www.delorie.com/archives/browse.cgi   search  
Mail Archives: djgpp-workers/2001/10/23/12:31:02

Message-ID: <001c01c15bdf$cac187c0$0d2c24d5@zephyr>
From: "Eric Botcazou" <ebotcazou AT libertysurf DOT fr>
To: "DJGPP workers" <djgpp-workers AT delorie DOT com>
Subject: _findfirst() patch (2)
Date: Tue, 23 Oct 2001 18:20:29 +0200
MIME-Version: 1.0
X-Priority: 3
X-MSMail-Priority: Normal
X-Mailer: Microsoft Outlook Express 5.00.2014.211
X-MimeOLE: Produced By Microsoft MimeOLE V5.00.2014.211
Reply-To: djgpp-workers AT delorie DOT com

This is a multi-part message in MIME format.

------=_NextPart_000_0015_01C15BEF.653A1060
Content-Type: text/plain;
	charset="iso-8859-1"
Content-Transfer-Encoding: 7bit

Hello,

I've attached a (completely) revised version of my _findfirst() patch,
following the guidelines Eli and Charles provided me with.

The general design is the one Eli agreed to:
- _lfn_findfirst(), _lfn_findnext() and _lfn_findclose() are the low-level
wrapper functions around the functions 714eh, 714fh, 71a1h respectively,
living in the src/libc/dos/dir directory,
- _dos_findfirst() and _dos_findnext() have been rewritten using materials
from the former findfirst() and findnext(),
- findfirst()/findnext() and _findfirst()/_findnext()/_findclose() are now
high-level functions that call the two previously cited sets of functions,
- I've revamped my DOS time to ANSI C time conversion function, because I
found that there is already a structure (namely struct ftime) in dos.h which
describes the DOS time format,
- everything follows the 'one external function per file' rule and is
documented.

I've also attached a more complete version of the test program.

--
Eric Botcazou
ebotcazou AT multimania DOT com

------=_NextPart_000_0015_01C15BEF.653A1060
Content-Type: application/octet-stream;
	name="_findfirst2.diff"
Content-Transfer-Encoding: quoted-printable
Content-Disposition: attachment;
	filename="_findfirst2.diff"

--- /cvsroot/djgpp/src/libc/dos/compat/d_findf.c	Sun Aug 31 17:49:56 =
1997
+++ /djgpp-cvs/src/libc/dos/compat/d_findf.c	Tue Oct 23 17:15:08 2001
@@ -15,29 +15,46 @@
 #include <go32.h>
 #include <errno.h>
 #include <dpmi.h>
-#include <string.h>
+#include <dir.h>
 #include <dos.h>
=20
-unsigned int _dos_findfirst(const char *name, unsigned int attr, struct =
_find_t *result)
+unsigned int
+_dos_findfirst(const char *name, unsigned int attr, struct _find_t =
*result)
 {
   __dpmi_regs r;
+  int namelen;
+
+  if (name =3D=3D 0 || result =3D=3D 0) {
+    errno =3D EACCES;
+    return 0x05;  /* DOS error code: access denied */
+  }
+
+  namelen =3D strlen(name) + 1;
=20
   _put_path(name);
-  r.x.dx =3D (__tb & 15) + strlen(name) + 1;
-  r.x.ds =3D __tb / 16;
-  r.h.ah =3D 0x1A;
+
+  /* There will be a _sizeof_dos_ffblk character return value from =
_dos_findfirst=20
+     in the DTA.  Put the file name before this.  First set the DTA to =
be
+     transfer buffer. */
+
+  r.x.dx =3D __tb_offset + namelen;
+  r.x.ds =3D __tb_segment;
+  r.h.ah =3D 0x1a;
   __dpmi_int(0x21, &r);
=20
-  r.h.ah =3D 0x4E;
-  r.x.dx =3D (__tb & 15);
-  r.x.ds =3D __tb / 16;
+  r.h.ah =3D 0x4e;
+  r.x.dx =3D __tb_offset;
+  r.x.ds =3D __tb_segment;
   r.x.cx =3D attr;
   __dpmi_int(0x21, &r);
-  if ( r.x.flags & 1 )
-  {
+
+  if (r.x.flags&1) {  /* error? */
     errno =3D __doserr_to_errno(r.x.ax);
     return r.x.ax;
   }
-  dosmemget(__tb + strlen(name) + 1, sizeof(struct _find_t), result);
+
+  /* Recover results */
+  dosmemget(__tb + namelen, _sizeof_dos_ffblk, result);
+
   return 0;
 }
--- /cvsroot/djgpp/src/libc/dos/compat/d_findn.c	Mon Oct  9 08:00:00 =
1995
+++ /djgpp-cvs/src/libc/dos/compat/d_findn.c	Mon Oct 22 22:50:02 2001
@@ -14,24 +14,39 @@
 #include <go32.h>
 #include <errno.h>
 #include <dpmi.h>
+#include <dir.h>
 #include <dos.h>
=20
-unsigned int _dos_findnext(struct _find_t *result)
+unsigned int
+_dos_findnext(struct _find_t *result)
 {
   __dpmi_regs r;
=20
-  r.x.dx =3D __tb & 15;
-  r.x.ds =3D __tb / 16;
-  r.h.ah =3D 0x1A;
+  if (result =3D=3D 0) {
+    errno =3D EACCES;
+    return 0x05;  /* DOS error code: access denied */
+  }
+
+  /* The 43 character ff block must be put to the DTA, make the call, =
then
+     recover the ff block. */
+
+  r.x.dx =3D __tb_offset;
+  r.x.ds =3D __tb_segment;
+  r.h.ah =3D 0x1a;
   __dpmi_int(0x21, &r);
-  dosmemput(result, sizeof(struct _find_t), __tb);
-  r.h.ah =3D 0x4F;
+
+  dosmemput(result, _sizeof_dos_ffblk, __tb);
+
+  r.h.ah =3D 0x4f;
   __dpmi_int(0x21, &r);
-  if ( r.x.flags & 1 )
-  {
+
+  if (r.x.flags&1) {  /* error? */
     errno =3D __doserr_to_errno(r.x.ax);
     return r.x.ax;
   }
-  dosmemget(__tb, sizeof(struct _find_t), result);
+
+  /* Recover results */
+  dosmemget(__tb, _sizeof_dos_ffblk, result);
+
   return 0;
 }
--- /cvsroot/djgpp/src/libc/dos/compat/d_gettim.c	Mon Oct  9 08:00:00 =
1995
+++ /djgpp-cvs/src/libc/dos/compat/d_gettim.c	Mon Oct 22 20:40:02 2001
@@ -12,14 +12,14 @@
 #include <dpmi.h>
 #include <dos.h>
=20
-void _dos_gettime(struct _dostime_t *time)
+void _dos_gettime(struct _dostime_t *dtime)
 {
   __dpmi_regs r;
=20
   r.h.ah =3D 0x2C;
   __dpmi_int(0x21, &r);
-  time->hour    =3D r.h.ch;
-  time->minute  =3D r.h.cl;
-  time->second  =3D r.h.dh;
-  time->hsecond =3D r.h.dl;
+  dtime->hour    =3D r.h.ch;
+  dtime->minute  =3D r.h.cl;
+  dtime->second  =3D r.h.dh;
+  dtime->hsecond =3D r.h.dl;
 }
--- /cvsroot/djgpp/src/libc/dos/compat/d_setftm.c	Mon Oct  9 08:00:00 =
1995
+++ /djgpp-cvs/src/libc/dos/compat/d_setftm.c	Mon Oct 22 20:45:18 2001
@@ -13,13 +13,13 @@
 #include <errno.h>
 #include <dos.h>
=20
-unsigned int _dos_setftime(int handle, unsigned int date, unsigned int =
time)
+unsigned int _dos_setftime(int handle, unsigned int date, unsigned int =
dtime)
 {
   __dpmi_regs r;
=20
   r.x.ax =3D 0x5701;
   r.x.bx =3D handle;
-  r.x.cx =3D time;
+  r.x.cx =3D dtime;
   r.x.dx =3D date;
   __dpmi_int(0x21, &r);
   if ( r.x.flags & 1 )
--- /cvsroot/djgpp/src/libc/dos/compat/d_settim.c	Sat Nov 25 03:20:36 =
1995
+++ /djgpp-cvs/src/libc/dos/compat/d_settim.c	Mon Oct 22 20:45:44 2001
@@ -13,21 +13,21 @@
 #include <errno.h>
 #include <dos.h>
=20
-unsigned int _dos_settime(struct _dostime_t *time)
+unsigned int _dos_settime(struct _dostime_t *dtime)
 {
   __dpmi_regs r;
=20
-  if (time =3D=3D 0)
+  if (dtime =3D=3D 0)
   {
     errno =3D EINVAL;
     return -1;
   }
=20
   r.h.ah =3D 0x2D;
-  r.h.ch =3D time->hour;
-  r.h.cl =3D time->minute;
-  r.h.dh =3D time->second;
-  r.h.dl =3D time->hsecond;
+  r.h.ch =3D dtime->hour;
+  r.h.cl =3D dtime->minute;
+  r.h.dh =3D dtime->second;
+  r.h.dl =3D dtime->hsecond;
   __dpmi_int(0x21, &r);
   if ( r.h.al )
   {
--- /cvsroot/djgpp/src/libc/dos/dir/findfirs.c	Sat Aug 31 23:09:32 1996
+++ /djgpp-cvs/src/libc/dos/dir/findfirs.c	Tue Oct 23 17:18:22 2001
@@ -1,56 +1,22 @@
 /* Copyright (C) 1996 DJ Delorie, see COPYING.DJ for details */
 /* Copyright (C) 1995 DJ Delorie, see COPYING.DJ for details */
 #include <libc/stubs.h>
-#include <stdlib.h>
 #include <string.h>
 #include <errno.h>
 #include <fcntl.h>
-#include <go32.h>
-#include <dpmi.h>
 #include <dir.h>
-#include <libc/dosio.h>
+#include <dos.h>
=20
 int
 findfirst(const char *pathname, struct ffblk *ffblk, int attrib)
 {
-  __dpmi_regs r;
-  int pathlen;
-  int use_lfn =3D _USE_LFN;
-
-  if (pathname =3D=3D 0 || ffblk =3D=3D 0)
-  {
-    errno =3D EACCES;
-    return -1;
-  }
-
-  pathlen =3D strlen(pathname) + 1;
-
-  _put_path(pathname);
-  if(use_lfn) {
+  if (_USE_LFN) {
+    struct ffblklfn ffblk32;
+    long handle;
=20
-    /* si =3D 1 indicates DOS style dates, 0 means Win32 type dates.
-       DOS style dates are broken in some Win95 betas, build for =
either.
-       Release works with DOS date, it's faster, so use it. */
-    #define USEDOSDATE 1
-    #if USEDOSDATE =3D=3D 1
-      #define _Win32_to_DOS (long)
-    #else
-      extern long _Win32_to_DOS(long long WinTime);
-    #endif
-
-    r.x.ax =3D 0x714e;
-    r.x.cx =3D attrib;
-    r.x.dx =3D __tb_offset;
-    r.x.ds =3D __tb_segment;
-    r.x.di =3D __tb_offset + pathlen;
-    r.x.es =3D r.x.ds;
-    r.x.si =3D USEDOSDATE;
-    __dpmi_int(0x21, &r);
-    if(!(r.x.flags & 1)) {
-      struct ffblklfn ffblk32;
-      /* Recover results */
-      dosmemget(__tb+pathlen, sizeof(struct ffblklfn), &ffblk32);
+    handle =3D _lfn_findfirst(pathname, attrib, &ffblk32);
=20
+    if (handle > 0) {
       ffblk->ff_attrib =3D (char)ffblk32.fd_attrib;
       *(long *)(&ffblk->ff_ftime) =3D _Win32_to_DOS(ffblk32.fd_mtime);
       ffblk->ff_fsize =3D ffblk32.fd_size;
@@ -58,43 +24,22 @@
       strcpy(ffblk->lfn_magic, "LFN32");
=20
       /* If no wildcards, close the handle */
-      if(!strchr(pathname,'*') && !strchr(pathname,'?')) {
-        r.x.bx =3D r.x.ax;
-        r.x.ax =3D 0x71a1;
-        __dpmi_int(0x21, &r);
-        r.x.ax =3D 0;
+      if (!strchr(pathname,'*') && !strchr(pathname,'?')) {
+        _lfn_findclose(handle);
+        handle =3D 0;
       }
        =20
-      ffblk->lfn_handle =3D r.x.ax;
+      ffblk->lfn_handle =3D handle;
       *(long *)(&ffblk->lfn_ctime) =3D _Win32_to_DOS(ffblk32.fd_ctime);
       *(long *)(&ffblk->lfn_atime) =3D _Win32_to_DOS(ffblk32.fd_atime);
=20
       return 0;
     }
-  } else {
-
-    #define _sizeof_dos_ffblk 44
-    /* There will be a _sizeof_dos_ffblk character return value from =
findfirst=20
-       in the DTA.  Put the file name before this.  First set the DTA =
to be=20
-       transfer buffer. */
-
-    r.x.dx =3D __tb_offset + pathlen;
-    r.x.ds =3D __tb_segment;
-    r.h.ah =3D 0x1a;
-    __dpmi_int(0x21, &r);
-
-    r.h.ah =3D 0x4e;
-    r.x.dx =3D __tb_offset;
-    r.x.ds =3D __tb_segment;
-    r.x.cx =3D attrib;
-    __dpmi_int(0x21, &r);
-    if(!(r.x.flags & 1)) {
-      /* Recover results */
-      dosmemget(__tb+pathlen, _sizeof_dos_ffblk, ffblk);
+  }
+  else {
+    if (_dos_findfirst(pathname, attrib, (struct _find_t *)ffblk) =
=3D=3D 0)
       return 0;
-    }
   }
=20
-  errno =3D __doserr_to_errno(r.x.ax);
   return errno;
 }
--- /cvsroot/djgpp/src/libc/dos/dir/findnext.c	Sun Sep  1 00:09:32 1996
+++ /djgpp-cvs/src/libc/dos/dir/findnext.c	Mon Oct 22 22:50:24 2001
@@ -1,56 +1,24 @@
 /* Copyright (C) 1996 DJ Delorie, see COPYING.DJ for details */
 /* Copyright (C) 1995 DJ Delorie, see COPYING.DJ for details */
 #include <libc/stubs.h>
-#include <stdlib.h>
 #include <string.h>
+#include <fcntl.h>
 #include <errno.h>
-#include <go32.h>
-#include <dpmi.h>
 #include <dir.h>
-#include <fcntl.h>
-#include <libc/dosio.h>
+#include <dos.h>
=20
 int
 findnext(struct ffblk *ffblk)
 {
-  __dpmi_regs r;
-
-  if (ffblk =3D=3D 0)
-  {
-    errno =3D EACCES;
-    return -1;
-  }
+  if (_USE_LFN) {
+    struct ffblklfn ffblk32;
=20
-  if(_USE_LFN)
-  {
-    /* si =3D 1 indicates DOS style dates, 0 means Win32 type dates.
-       DOS style dates are broken in some Win95 betas, build for =
either.
-       Release works with DOS date, it's faster, so use it. */
-    #define USEDOSDATE 1
-    #if USEDOSDATE =3D=3D 1
-      #define _Win32_to_DOS (long)
-    #else
-      extern long _Win32_to_DOS(long long WinTime);
-    #endif
-
-    r.x.ax =3D 0x714f;
-    r.x.bx =3D ffblk->lfn_handle;
-    if(!r.x.bx)
-    {
+    if (!ffblk->lfn_handle) {  /* handle already closed? */
       errno =3D ENMFILE;
       return 1;
     }
-    r.x.di =3D __tb_offset;
-    r.x.es =3D __tb_segment;
-    r.x.si =3D USEDOSDATE;
-
-    __dpmi_int(0x21, &r);
-    if (!(r.x.flags & 1))
-    {
-      struct ffblklfn ffblk32;
-      /* Recover results */
-      dosmemget(__tb, sizeof(struct ffblklfn), &ffblk32);
=20
+    if (_lfn_findnext(ffblk->lfn_handle, &ffblk32) =3D=3D 0) {
       ffblk->ff_attrib =3D (char)ffblk32.fd_attrib;
       *(long *)&ffblk->ff_ftime =3D _Win32_to_DOS(ffblk32.fd_mtime);
       ffblk->ff_fsize =3D ffblk32.fd_size;
@@ -60,44 +28,19 @@
=20
       return 0;
     }
-    errno =3D __doserr_to_errno(r.x.ax);
-    if (errno =3D=3D ENMFILE)         /* call FindClose */
-    {
-      ffblk->lfn_handle =3D 0;
-      r.x.ax =3D 0x71a1;
-      __dpmi_int(0x21, &r);
-      if(r.x.flags & 1)
-      {
-        errno =3D __doserr_to_errno(r.x.ax);
+
+    if (errno =3D=3D ENMFILE) {  /* no more files? */
+      if (_lfn_findclose(ffblk->lfn_handle) < 0)
         return -1;
-      }
+
+      ffblk->lfn_handle =3D 0;
       return 1;
     }
-    return -1;
   }
-  else
-  {
-    #define _sizeof_dos_ffblk 44
-    /* The 43 character ff block must be put to the DTA, make the call, =
then
-       recover the ff block. */
-
-    r.x.dx =3D __tb_offset;
-    r.x.ds =3D __tb_segment;
-    r.h.ah =3D 0x1a;
-    __dpmi_int(0x21, &r);
-
-    dosmemput(ffblk, sizeof(struct ffblk), __tb);
-
-    r.h.ah =3D 0x4f;
-    __dpmi_int(0x21, &r);
-    if(r.x.flags & 1)
-    {
-      errno =3D __doserr_to_errno(r.x.ax);
-      return -1;
-    }
-
-    /* Recover results */
-    dosmemget(__tb, _sizeof_dos_ffblk, ffblk);
-    return 0;
+  else {
+    if (_dos_findnext((struct _find_t *)ffblk) =3D=3D 0)
+      return 0;
   }
+
+  return -1;
 }
--- /cvsroot/djgpp/src/libc/dos/dir/l_findc.c	Thu Jan  1 00:00:00 1970
+++ /djgpp-cvs/src/libc/dos/dir/l_findc.c	Tue Oct 23 17:17:04 2001
@@ -0,0 +1,22 @@
+#include <libc/stubs.h>
+#include <libc/dosio.h>
+#include <errno.h>
+#include <dpmi.h>
+#include <dir.h>
+
+int
+_lfn_findclose(long handle)
+{
+  __dpmi_regs r;
+
+  r.x.ax =3D 0x71a1;
+  r.x.bx =3D handle;
+  __dpmi_int(0x21, &r);
+
+  if (r.x.flags&1) {  /* error? */
+    errno =3D __doserr_to_errno(r.x.ax);
+    return -1;
+  }
+
+  return 0;
+}
--- /cvsroot/djgpp/src/libc/dos/dir/l_findc.txh	Thu Jan  1 00:00:00 1970
+++ /djgpp-cvs/src/libc/dos/dir/l_findc.txh	Tue Oct 23 01:13:22 2001
@@ -0,0 +1,21 @@
+@node _lfn_findclose, file system
+@subheading Syntax
+
+@example
+#include <dir.h>
+
+int _lfn_findclose(long handle);
+@end example
+
+@subheading Description
+
+This closes the search started by @code{_lfn_findfirst}.
+
+@subheading Return Value
+
+Zero on success, -1 on error (and sets @var{errno}).
+
+@subheading Portability
+
+@portability !ansi, !posix
+
--- /cvsroot/djgpp/src/libc/dos/dir/l_findf.c	Thu Jan  1 00:00:00 1970
+++ /djgpp-cvs/src/libc/dos/dir/l_findf.c	Tue Oct 23 01:17:58 2001
@@ -0,0 +1,43 @@
+/* Copyright (C) 1996 DJ Delorie, see COPYING.DJ for details */
+/* Copyright (C) 1995 DJ Delorie, see COPYING.DJ for details */
+#include <libc/stubs.h>
+#include <libc/dosio.h>
+#include <errno.h>
+#include <dpmi.h>
+#include <go32.h>
+#include <dir.h>
+
+long
+_lfn_findfirst(const char *pathname, int attrib, struct ffblklfn =
*ffblklfn)
+{
+  __dpmi_regs r;
+  int pathlen;
+
+  if (pathname =3D=3D 0 || ffblklfn =3D=3D 0) {
+    errno =3D EACCES;
+    return -1;
+  }
+
+  pathlen =3D strlen(pathname) + 1;
+
+  _put_path(pathname);
+
+  r.x.ax =3D 0x714e;
+  r.x.cx =3D attrib;
+  r.x.dx =3D __tb_offset;
+  r.x.ds =3D __tb_segment;
+  r.x.di =3D __tb_offset + pathlen;
+  r.x.es =3D r.x.ds;
+  r.x.si =3D USEDOSDATE;
+  __dpmi_int(0x21, &r);
+
+  if (r.x.flags&1) {  /* error? */
+    errno =3D __doserr_to_errno(r.x.ax);
+    return -1;
+  }
+
+  /* Recover results */
+  dosmemget(__tb+pathlen, sizeof(struct ffblklfn), ffblklfn);
+
+  return (long)r.x.ax;
+}
--- /cvsroot/djgpp/src/libc/dos/dir/l_findf.txh	Thu Jan  1 00:00:00 1970
+++ /djgpp-cvs/src/libc/dos/dir/l_findf.txh	Tue Oct 23 01:15:44 2001
@@ -0,0 +1,30 @@
+@node _lfn_findfirst, file system
+@subheading Syntax
+
+@example
+#include <dir.h>
+
+long _lfn_findfirst(const char *pathname, int attrib, struct ffblklfn =
*ffblklfn);
+@end example
+
+@subheading Description
+
+This function and the related @code{_lfn_findnext} =
(@pxref{_lfn_findnext})
+and @code{_lfn_findclose} (@pxref{_lfn_findclose}) are used to scan
+directories for the list of files therein. However they are not =
intended
+to be directly called. Use one of the two public functions instead
+(@pxref{findfirst} and @pxref{_findfirst}).
+
+This function works only if long file names are supported by the =
system.
+
+@subheading Return Value
+
+If a match is found, @code{_lfn_findfirst} returns an unique handle
+identifying the search that can be used in subsequent calls to
+@code{_lfn_findnext} and to @code{_lfn_findclose}. Otherwise,
+@code{_lfn_findfirst} returns -1 (and sets @var{errno}).
+
+@subheading Portability
+
+@portability !ansi, !posix
+
--- /cvsroot/djgpp/src/libc/dos/dir/l_findn.c	Thu Jan  1 00:00:00 1970
+++ /djgpp-cvs/src/libc/dos/dir/l_findn.c	Tue Oct 23 17:17:54 2001
@@ -0,0 +1,36 @@
+/* Copyright (C) 1996 DJ Delorie, see COPYING.DJ for details */
+/* Copyright (C) 1995 DJ Delorie, see COPYING.DJ for details */
+#include <libc/stubs.h>
+#include <libc/dosio.h>
+#include <errno.h>
+#include <go32.h>
+#include <dpmi.h>
+#include <dir.h>
+
+int
+_lfn_findnext(long handle, struct ffblklfn *ffblklfn)
+{
+  __dpmi_regs r;
+
+  if (ffblklfn =3D=3D 0) {
+    errno =3D EACCES;
+    return -1;
+  }
+
+  r.x.ax =3D 0x714f;
+  r.x.bx =3D handle;
+  r.x.di =3D __tb_offset;
+  r.x.es =3D __tb_segment;
+  r.x.si =3D USEDOSDATE;
+  __dpmi_int(0x21, &r);
+
+  if (r.x.flags&1) {  /* error? */
+    errno =3D __doserr_to_errno(r.x.ax);
+    return -1;
+  }
+
+  /* Recover results */
+  dosmemget(__tb, sizeof(struct ffblklfn), ffblklfn);
+
+  return 0;
+}
--- /cvsroot/djgpp/src/libc/dos/dir/l_findn.txh	Thu Jan  1 00:00:00 1970
+++ /djgpp-cvs/src/libc/dos/dir/l_findn.txh	Tue Oct 23 01:13:12 2001
@@ -0,0 +1,23 @@
+@node _lfn_findnext, file system
+@subheading Syntax
+
+@example
+#include <dir.h>
+
+int _lfn_findnext(long handle, struct ffblklfn *ffblklfn)
+@end example
+
+@subheading Description
+
+This finds the next file in the search started by =
@code{_lfn_findfirst}.
+
+This function works only if long file names are supported by the =
system.
+
+@subheading Return Value
+
+Zero if a match is found, -1 if not found (and sets @var{errno}).
+
+@subheading Portability
+
+@portability !ansi, !posix
+
--- /cvsroot/djgpp/src/libc/dos/dir/makefile	Tue Jun 13 08:03:36 1995
+++ /djgpp-cvs/src/libc/dos/dir/makefile	Mon Oct 22 19:17:18 2001
@@ -1,6 +1,9 @@
 # Copyright (C) 1995 DJ Delorie, see COPYING.DJ for details
 TOP=3D../..
=20
+SRC +=3D l_findc.c
+SRC +=3D l_findf.c
+SRC +=3D l_findn.c
 SRC +=3D findfirs.c
 SRC +=3D findnext.c
 SRC +=3D fnmerge.c
--- /cvsroot/djgpp/src/libc/dos/dos/ftime2tm.c	Thu Jan  1 00:00:00 1970
+++ /djgpp-cvs/src/libc/dos/dos/ftime2tm.c	Mon Oct 22 18:57:36 2001
@@ -0,0 +1,20 @@
+#include <string.h>
+#include <time.h>
+#include <dos.h>
+
+time_t
+_ftime_to_time_t(struct ftime *ftimep)
+{
+  struct tm t;
+
+  memset(&t, 0, sizeof(struct tm));
+  t.tm_sec  =3D ftimep->ft_tsec * 2;
+  t.tm_min  =3D ftimep->ft_min;
+  t.tm_hour =3D ftimep->ft_hour;
+  t.tm_mday =3D ftimep->ft_day;
+  t.tm_mon  =3D ftimep->ft_month - 1;
+  t.tm_year =3D ftimep->ft_year + 80;
+  t.tm_isdst =3D -1;
+
+  return mktime(&t);
+}
--- /cvsroot/djgpp/src/libc/dos/dos/ftime2tm.txh	Thu Jan  1 00:00:00 =
1970
+++ /djgpp-cvs/src/libc/dos/dos/ftime2tm.txh	Tue Oct 23 00:56:56 2001
@@ -0,0 +1,33 @@
+@node _ftime_to_time_t, file system
+@subheading Syntax
+
+@example
+#include <dos.h>
+
+time_t _ftime_to_time_t(struct ftime *ftimep);
+@end example
+
+@subheading Description
+
+This function converts the DOS time format used for files
+into the ANSI C time format.
+
+@xref{getftime}, for the description of @code{struct ftime}.
+
+@subheading Return Value
+
+Converted time value.
+
+@subheading Portability
+
+@portability !ansi, !posix
+
+@subheading Example
+
+@example
+struct ftime t;
+time_t time;
+getftime(fd, &t);
+time =3D _ftime_to_time_t(&t);
+@end example
+
--- /cvsroot/djgpp/src/libc/dos/dos/makefile	Mon Jun 19 20:00:56 2000
+++ /djgpp-cvs/src/libc/dos/dos/makefile	Mon Oct 22 21:25:34 2001
@@ -5,6 +5,7 @@
 SRC +=3D bdosptr.S
 SRC +=3D delay.c
 SRC +=3D fexistp.c
+SRC +=3D ftime2tm.c
 SRC +=3D getcbrk.c
 SRC +=3D getdate.c
 SRC +=3D getdfree.c
--- /cvsroot/djgpp/src/libc/dos/io/_findclo.c	Thu Jan  1 00:00:00 1970
+++ /djgpp-cvs/src/libc/dos/io/_findclo.c	Mon Oct 22 22:51:24 2001
@@ -0,0 +1,18 @@
+#include <libc/stubs.h>
+#include <stdlib.h>
+#include <fcntl.h>
+#include <dir.h>
+#include <io.h>
+
+int
+_findclose(long handle)
+{
+  if (_USE_LFN) {
+    return _lfn_findclose(handle);
+  }
+  else {
+    free((struct ffblk*)handle);
+    return 0;
+  }
+}
+
--- /cvsroot/djgpp/src/libc/dos/io/_findclo.txh	Thu Jan  1 00:00:00 1970
+++ /djgpp-cvs/src/libc/dos/io/_findclo.txh	Tue Oct  9 11:52:16 2001
@@ -0,0 +1,21 @@
+@node _findclose, file system
+@subheading Syntax
+
+@example
+#include <io.h>
+
+int _findclose(long handle);
+@end example
+
+@subheading Description
+
+This closes the search started by @code{_findfirst}.
+
+@subheading Return Value
+
+Zero on success, -1 on error (and sets @var{errno}).
+
+@subheading Portability
+
+@portability !ansi, !posix
+
--- /cvsroot/djgpp/src/libc/dos/io/_findfir.c	Thu Jan  1 00:00:00 1970
+++ /djgpp-cvs/src/libc/dos/io/_findfir.c	Mon Oct 22 22:51:34 2001
@@ -0,0 +1,58 @@
+#include <libc/stubs.h>
+#include <stdlib.h>
+#include <string.h>
+#include <errno.h>
+#include <fcntl.h>
+#include <dir.h>
+#include <io.h>
+
+long
+_findfirst(const char *pathname, struct _finddata_t *fileinfo)
+{
+  #define ALL_ATTRIB (_A_RDONLY | _A_HIDDEN | _A_SYSTEM | _A_VOLID | =
_A_SUBDIR | _A_ARCH)
+
+  if (_USE_LFN) {
+    struct ffblklfn ffblk32;
+    long handle, temp;
+
+    handle =3D _lfn_findfirst(pathname, ALL_ATTRIB, &ffblk32);
+
+    if (handle > 0) {
+      fileinfo->attrib =3D (unsigned)ffblk32.fd_attrib;
+
+      temp =3D _Win32_to_DOS(ffblk32.fd_ctime);
+      fileinfo->time_create =3D _ftime_to_time_t((struct ftime =
*)&temp);
+
+      temp =3D _Win32_to_DOS(ffblk32.fd_atime);
+      fileinfo->time_access =3D _ftime_to_time_t((struct ftime =
*)&temp);
+
+      temp =3D _Win32_to_DOS(ffblk32.fd_mtime);
+      fileinfo->time_write  =3D _ftime_to_time_t((struct ftime =
*)&temp);
+
+      fileinfo->size =3D (_fsize_t)ffblk32.fd_size;
+      strcpy(fileinfo->name, ffblk32.fd_longname);
+
+      return handle;
+    }
+  }
+  else {
+    struct ffblk *ffblk16 =3D malloc(_sizeof_dos_ffblk);
+    if (!ffblk16) {
+      errno =3D ENOMEM;
+      return -1;
+    }
+
+    if (_dos_findfirst(pathname, ALL_ATTRIB, (struct _find_t *)ffblk16) =
=3D=3D 0) {
+      fileinfo->attrib =3D (unsigned)ffblk16->ff_attrib;
+      fileinfo->time_create =3D -1;
+      fileinfo->time_access =3D -1;
+      fileinfo->time_write =3D _ftime_to_time_t((struct ftime =
*)&ffblk16->ff_ftime);
+      fileinfo->size =3D (_fsize_t)ffblk16->ff_fsize;
+      strcpy(fileinfo->name, ffblk16->ff_name);
+
+      return (long)ffblk16;
+    }
+  }
+
+  return -1;
+}
--- /cvsroot/djgpp/src/libc/dos/io/_findfir.txh	Thu Jan  1 00:00:00 1970
+++ /djgpp-cvs/src/libc/dos/io/_findfir.txh	Tue Oct  9 11:54:04 2001
@@ -0,0 +1,119 @@
+@node _findfirst, file system
+@subheading Syntax
+
+@example
+#include <io.h>
+
+long _findfirst(const char *pathname, struct _finddata_t *fileinfo);
+@end example
+
+@subheading Description
+
+This function and the related @code{_findnext} (@pxref{_findnext}) and
+@code{_findclose} (@pxref{_findclose}) are used to scan directories for =
the
+list of files therein. The @var{pathname} is a wildcard that specifies =
the
+directory and files to search for (such as @code{subdir/*.c}) and
+@var{fileinfo} is a structure to hold the results of the search.
+
+The results are returned in a @code{struct _finddata_t} defined in
+@code{<io.h>} as follows:
+
+@example
+struct _finddata_t @{
+  unsigned attrib;
+  time_t time_create;
+  time_t time_access;
+  time_t time_write;
+  _fsize_t size;
+  char name[260];
+@};
+@end example
+
+The @var{attrib} field is a combination of the following:
+
+@table @code
+
+@item _A_NORMAL (0x00)
+
+Normal file (no read/write restrictions)
+
+@item _A_RDONLY (0x01)
+
+Read only file
+
+@item _A_HIDDEN (0x02)
+
+Hidden file
+
+@item _A_SYSTEM (0x04)
+
+System file
+
+@item _A_VOLID (0x08)
+
+Volume ID file
+
+@item _A_SUBDIR (0x10)
+
+Subdirectory
+
+@item _A_ARCH (0x20)
+
+Archive file
+
+@end table
+
+This function supports long file names.
+
+@subheading Return Value
+
+If a match is found, @code{_findfirst} returns an unique handle =
identifying
+the search that can be used in subsequent calls to @code{_findnext} and =
to
+@code{_findclose}. Otherwise, @code{_findfirst} returns -1 (and sets
+@var{errno}).
+
+@subheading Portability
+
+@portability !ansi, !posix
+
+@subheading Example
+
+@example
+#include <io.h>
+#include <time.h>
+
+struct _finddata_t fileinfo;
+long handle;
+char attrib_str[7], time_str[32];
+int c =3D 0;
+
+handle =3D _findfirst("*.dat", &fileinfo);
+
+if (handle<0)
+@{
+  printf("no matching file.\n");
+@}
+else
+@{
+  do
+  @{
+    attrib_str[0] =3D (fileinfo.attrib&_A_RDONLY ? 'r' : '-');
+    attrib_str[1] =3D (fileinfo.attrib&_A_HIDDEN ? 'h' : '-');
+    attrib_str[2] =3D (fileinfo.attrib&_A_SYSTEM ? 's' : '-');
+    attrib_str[3] =3D (fileinfo.attrib&_A_VOLID  ? 'l' : '-');
+    attrib_str[4] =3D (fileinfo.attrib&_A_SUBDIR ? 'd' : '-');
+    attrib_str[5] =3D (fileinfo.attrib&_A_ARCH   ? 'a' : '-');
+    attrib_str[6] =3D '\0';
+
+    strftime(time_str, sizeof(time_str), "%m/%d/%Y %H:%M ", =
localtime(&fileinfo.time_write));
+
+    printf("%-14s  %5ld kb  %s  %s\n", fileinfo.name, 1 + =
fileinfo.size/1024, attrib_str, time_str);
+
+    c++;
+  @} while (_findnext(handle, &fileinfo) =3D=3D 0);
+
+  _findclose(handle);
+
+  printf("%d matching file%s\n", c, c>1 ? "s." : ".");
+@}
+@end example
--- /cvsroot/djgpp/src/libc/dos/io/_findnex.c	Thu Jan  1 00:00:00 1970
+++ /djgpp-cvs/src/libc/dos/io/_findnex.c	Mon Oct 22 22:52:20 2001
@@ -0,0 +1,48 @@
+#include <libc/stubs.h>
+#include <string.h>
+#include <fcntl.h>
+#include <dir.h>
+#include <io.h>
+
+int
+_findnext(long handle, struct _finddata_t *fileinfo)
+{
+  if (_USE_LFN) {
+    struct ffblklfn ffblk32;
+    long temp;
+
+    if (_lfn_findnext(handle, &ffblk32) =3D=3D 0) {
+      fileinfo->attrib =3D (unsigned)ffblk32.fd_attrib;
+
+      temp =3D _Win32_to_DOS(ffblk32.fd_ctime);
+      fileinfo->time_create =3D _ftime_to_time_t((struct ftime =
*)&temp);
+
+      temp =3D _Win32_to_DOS(ffblk32.fd_atime);
+      fileinfo->time_access =3D _ftime_to_time_t((struct ftime =
*)&temp);
+
+      temp =3D _Win32_to_DOS(ffblk32.fd_mtime);
+      fileinfo->time_write  =3D _ftime_to_time_t((struct ftime =
*)&temp);
+
+      fileinfo->size =3D (_fsize_t)ffblk32.fd_size;
+      strcpy(fileinfo->name, ffblk32.fd_longname);
+
+      return 0;
+    }
+  }
+  else {
+    struct ffblk *ffblk16 =3D (struct ffblk *)handle;
+
+    if (_dos_findnext((struct _find_t *)ffblk16) =3D=3D 0) {
+      fileinfo->attrib =3D (unsigned)ffblk16->ff_attrib;
+      fileinfo->time_create =3D -1;
+      fileinfo->time_access =3D -1;
+      fileinfo->time_write =3D _ftime_to_time_t((struct ftime =
*)&ffblk16->ff_ftime);
+      fileinfo->size =3D (_fsize_t)ffblk16->ff_fsize;
+      strcpy(fileinfo->name, ffblk16->ff_name);
+
+      return 0;
+    }
+  }
+
+  return -1;
+}
--- /cvsroot/djgpp/src/libc/dos/io/_findnex.txh	Thu Jan  1 00:00:00 1970
+++ /djgpp-cvs/src/libc/dos/io/_findnex.txh	Tue Oct  9 11:46:16 2001
@@ -0,0 +1,24 @@
+@node _findnext, file system
+@subheading Syntax
+
+@example
+#include <io.h>
+
+int _findnext(long handle, struct _finddata_t *fileinfo);
+@end example
+
+@subheading Description
+
+This finds the next file in the search started by @code{_findfirst}.
+See @ref{_findfirst}, for the description of @code{struct _finddata_t}.
+
+This function supports long file names.
+
+@subheading Return Value
+
+Zero if a match is found, -1 if not found (and sets @var{errno}).
+
+@subheading Portability
+
+@portability !ansi, !posix
+
--- /cvsroot/djgpp/src/libc/dos/io/makefile	Wed Mar  7 06:34:26 2001
+++ /djgpp-cvs/src/libc/dos/io/makefile	Mon Oct  8 21:44:18 2001
@@ -8,6 +8,9 @@
 SRC +=3D _close.c
 SRC +=3D _creat.c
 SRC +=3D _creat_n.c
+SRC +=3D _findfir.c
+SRC +=3D _findnex.c
+SRC +=3D _findclo.c
 SRC +=3D _open.c
 SRC +=3D _read.c
 SRC +=3D _write.c
diff -u /cvsroot/djgpp/include/dir.h /djgpp-cvs/include/dir.h
--- /cvsroot/djgpp/include/dir.h	Mon Jun 29 01:37:14 1998
+++ /djgpp-cvs/include/dir.h	Tue Oct 23 01:11:30 2001
@@ -19,7 +19,20 @@
=20
 /* This is for g++ 2.7.2 and below */
 #pragma pack(1)
- =20
+
+/* USEDOSDATE =3D 1 indicates DOS style dates, 0 means Win32 type =
dates.
+   DOS style dates are broken in some Win95 betas, build for either.
+   Release works with DOS date, it's faster, so use it. */
+#define USEDOSDATE 1
+
+#ifdef USEDOSDATE
+  #define _Win32_to_DOS (long)
+#else
+  long _Win32_to_DOS(long long _WinTime);
+#endif
+
+#define _sizeof_dos_ffblk 44
+
 struct ffblk {
   char lfn_magic[6] __attribute__((packed));			/* LFN */
   short lfn_handle __attribute__((packed));			/* LFN */
@@ -70,6 +83,9 @@
 #define DRIVE	  0x10
=20
 int	__file_tree_walk(const char *_dir, int (*_fn)(const char *_path, =
const struct ffblk *_ff));
+long	_lfn_findfirst(const char *_pathname, int _attrib, struct ffblklfn =
*_ffblklfn);
+int	_lfn_findnext(long _handle, struct ffblklfn *_ffblklfn);
+int	_lfn_findclose(long _handle);
 int	findfirst(const char *_pathname, struct ffblk *_ffblk, int =
_attrib);
 int	findnext(struct ffblk *_ffblk);
 void	fnmerge (char *_path, const char *_drive, const char *_dir, const =
char *_name, const char *_ext);
diff -u /cvsroot/djgpp/include/dos.h /djgpp-cvs/include/dos.h
--- /cvsroot/djgpp/include/dos.h	Mon Sep 24 23:11:04 2001
+++ /djgpp-cvs/include/dos.h	Mon Oct 22 20:45:56 2001
@@ -11,6 +11,7 @@
=20
 #ifndef _POSIX_SOURCE
=20
+#include <time.h>
 #include <pc.h>
=20
 extern int _8087;
@@ -158,6 +159,8 @@
 int enable(void);
 int disable(void);
=20
+time_t _ftime_to_time_t(struct ftime *_ftimep);
+
 int getftime(int _handle, struct ftime *_ftimep);
 int setftime(int _handle, struct ftime *_ftimep);
=20
@@ -268,7 +271,7 @@
 unsigned int   _dos_settime(struct _dostime_t *_time);
=20
 unsigned int   _dos_getftime(int _handle, unsigned int *_p_date, =
unsigned int *_p_time);
-unsigned int   _dos_setftime(int _handle, unsigned int _date, unsigned =
int _time);
+unsigned int   _dos_setftime(int _handle, unsigned int _date, unsigned =
int _dtime);
 unsigned int   _dos_getfileattr(const char *_filename, unsigned int =
*_p_attr);
 unsigned int   _dos_setfileattr(const char *_filename, unsigned int =
_attr);
=20
diff -u /cvsroot/djgpp/include/io.h /djgpp-cvs/include/io.h
--- /cvsroot/djgpp/include/io.h	Thu Feb  1 20:39:54 2001
+++ /djgpp-cvs/include/io.h	Tue Oct  9 11:00:12 2001
@@ -14,8 +14,20 @@
=20
 #ifndef _POSIX_SOURCE
=20
+#include <dos.h>  /* for the _A_* flags */
 #include <sys/types.h>
=20
+typedef unsigned long _fsize_t;
+
+struct _finddata_t {
+  unsigned attrib __attribute__((packed));
+  time_t   time_create __attribute__((packed));
+  time_t   time_access __attribute__((packed));
+  time_t   time_write __attribute__((packed));
+  _fsize_t size __attribute__((packed));
+  char     name[260] __attribute__((packed));
+};
+
 int		chsize(int handle, long size);
 int		_close(int _fd);
 int		_creat(const char *_path, int _attrib);
@@ -24,6 +36,9 @@
 int		_dos_lock(int _fd, long _offset, long _length);
 int		_dos_lk64(int _fd, long long _offset, long long _length);
 long		filelength(int _handle);
+long		_findfirst(const char *_pathname, struct _finddata_t *_fileinfo);
+int		_findnext(long _handle, struct _finddata_t *_fileinfo);
+int		_findclose(long _handle);
 short		_get_dev_info(int _arg);
 long long	lfilelength(int _handle);
 int		lock(int _fd, long _offset, long _length);

------=_NextPart_000_0015_01C15BEF.653A1060
Content-Type: application/octet-stream;
	name="findfile.c"
Content-Transfer-Encoding: quoted-printable
Content-Disposition: attachment;
	filename="findfile.c"

#include <stdio.h>
#include <stdlib.h>
#include <time.h>
#include <dir.h>
#include <dos.h>
#include <io.h>


void usage(void)
{
   fprintf(stderr, "Usage:\n");
   fprintf(stderr, "       findfile [-i] pattern\n");
   fprintf(stderr, "where i can take one of the following values:\n");
   fprintf(stderr, "  - 1   use the basic DOS _dos_findfirst() =
function\n");
   fprintf(stderr, "  - 2   use the Borland-compatible findfirst() =
function\n");
   fprintf(stderr, "  - 3   use the Watcom-compatible _findfirst() =
function\n");
   exit(EXIT_FAILURE);
}


#define ALL_ATTRIB (_A_RDONLY | _A_HIDDEN | _A_SYSTEM | _A_VOLID | =
_A_SUBDIR | _A_ARCH)
#define ALL_FATTRIB (FA_RDONLY | FA_HIDDEN | FA_SYSTEM | FA_LABEL | =
FA_DIREC | FA_ARCH)


int main(int argc, char *argv[])
{
   struct _find_t result;
   struct ffblk ffblk;
   struct _finddata_t fileinfo;
   int ret, handle;
   time_t time_write;
   char attrib_str[7], time_str[64];
   int level =3D 3, c =3D 0;

   if (argc < 2)
      usage();

   if (argv[1][0] =3D=3D '-') {
      if (argc < 3)
         usage();

      level =3D argv[1][1] - '0';

      if ((level<1) || (level>3))
         usage();

      argv[1] =3D argv[2];
   }

   switch (level) {

      case 1:
         ret =3D _dos_findfirst(argv[1], ALL_ATTRIB, &result);

         if (ret) {
            printf("no matching file.\n");
         }
         else {
            do {
               attrib_str[0] =3D (result.attrib&_A_RDONLY ? 'r' : '-');
               attrib_str[1] =3D (result.attrib&_A_HIDDEN ? 'h' : '-');
               attrib_str[2] =3D (result.attrib&_A_SYSTEM ? 's' : '-');
               attrib_str[3] =3D (result.attrib&_A_VOLID  ? 'l' : '-');
               attrib_str[4] =3D (result.attrib&_A_SUBDIR ? 'd' : '-');
               attrib_str[5] =3D (result.attrib&_A_ARCH   ? 'a' : '-');
               attrib_str[6] =3D '\0';

               time_write =3D _ftime_to_time_t((struct ftime =
*)&result.wr_time);

               strftime(time_str, sizeof(time_str), "%m/%d/%Y %H:%M ", =
localtime(&time_write));

               printf("%-14s  %5ld kb  %s  %s\n", result.name, 1 + =
result.size/1024, attrib_str, time_str);

               c++;
            }
            while (_dos_findnext(&result) =3D=3D 0);

            printf("%d matching file%s\n", c, c>1 ? "s." : ".");
         }
         break;

      case 2:
         ret =3D findfirst(argv[1], &ffblk, ALL_FATTRIB);

         if (ret) {
            printf("no matching file.\n");
         }
         else {
            do {
               attrib_str[0] =3D (ffblk.ff_attrib&FA_RDONLY ? 'r' : =
'-');
               attrib_str[1] =3D (ffblk.ff_attrib&FA_HIDDEN ? 'h' : =
'-');
               attrib_str[2] =3D (ffblk.ff_attrib&FA_SYSTEM ? 's' : =
'-');
               attrib_str[3] =3D (ffblk.ff_attrib&FA_LABEL  ? 'l' : =
'-');
               attrib_str[4] =3D (ffblk.ff_attrib&FA_DIREC  ? 'd' : =
'-');
               attrib_str[5] =3D (ffblk.ff_attrib&FA_ARCH   ? 'a' : =
'-');
               attrib_str[6] =3D '\0';

               time_write =3D _ftime_to_time_t((struct ftime =
*)&ffblk.ff_ftime);

               strftime(time_str, sizeof(time_str), "%m/%d/%Y %H:%M ", =
localtime(&time_write));

               printf("%-14s  %5ld kb  %s  %s\n", ffblk.ff_name, 1 + =
ffblk.ff_fsize/1024, attrib_str, time_str);

               c++;
            }
            while (findnext(&ffblk) =3D=3D 0);

            printf("%d matching file%s\n", c, c>1 ? "s." : ".");
         }
         break;

      case 3:
         handle =3D _findfirst(argv[1], &fileinfo);

         if (handle<0) {
            printf("no matching file.\n");
         }
         else {
            do {
               attrib_str[0] =3D (fileinfo.attrib&_A_RDONLY ? 'r' : =
'-');
               attrib_str[1] =3D (fileinfo.attrib&_A_HIDDEN ? 'h' : =
'-');
               attrib_str[2] =3D (fileinfo.attrib&_A_SYSTEM ? 's' : =
'-');
               attrib_str[3] =3D (fileinfo.attrib&_A_VOLID  ? 'l' : =
'-');
               attrib_str[4] =3D (fileinfo.attrib&_A_SUBDIR ? 'd' : =
'-');
               attrib_str[5] =3D (fileinfo.attrib&_A_ARCH   ? 'a' : =
'-');
               attrib_str[6] =3D '\0';

               strftime(time_str, sizeof(time_str), "%m/%d/%Y %H:%M ", =
localtime(&fileinfo.time_write));

               printf("%-14s  %5ld kb  %s  %s\n", fileinfo.name, 1 + =
fileinfo.size/1024, attrib_str, time_str);

               c++;
            }
            while (_findnext(handle, &fileinfo) =3D=3D 0);

            _findclose(handle);

            printf("%d matching file%s\n", c, c>1 ? "s." : ".");
         }
         break;
   }

   return 0;
}

------=_NextPart_000_0015_01C15BEF.653A1060--

- Raw text -


  webmaster     delorie software   privacy  
  Copyright © 2019   by DJ Delorie     Updated Jul 2019