ftp.delorie.com/archives/browse.cgi   search  
Mail Archives: djgpp/2011/09/25/18:34:38

X-Authentication-Warning: delorie.com: mail set sender to djgpp-bounces using -f
X-Recipient: djgpp AT delorie DOT com
X-Authenticated: #27081556
X-Provags-ID: V01U2FsdGVkX18riaFRHCormdnF1ueq0yLY9+CMLRILDLLuJKK3qn
jwnFDdY1eGDPar
From: Juan Manuel Guerrero <juan DOT guerrero AT gmx DOT de>
To: djgpp AT delorie DOT com
Subject: Re: Isues concerning the INT 21 Windows95 - LONG FILENAME FUNCTIONS (0x71XX) implementation.
Date: Mon, 26 Sep 2011 00:29:41 +0200
User-Agent: KMail/1.9.10
MIME-Version: 1.0
Message-Id: <201109260029.41840.juan.guerrero@gmx.de>
X-Y-GMX-Trusted: 0

OFYI, I have produced a second version of the patch presented the last time.
This time the patch shall fix the same issues but for djdev 2.03.

Suggestions, objections, comments are welcome.

Regards,
Juan M. Guerrero




2011-09-24  Juan Manuel Guerrero  <juan DOT guerrero AT gmx DOT de>

	* src/libc/dos/io/flushdc.c: Check that 0x710D call is supported
	by checking that AX does not contain 0x7100.  If not supported fall
	back on BIOS DISK RESET.  Set CF before calling 0x710D function.

	* src/libcdos/process/dosexec.c: Check that 0x7160 call is supported
	by checking that AX does not contain 0x7100.  If not supported ignore.
	Set CF before calling 0x7160 function.

	* src/libc/posix/sys/stat/fixpath.c: Check that 0x7147 call is supported
	by checking that AX does not contain 0x7100.  If not supported fall
	back on 0x47NN.  Set CF before calling 0x713B function.

	* src/libc/posix/dirent/opendir.c: Check that 0x71A1 call is supported
	by checking that AX does not contain 0x7100.  If not supported ignore.
	Set CF before calling 0x71A1 function.

	* src/libc/posix/unistd/getcwd.c: Check that 0x713B call is supported
	by checking that AX does not contain 0x7100.  If not supported fall
	back on 0x3BNN.  Set CF before calling 0x7147 function.

	* src/libc/posix/sys/stat/mkdir.c: Check that 0x7139 call is supported
	by checking that AX does not contain 0x7100.  If not supported fall
	back on 0x39NN.  Set CF before calling 0x7139 function.

	* src/libc/posix/unistd/rmdir.c: Check that 0x713A call is supported
	by checking that AX does not contain 0x7100.  If not supported fail.
	Set CF before calling 0x713A function.

	* src/libc/posix/unistd/chdir.c: Check that 0x713B call is supported
	by checking that AX does not contain 0x7100.  If not supported fall
	back on 0x3BNN.  Set CF before calling 0x713B function.

	* src/libc/posix/sys/stat/fstat.c:  Check that 0x71A6 call is
	supported by checking that AX does not contain 0x7100.  If not
	supported ignore.  Set CF before calling 0x71A6 function.

	* src/libc/dos/io/_open.c: If 0x716C function not supported fall
	back on SFN.  Set CF before calling 0x716C function.

	* src/libc/dos/io/_chmod.c: If 0x7143 function not supported fail.
	Set CF before calling 0x7143 function.

	* src/libc/dos/io/_creat_n.c: If 0x716C function not supported fall
	back on SFN.  Set CF before calling 0x716C function.

	* src/libc/dos/io/_creat.c: If 0x716C function not supported fall
	back on SFN.  Set CF before calling 0x716C function.

	* src/libc/ansi/stdio/remove.c: Check that 0x713A and 0x7141 calls are
	supported by checking that AX does not contain 0x7100.  If not supported
	fail.  Set CF before calling 0x71NN function.

	* src/libc/ansi/stdio/findfirs.c: Check that 0x714E call is supported
	by checking that AX does not contain 0x7100.  If not supported fail.
	Set CF before calling 0x714E function.

	* src/libc/ansi/stdio/findnext.c: Check that 0x714F call is supported
	by checking that AX does not contain 0x7100.  If not supported fail.
	Set CF before calling 0x714F function.

	* src/libc/dos/dos/truename.c: Check that 0x7160 call is supported
	by checking that AX does not contain 0x7100.  If not supported fall
	back on 0x6000.  Set CF before calling 0x7160 function.

	* src/libc/dos/lfn/lfnshort.c: If 0x71a8 function not supported fall
	back on SFN.  Set CF before calling 0x71a8 function.

	* src/libc/dos/lfn/_use_lfn.c: Set CF before calling 0x71a0 function.

	* src/libc/ansi/stdio/_rename.c: Check that 0x71A6 call is supported
	by checking that AX does not contain 0x7100.  If not supported fail.
	Set CF before calling 0x71A6 function.






diff -aprNU5 djgpp-2.03.orig/src/libc/ansi/stdio/_rename.c djgpp-2.03/src/libc/ansi/stdio/_rename.c
--- djgpp-2.03.orig/src/libc/ansi/stdio/_rename.c	2001-03-18 16:52:40 +0000
+++ djgpp-2.03/src/libc/ansi/stdio/_rename.c	2011-09-25 12:40:46 +0000
@@ -1,5 +1,6 @@
+/* Copyright (C) 2011 DJ Delorie, see COPYING.DJ for details */
 /* Copyright (C) 2001 DJ Delorie, see COPYING.DJ for details */
 /* Copyright (C) 2000 DJ Delorie, see COPYING.DJ for details */
 /* Copyright (C) 1999 DJ Delorie, see COPYING.DJ for details */
 /* Copyright (C) 1998 DJ Delorie, see COPYING.DJ for details */
 /* Copyright (C) 1997 DJ Delorie, see COPYING.DJ for details */
@@ -67,11 +68,11 @@ int _rename(const char *old, const char
        makes OLD and NEW the same file.  We must rename
        through a temporary file to work around this.  */
 
     char *pbase = 0, *p;
     static char try_char[] = "abcdefghijklmnopqrstuvwxyz012345789";
-    int idx = sizeof(try_char)-1;
+    int idx = sizeof(try_char) - 1;
 
     /* Generate a temporary name.  Can't use `tmpnam', since $TMPDIR
        might point to another drive, which will fail the DOS call.  */
     strcpy(tempfile, old);
     for (p = tempfile; *p; p++)	/* ensure temporary is on the same drive */
@@ -88,16 +89,20 @@ int _rename(const char *old, const char
       if (idx <= 0)
 	return -1;
       *pbase = try_char[--idx];
     } while (_chmod(tempfile, 0) != -1);
 
+    r.x.flags |= 1;  /* Always set CF before calling a 0x71NN function. */
     r.x.ax = 0x7156;
     _put_path2(tempfile, olen);
     _put_path(old);
     __dpmi_int(0x21, &r);
-    if (r.x.flags & 1)
+    if ((r.x.flags & 1) || (r.x.ax == 0x7100))
     {
+      /*  Never assume that the complete LFN API is implemented,
+          so check that AX != 0x7100.  E.G.: MSDOS 6.22 and DOSLFN 0.40.
+          If not supported fail.  */
       errno = __doserr_to_errno(r.x.ax);
       return -1;
     }
 
     /* Now create a file with the original name.  This will
@@ -109,14 +114,17 @@ int _rename(const char *old, const char
     olen = strlen(tempfile) + 1;
     old  = tempfile;
     r.x.di = __tb_offset + olen;
   }
 
-  for (i=0; i<2; i++)
+  for (i = 0; i < 2; i++)
   {
-    if(use_lfn)
+    if (use_lfn)
+    {
+      r.x.flags |= 1;  /* Always set CF before calling a 0x71NN function. */
       r.x.ax = 0x7156;
+    }
 #if 0
     /* It seems that no version of DOS, including DOS 8, which is part
        of Windows/ME, implements this function.  Without LFN, this fails
        _rename on Windows/ME.  Disabled.  */
     else if ((_osmajor > 7 && _osmajor < 10) /* OS/2 returns v10 and above */
@@ -133,11 +141,11 @@ int _rename(const char *old, const char
     else
       r.h.ah = 0x56;
     _put_path2(new, olen);
     _put_path(old);
     __dpmi_int(0x21, &r);
-    if(r.x.flags & 1)
+    if ((r.x.flags & 1) || (r.x.ax == 0x7100))
     {
       if (i == 0
 	  && !identical_but_for_case /* don't nuke OLD! */
 	  && (r.x.ax == 5 || (r.x.ax == 2 && __file_exists(old))
 	      /* Windows 2000 returns B7h when the target file exists.  */
diff -aprNU5 djgpp-2.03.orig/src/libc/dos/dir/findfirs.c djgpp-2.03/src/libc/dos/dir/findfirs.c
--- djgpp-2.03.orig/src/libc/dos/dir/findfirs.c	1996-08-31 21:09:32 +0000
+++ djgpp-2.03/src/libc/dos/dir/findfirs.c	2011-09-25 12:50:06 +0000
@@ -1,5 +1,6 @@
+/* Copyright (C) 2011 DJ Delorie, see COPYING.DJ for details */
 /* 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>
@@ -24,31 +25,37 @@ findfirst(const char *pathname, struct f
   }
 
   pathlen = strlen(pathname) + 1;
 
   _put_path(pathname);
-  if(use_lfn) {
-
+  if (use_lfn)
+  {
     /* si = 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 == 1
       #define _Win32_to_DOS (long)
     #else
       extern long _Win32_to_DOS(long long WinTime);
     #endif
 
+    r.x.flags |= 1;  /* Always set CF before calling a 0x71NN function. */
     r.x.ax = 0x714e;
     r.x.cx = attrib;
     r.x.dx = __tb_offset;
     r.x.ds = __tb_segment;
     r.x.di = __tb_offset + pathlen;
     r.x.es = r.x.ds;
     r.x.si = USEDOSDATE;
     __dpmi_int(0x21, &r);
-    if(!(r.x.flags & 1)) {
+    if (!(r.x.flags & 1) && (r.x.ax != 0x7100))
+    {
+      /*  Never assume that the complete LFN API is implemented,
+          so check that AX != 0x7100.  E.G.: MSDOS 6.22 and DOSLFN 0.40.
+          If not supported fall back on SFN API 0x4E.  */
+
       struct ffblklfn ffblk32;
       /* Recover results */
       dosmemget(__tb+pathlen, sizeof(struct ffblklfn), &ffblk32);
 
       ffblk->ff_attrib = (char)ffblk32.fd_attrib;
@@ -56,11 +63,13 @@ findfirst(const char *pathname, struct f
       ffblk->ff_fsize = ffblk32.fd_size;
       strcpy(ffblk->ff_name, ffblk32.fd_longname);
       strcpy(ffblk->lfn_magic, "LFN32");
 
       /* If no wildcards, close the handle */
-      if(!strchr(pathname,'*') && !strchr(pathname,'?')) {
+      if (!strchr(pathname, '*') && !strchr(pathname, '?'))
+      {
+        r.x.flags |= 1;  /* Always set CF before calling a 0x71NN function. */
         r.x.bx = r.x.ax;
         r.x.ax = 0x71a1;
         __dpmi_int(0x21, &r);
         r.x.ax = 0;
       }
@@ -69,11 +78,13 @@ findfirst(const char *pathname, struct f
       *(long *)(&ffblk->lfn_ctime) = _Win32_to_DOS(ffblk32.fd_ctime);
       *(long *)(&ffblk->lfn_atime) = _Win32_to_DOS(ffblk32.fd_atime);
 
       return 0;
     }
-  } else {
+  }
+  else
+  {
 
     #define _sizeof_dos_ffblk 44
     /* There will be a _sizeof_dos_ffblk character return value from findfirst 
        in the DTA.  Put the file name before this.  First set the DTA to be 
        transfer buffer. */
@@ -86,13 +97,14 @@ findfirst(const char *pathname, struct f
     r.h.ah = 0x4e;
     r.x.dx = __tb_offset;
     r.x.ds = __tb_segment;
     r.x.cx = attrib;
     __dpmi_int(0x21, &r);
-    if(!(r.x.flags & 1)) {
+    if (!(r.x.flags & 1))
+    {
       /* Recover results */
-      dosmemget(__tb+pathlen, _sizeof_dos_ffblk, ffblk);
+      dosmemget(__tb + pathlen, _sizeof_dos_ffblk, ffblk);
       return 0;
     }
   }
 
   errno = __doserr_to_errno(r.x.ax);
diff -aprNU5 djgpp-2.03.orig/src/libc/dos/dir/findnext.c djgpp-2.03/src/libc/dos/dir/findnext.c
--- djgpp-2.03.orig/src/libc/dos/dir/findnext.c	1996-08-31 22:09:32 +0000
+++ djgpp-2.03/src/libc/dos/dir/findnext.c	2011-09-25 12:56:38 +0000
@@ -1,5 +1,6 @@
+/* Copyright (C) 2011 DJ Delorie, see COPYING.DJ for details */
 /* 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>
@@ -19,11 +20,11 @@ findnext(struct ffblk *ffblk)
   {
     errno = EACCES;
     return -1;
   }
 
-  if(_USE_LFN)
+  if (_USE_LFN)
   {
     /* si = 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
@@ -31,24 +32,29 @@ findnext(struct ffblk *ffblk)
       #define _Win32_to_DOS (long)
     #else
       extern long _Win32_to_DOS(long long WinTime);
     #endif
 
+    r.x.flags |= 1;  /* Always set CF before calling a 0x71NN function. */
     r.x.ax = 0x714f;
     r.x.bx = ffblk->lfn_handle;
-    if(!r.x.bx)
+    if (!r.x.bx)
     {
       errno = ENMFILE;
       return 1;
     }
     r.x.di = __tb_offset;
     r.x.es = __tb_segment;
     r.x.si = USEDOSDATE;
 
     __dpmi_int(0x21, &r);
-    if (!(r.x.flags & 1))
+    if (!(r.x.flags & 1) && (r.x.ax != 0x7100))
     {
+      /*  Never assume that the complete LFN API is implemented,
+          so check that AX != 0x7100.  E.G.: MSDOS 6.22 and DOSLFN 0.40.
+          If not supported fall back on SFN API 0x4F.  */
+
       struct ffblklfn ffblk32;
       /* Recover results */
       dosmemget(__tb, sizeof(struct ffblklfn), &ffblk32);
 
       ffblk->ff_attrib = (char)ffblk32.fd_attrib;
@@ -62,13 +68,14 @@ findnext(struct ffblk *ffblk)
     }
     errno = __doserr_to_errno(r.x.ax);
     if (errno == ENMFILE)         /* call FindClose */
     {
       ffblk->lfn_handle = 0;
+      r.x.flags |= 1;  /* Always set CF before calling a 0x71NN function. */
       r.x.ax = 0x71a1;
       __dpmi_int(0x21, &r);
-      if(r.x.flags & 1)
+      if (r.x.flags & 1)
       {
         errno = __doserr_to_errno(r.x.ax);
         return -1;
       }
       return 1;
@@ -88,11 +95,11 @@ findnext(struct ffblk *ffblk)
 
     dosmemput(ffblk, sizeof(struct ffblk), __tb);
 
     r.h.ah = 0x4f;
     __dpmi_int(0x21, &r);
-    if(r.x.flags & 1)
+    if (r.x.flags & 1)
     {
       errno = __doserr_to_errno(r.x.ax);
       return -1;
     }
 
diff -aprNU5 djgpp-2.03.orig/src/libc/dos/dos/truename.c djgpp-2.03/src/libc/dos/dos/truename.c
--- djgpp-2.03.orig/src/libc/dos/dos/truename.c	1999-06-14 16:20:40 +0000
+++ djgpp-2.03/src/libc/dos/dos/truename.c	2011-09-25 14:38:30 +0000
@@ -1,5 +1,6 @@
+/* Copyright (C) 2011 DJ Delorie, see COPYING.DJ for details */
 /* Copyright (C) 1997 DJ Delorie, see COPYING.DJ for details */
 /* Copyright (C) 1995 DJ Delorie, see COPYING.DJ for details */
 /*
  * This is file TRUENAME.C
  *
@@ -102,25 +103,38 @@ _truename(const char *file, char *buf)
       name_start[4] = '\0';
     }
   _put_path(name_start);
 
   /* Call DOS INT 21H undocumented function 60h. */
-  if(use_lfn) {
+  if (use_lfn)
+  {
+    regs.x.flags |= 1;  /* Always set CF before calling a 0x71NN function. */
     regs.x.ax = 0x7160;
     regs.x.cx = 2;		/* Get Long Path Name (if there is one) */
-  } else
+  }
+  else
     regs.x.ax = 0x6000;
 
   /* According to Ralph Brown's Interrupt List, can't make the input
      and output buffers be the same, because it doesn't work for early
      versions of DR-DOS.  */
- lfn_retry:
+lfn_retry:
   regs.x.ds = regs.x.es = __tb_segment;
   regs.x.si = __tb_offset;
   regs.x.di = __tb_offset + MAX_TRUE_NAME;
   __dpmi_int(0x21, &regs);
 
+  if (regs.x.ax == 0x7100)
+  {
+    /*  Never assume that the complete LFN API is implemented,
+        so check that AX != 0x7100.  E.G.: MSDOS 6.22 and DOSLFN 0.40.
+        If not supported fall back on 0x6000.  */
+    use_lfn = 0;
+    regs.x.ax = 0x6000;
+    goto lfn_retry;
+  }
+
   /* Now get the result from lower memory. */
   movedata(dos_mem_selector, __tb + MAX_TRUE_NAME,
            our_mem_selector, (unsigned int)true_name, MAX_TRUE_NAME);
 
   if (regs.x.flags & 1)
diff -aprNU5 djgpp-2.03.orig/src/libc/dos/io/_chmod.c djgpp-2.03/src/libc/dos/io/_chmod.c
--- djgpp-2.03.orig/src/libc/dos/io/_chmod.c	1996-08-31 22:09:32 +0000
+++ djgpp-2.03/src/libc/dos/io/_chmod.c	2011-09-24 21:01:04 +0000
@@ -1,5 +1,6 @@
+/* Copyright (C) 2011 DJ Delorie, see COPYING.DJ for details */
 /* 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 <io.h>
 #include <errno.h>
@@ -11,23 +12,29 @@
 int
 _chmod(const char *filename, int func, ...)
 {
   __dpmi_regs r;
 
-  if(_USE_LFN) {
+  if (_USE_LFN)
+  {
+    r.x.flags |= 1;			/* Always set CF before calling a 0x71NN function. */
     r.x.ax = 0x7143;
     r.h.bl = func;			/* Get or Put */
-  } else
+  }
+  else
     r.x.ax = 0x4300 + func;
   _put_path(filename);
   if (func == 1)
     r.x.cx = *(&func + 1);		/* Value to set */
   r.x.dx = __tb_offset;
   r.x.ds = __tb_segment;
   __dpmi_int(0x21, &r);
-  if(r.x.flags & 1)
+  if ((r.x.flags & 1) || (r.x.ax == 0x7100))
   {
+    /*  Never assume that the complete LFN API is implemented,
+        so check that AX != 0x7100.  E.G.: MSDOS 6.22 and DOSLFN 0.40.
+        If not supported fail.  */
     errno = __doserr_to_errno(r.x.ax);
     return -1;
   }
  
   return r.x.cx;
diff -aprNU5 djgpp-2.03.orig/src/libc/dos/io/_creat.c djgpp-2.03/src/libc/dos/io/_creat.c
--- djgpp-2.03.orig/src/libc/dos/io/_creat.c	2001-12-05 19:41:36 +0000
+++ djgpp-2.03/src/libc/dos/io/_creat.c	2011-09-25 12:35:50 +0000
@@ -1,5 +1,6 @@
+/* Copyright (C) 2011 DJ Delorie, see COPYING.DJ for details */
 /* Copyright (C) 2001 DJ Delorie, see COPYING.DJ for details */
 /* 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 <fcntl.h>
@@ -27,36 +28,54 @@ _creat(const char* filename, int attrib)
 
   if (__FSEXT_call_open_handlers(__FSEXT_creat, &rv, &filename))
     return rv;
 
   _put_path(filename);
-  if(use_lfn) {
+  if (use_lfn)
+  {
+    r.x.flags |= 1;  /* Always set CF before calling a 0x71NN function. */
     r.x.ax = 0x716c;
     r.x.bx = 0x0002;		/* open r/w */
     r.x.dx = 0x0012;		/* Create, truncate if exists */
     r.x.si = __tb_offset;
-  } else {
+  }
+  else
+  {
     r.h.ah = 0x3c;
     r.x.dx = __tb_offset;
   }
+do_create:
   r.x.cx = attrib;
   r.x.ds = __tb_segment;
   __dpmi_int(0x21, &r);
-  if(r.x.flags & 1)
+  if (r.x.ax == 0x7100)
+  {
+    /*  Never assume that the complete LFN API is implemented,
+        so check that AX != 0x7100.  E.G.: MSDOS 6.22 and DOSLFN 0.40.
+        If not supported fall back on SFN API 0x3C.  */
+    use_lfn = 0;
+    r.h.ah = 0x3c;
+    r.x.dx = __tb_offset;
+    goto do_create;
+  }
+  else if (r.x.flags & 1)
   {
     errno = __doserr_to_errno(r.x.ax);
     return -1;
   }
-  if(use_lfn && _osmajor == 5 && _get_dos_version(1) == 0x532) {
+
+  if(use_lfn && _osmajor == 5 && _get_dos_version(1) == 0x532)
+  {
     /* Windows 2000 or XP; or NT with LFN TSR.  Windows 2000 behaves
        badly when using IOCTL and write-truncate calls on LFN handles.
        We close the long name file and re-open it with _open.c (short)
        to work around the bugs. */
     rv = _open(filename,2);	/* 2 is a read/write flag */
-    if(rv != -1) {	/* Re-open failure, continue with LFN handle */
-      dup2(rv, r.x.ax);	/* Close ax, put handle in first position (bugs) */
-      _close(rv);
+    if (rv != -1)
+    {
+      dup2(rv, r.x.ax);	/* Re-open failure, continue with LFN handle */
+      _close(rv);	/* Close ax, put handle in first position (bugs) */
     }
   }
   __file_handle_set(r.x.ax, O_BINARY);
   return r.x.ax;
 }
diff -aprNU5 djgpp-2.03.orig/src/libc/dos/io/_creat_n.c djgpp-2.03/src/libc/dos/io/_creat_n.c
--- djgpp-2.03.orig/src/libc/dos/io/_creat_n.c	2001-12-05 19:41:36 +0000
+++ djgpp-2.03/src/libc/dos/io/_creat_n.c	2011-09-25 12:26:24 +0000
@@ -1,5 +1,6 @@
+/* Copyright (C) 2011 DJ Delorie, see COPYING.DJ for details */
 /* Copyright (C) 2001 DJ Delorie, see COPYING.DJ for details */
 /* Copyright (C) 1998 DJ Delorie, see COPYING.DJ for details */
 #include <libc/stubs.h>
 #include <fcntl.h>
 #include <errno.h>
@@ -30,12 +31,15 @@ _creatnew(const char* filename, int attr
   _put_path(filename);
   r.x.bx =
     0x2002 | (flags & 0xfff0);	/* r/w, no Int 24h, use caller-defined flags */
   r.x.dx = 0x0010;		/* Create, fail if exists */
   r.x.si = __tb_offset;
-  if(use_lfn)
+  if (use_lfn)
+  {
+    r.x.flags |= 1; 		/* Always set CF before calling a 0x71NN function. */
     r.x.ax = 0x716c;
+  }
   else
   {
     if (_osmajor > 3)
       r.x.ax = 0x6c00;
     else
@@ -44,27 +48,42 @@ _creatnew(const char* filename, int attr
       r.x.bx = 0;		/* lose support for fancy flags in DOS 3.x */
       r.x.dx = __tb_offset;
       r.x.si = 0;
     }
   }
+do_create:
   r.x.cx = attrib & 0xffff;
   r.x.ds = __tb_segment;
   __dpmi_int(0x21, &r);
-  if(r.x.flags & 1)
+  if (r.x.ax == 0x7100)
+  {
+    /*  Never assume that the complete LFN API is implemented,
+        so check that AX != 0x7100.  E.G.: MSDOS 6.22 and DOSLFN 0.40.
+        If not supported fall back on SFN API 0x5B.  */
+    use_lfn = 0;
+    r.h.ah = 0x5b;
+    r.x.bx = 0;		/* lose support for fancy flags in DOS 3.x */
+    r.x.dx = __tb_offset;
+    r.x.si = 0;
+    goto do_create;
+  }
+  else if (r.x.flags & 1)
   {
     errno = __doserr_to_errno(r.x.ax);
     return -1;
   }
-  if(use_lfn && _osmajor == 5 && _get_dos_version(1) == 0x532) {
+  if (use_lfn && _osmajor == 5 && _get_dos_version(1) == 0x532)
+  {
     /* Windows 2000 or XP; or NT with LFN TSR.  Windows 2000 behaves
        badly when using IOCTL and write-truncate calls on LFN handles.
        We close the long name file and re-open it with _open.c (short)
        to work around the bugs. */
     rv = _open(filename, flags | 2);	/* 2 is a read/write flag */
-    if(rv != -1) {	/* Re-open failure, continue with LFN handle */
-      dup2(rv, r.x.ax);	/* Close ax, put handle in first position (bugs) */
-      _close(rv);
+    if (rv != -1)
+    {
+      dup2(rv, r.x.ax);	/* Re-open failure, continue with LFN handle */
+      _close(rv);	/* Close ax, put handle in first position (bugs) */
     }
   }
   __file_handle_set(r.x.ax, O_BINARY);
   return r.x.ax;
 }
diff -aprNU5 djgpp-2.03.orig/src/libc/dos/io/_open.c djgpp-2.03/src/libc/dos/io/_open.c
--- djgpp-2.03.orig/src/libc/dos/io/_open.c	2001-12-05 19:44:14 +0000
+++ djgpp-2.03/src/libc/dos/io/_open.c	2011-09-24 20:53:20 +0000
@@ -1,5 +1,6 @@
+/* Copyright (C) 2011 DJ Delorie, see COPYING.DJ for details */
 /* Copyright (C) 2001 DJ Delorie, see COPYING.DJ for details */
 /* 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 <string.h>
@@ -26,68 +27,90 @@ _open(const char* filename, int oflag)
   }
 
   if (__FSEXT_call_open_handlers(__FSEXT_open, &rv, &filename))
     return rv;
 
-  if(use_lfn && _osmajor == 5 && _get_dos_version(1) == 0x532) {
+  if (use_lfn && _osmajor == 5 && _get_dos_version(1) == 0x532)
+  {
     /* Windows 2000 or XP; or NT with LFN TSR.  Windows 2000 behaves
        badly when using IOCTL and write-truncate calls on LFN handles.
        We convert the long name to a short name and open existing files
        via short name.  New files use LFN, but we know they aren't
        character devices. */
+    r.x.flags |= 1;			/* Always set CF before calling a 0x71NN function. */
     r.x.ax = 0x7160;
     r.x.cx = 1;				/* Get short name equivalent */
     r.x.ds = __tb_segment;
     r.x.si = __tb_offset;		/* Long name to convert - putpath */
     r.x.es = __tb_segment;
     r.x.di = __tb_offset + _put_path(filename);	/* Short name destination */
     __dpmi_int(0x21, &r);
-    if(!(r.x.flags & 1)) {		/* Get short name success */
+    if (!(r.x.flags & 1)) 		/* Get short name success */
+    {
       r.x.ax = 0x6c00;
       r.x.bx = (oflag & 0xff);
       r.x.dx = 1;			/* Open existing file */
       r.x.si = r.x.di;
       goto do_open;
-    } else {
+    }
+    else
+    {
       /* Short name get failed, file doesn't exist or is device (same error) */
+      r.x.flags |= 1;			/* Always set CF before calling a 0x71NN function. */
       r.x.ax = 0x7143;			/* Get attributes */
       r.h.bl = 0;
       r.x.dx = __tb_offset;		/* Original long name */
       __dpmi_int(0x21, &r);		/* This is same as lfn _chmod */
-      if(!(r.x.flags & 1)) {		/* Name exists, probably device */
+      if (!(r.x.flags & 1)) 		/* Name exists, probably device */
+      {
         r.x.ax = 0x6c00;
         r.x.bx = (oflag & 0xff);
         r.x.dx = 1;                     /* Open existing file */
         r.x.si = __tb_offset;		/* Treat original name as short */
         r.x.cx = 0;
         __dpmi_int(0x21, &r);
-        if(!(r.x.flags & 1)) {		/* Success! */
+        if (!(r.x.flags & 1)) 		/* Success! */
           goto do_hset;
-        }
+
 	/* Fail on short name open after _chmod said OK.
 	   Device with directory?  We should re-try with LFN.
 	   Permission?  Readonly file?  We should quit.
 	   Let it fall through to the LFN open which should succeed.  */
       }
     }
   }
-  if(use_lfn) {
+  if (use_lfn)
+  {
+    r.x.flags |= 1;  /* Always set CF before calling a 0x71NN function. */
     r.x.ax = 0x716c;
     r.x.bx = oflag & 0xff;
     r.x.dx = 1;			/* Open existing file */
     r.x.si = __tb_offset;
-  } else {
+  }
+  else
+  {
     r.h.ah = 0x3d;
     r.h.al = oflag;
     r.x.dx = __tb_offset;
   }
   r.x.ds = __tb_segment;
   _put_path(filename);
 do_open:
   r.x.cx = 0;
   __dpmi_int(0x21, &r);
-  if(r.x.flags & 1)
+  if (r.x.ax == 0x7100)
+  {
+    /*  Never assume that the complete LFN API is implemented,
+        so check that AX != 0x7100.  E.G.: MSDOS 6.22 and DOSLFN 0.40.
+        If not supported fall back on SFN API 0x3D.  */
+    use_lfn = 0;
+    r.h.ah = 0x3d;
+    r.h.al = oflag;
+    r.x.dx = __tb_offset;
+    goto do_open;
+  }
+  else if (r.x.flags & 1)
   {
     errno = __doserr_to_errno(r.x.ax);
     return -1;
   }
 do_hset:
diff -aprNU5 djgpp-2.03.orig/src/libc/dos/io/flushdc.c djgpp-2.03/src/libc/dos/io/flushdc.c
--- djgpp-2.03.orig/src/libc/dos/io/flushdc.c	1996-09-19 23:38:56 +0000
+++ djgpp-2.03/src/libc/dos/io/flushdc.c	2011-09-24 20:31:52 +0000
@@ -1,37 +1,44 @@
+/* Copyright (C) 2011 DJ Delorie, see COPYING.DJ for details */
 /* Copyright (C) 1996 DJ Delorie, see COPYING.DJ for details */
 #include <libc/stubs.h>
 #include <fcntl.h>	/* for _USE_LFN */
 #include <io.h>		/* for the prototype of `_flush_disk_cache' */
 #include <dir.h>	/* for `getdisk' */
 #include <dpmi.h>	/* for `__dpmi_int' and friends */
 
 /* Try to cause the disk cache to write the cached data to disk(s).  */
 void
-_flush_disk_cache (void)
+_flush_disk_cache(void)
 {
   __dpmi_regs r;
-  int drv = getdisk ();
+  int drv = getdisk();
 
   if (_USE_LFN)
+  {
+    /* Windows 95 have special function to do what we want.  */
+    /* FIXME: What if LFN is supported by a platform other than W95?  */
+    r.x.flags |= 1;  /* Always set CF before calling a 0x71XX function. */
+    r.x.ax = 0x710d;
+    r.x.cx = 1;      /* flush buffers and cache, reset drive */
+    r.x.dx = drv + 1;
+    __dpmi_int (0x21, &r);
+    if ((r.x.flags & 1) || (r.x.ax == 0x7100))
     {
-      /* Windows 95 have special function to do what we want.  */
-      /* FIXME: What if LFN is supported by a platform other than W95?  */
-      r.x.ax = 0x710d;
-      r.x.cx = 1;	/* flush buffers and cache, reset drive */
-      r.x.dx = drv + 1;
-      __dpmi_int (0x21, &r);
-      /* According to docs (Interrupt list), this doesn't return
-	 any error codes (??).  */
-    }
-  else
-    {
-      /* The BIOS Disk Reset function causes most DOS caches to flush.  */
-      r.x.ax = 0;
-      /* Hard disks should have 7th bit set.  */
-      /* FIXME: The mapping between DOS drive numbers and BIOS
-	 drives is ignored.  The assumption is that Reset function
-	 on ANY hard disk causes the cache to flush its buffers.  */
-      r.x.dx = drv > 2 ? ((drv - 2) | 0x80) : drv;
-      __dpmi_int (0x13, &r);
+      /*  Never assume that the complete LFN API is implemented,
+          so check that AX != 0x7100.  E.G.: MSDOS 6.22 and DOSLFN 0.40.
+          If not supported fall back on SFN API.  */
+      goto do_BIOS_DISK_RESET;
     }
+    return;
+  }
+
+do_BIOS_DISK_RESET:
+  /* The BIOS Disk Reset function causes most DOS caches to flush.  */
+  r.x.ax = 0;
+  /* Hard disks should have 7th bit set.  */
+  /* FIXME: The mapping between DOS drive numbers and BIOS
+     drives is ignored.  The assumption is that Reset function
+     on ANY hard disk causes the cache to flush its buffers.  */
+  r.x.dx = drv > 2 ? ((drv - 2) | 0x80) : drv;
+  __dpmi_int(0x13, &r);
 }
diff -aprNU5 djgpp-2.03.orig/src/libc/dos/lfn/_use_lfn.c djgpp-2.03/src/libc/dos/lfn/_use_lfn.c
--- djgpp-2.03.orig/src/libc/dos/lfn/_use_lfn.c	1999-12-24 20:00:40 +0000
+++ djgpp-2.03/src/libc/dos/lfn/_use_lfn.c	2011-09-25 14:42:40 +0000
@@ -1,5 +1,6 @@
+/* Copyright (C) 2011 DJ Delorie, see COPYING.DJ for details */
 /* Copyright (C) 1999 DJ Delorie, see COPYING.DJ for details */
 /* Copyright (C) 1998 DJ Delorie, see COPYING.DJ for details */
 /* Copyright (C) 1997 DJ Delorie, see COPYING.DJ for details */
 /* Copyright (C) 1996 DJ Delorie, see COPYING.DJ for details */
 /* Copyright (C) 1995 DJ Delorie, see COPYING.DJ for details */
@@ -69,19 +70,20 @@ _get_volume_info (const char *path, int
     _farpokeb(_dos_ds, tbuf_la++, ':');
     _farpokeb(_dos_ds, tbuf_la++, '\\');
     _farpokeb(_dos_ds, tbuf_la++, '\0');
   }
 
+  r.x.flags |= 1;	/* Always set CF before calling a 0x71NN function. */
   r.x.ax = 0x71a0;	/* Get Volume Information function */
   r.x.ds = tbuf_seg;	/* DS:DX points to root directory name */
   r.x.dx = 0;
   r.x.es = tbuf_seg;	/* ES:DI points to a buffer for filesys name */
   r.x.di = (tbuf_la - __tb) & 0xffff;
   r.x.cx = 32;		/* max size of filesystem name (Interrupt List) */
   __dpmi_int(0x21, &r);
 
-  if ((r.x.flags & 1) == 0 && r.x.ax != 0x7100)
+  if (!(r.x.flags & 1) && (r.x.ax != 0x7100))
   {
     char *p = fsystype, c;
 
     retval   = r.x.bx;
     if (maxfile)
diff -aprNU5 djgpp-2.03.orig/src/libc/dos/lfn/lfnshort.c djgpp-2.03/src/libc/dos/lfn/lfnshort.c
--- djgpp-2.03.orig/src/libc/dos/lfn/lfnshort.c	1999-06-03 17:27:34 +0000
+++ djgpp-2.03/src/libc/dos/lfn/lfnshort.c	2011-09-25 14:41:02 +0000
@@ -1,5 +1,6 @@
+/* Copyright (C) 2011 DJ Delorie, see COPYING.DJ for details */
 /* Copyright (C) 1999 DJ Delorie, see COPYING.DJ for details */
 /* Copyright (C) 1998 DJ Delorie, see COPYING.DJ for details */
 /* Copyright (C) 1997 DJ Delorie, see COPYING.DJ for details */
 #include <libc/stubs.h>
 #include <ctype.h>
@@ -19,10 +20,11 @@ char *
 _lfn_gen_short_fname (const char *long_fname, char *short_fname)
 {
   __dpmi_regs r;
   unsigned long tbuf = __tb;
 
+  r.x.flags |= 1;  /* Always set CF before calling a 0x71NN function. */
   r.x.ax = 0x7100;
   if (_USE_LFN)
     {
       dosmemput (long_fname, strlen (long_fname) + 1, tbuf);
       r.x.ax = 0x71a8;
@@ -32,11 +34,11 @@ _lfn_gen_short_fname (const char *long_f
       r.x.di = 260;
       r.x.dx = 0x0011;	/* DH=01 would be better, but it's buggy */
       __dpmi_int (0x21, &r);
     }
 
-  if ((r.x.flags & 1) == 0 && r.x.ax != 0x7100)
+  if (!(r.x.flags & 1) && (r.x.ax != 0x7100))
     {
       char buf[13], *s = buf, *d = short_fname;
 
       dosmemget (tbuf + 260, sizeof buf, buf);
 
diff -aprNU5 djgpp-2.03.orig/src/libc/dos/process/dosexec.c djgpp-2.03/src/libc/dos/process/dosexec.c
--- djgpp-2.03.orig/src/libc/dos/process/dosexec.c	2001-12-11 06:42:06 +0000
+++ djgpp-2.03/src/libc/dos/process/dosexec.c	2011-09-24 20:31:52 +0000
@@ -1,5 +1,6 @@
+/* Copyright (C) 2011 DJ Delorie, see COPYING.DJ for details */
 /* Copyright (C) 1999 DJ Delorie, see COPYING.DJ for details */
 /* Copyright (C) 1998 DJ Delorie, see COPYING.DJ for details */
 /* Copyright (C) 1996 DJ Delorie, see COPYING.DJ for details */
 /* Copyright (C) 1995 DJ Delorie, see COPYING.DJ for details */
 #include <libc/stubs.h>
@@ -180,18 +181,23 @@ direct_exec_tail_1 (const char *program,
   if (!check_talloc(proglen))
     return -1;
   /* Make sure any magic names, like /dev/c/foo, are converted to the
      usual DOS form, and, under LFN, to the short 8+3 alias.  */
   _put_path2(program, tbuf_beg == __tb ? tbuf_ptr - tbuf_beg : 0);
-  if(lfn) {
+  if (lfn)
+  {
+    r.x.flags |= 1;			/* Always set CF before calling a 0x71NN function. */
     r.x.ax = 0x7160;			/* Truename */
     r.x.cx = 1;				/* Get short name */
     r.x.ds = r.x.es = tbuf_ptr / 16;
     r.x.si = r.x.di = tbuf_ptr & 15;
     __dpmi_int(0x21, &r);
-    if (r.x.flags & 1)
+    if ((r.x.flags & 1) || (r.x.ax == 0x7100))
     {
+      /*  Never assume that the complete LFN API is implemented,
+          so check that AX != 0x7100.  E.G.: MSDOS 6.22 and DOSLFN 0.40.
+          If not supported fail.  */
       errno = __doserr_to_errno(r.x.ax);
       return -1;
     }
   }
   dosmemget(tbuf_beg == __tb ? tbuf_ptr : __tb, FILENAME_MAX, short_name);
diff -aprNU5 djgpp-2.03.orig/src/libc/posix/dirent/opendir.c djgpp-2.03/src/libc/posix/dirent/opendir.c
--- djgpp-2.03.orig/src/libc/posix/dirent/opendir.c	1998-11-15 13:48:38 +0000
+++ djgpp-2.03/src/libc/posix/dirent/opendir.c	2011-09-24 20:31:52 +0000
@@ -1,5 +1,6 @@
+/* Copyright (C) 2011 DJ Delorie, see COPYING.DJ for details */
 /* Copyright (C) 1998 DJ Delorie, see COPYING.DJ for details */
 /* Copyright (C) 1997 DJ Delorie, see COPYING.DJ for details */
 /* Copyright (C) 1996 DJ Delorie, see COPYING.DJ for details */
 /* Copyright (C) 1995 DJ Delorie, see COPYING.DJ for details */
 #include <libc/stubs.h>
@@ -19,15 +20,19 @@
 void
 _lfn_find_close(int handle)
 {
   __dpmi_regs r;
 
+  r.x.flags |= 1;  /* Always set CF before calling a 0x71NN function. */
   r.x.bx = handle;
   r.x.ax = 0x71a1;
   __dpmi_int(0x21, &r);
-  if (r.x.flags & 1)
+  if ((r.x.flags & 1) || (r.x.ax == 0x7100))
   {
+    /*  Never assume that the complete LFN API is implemented,
+        so check that AX != 0x7100.  E.G.: MSDOS 6.22 and DOSLFN 0.40.
+        If not supported fail.  */
     errno = __doserr_to_errno(r.x.ax);
   }
 }
 
 void
diff -aprNU5 djgpp-2.03.orig/src/libc/posix/sys/stat/fixpath.c djgpp-2.03/src/libc/posix/sys/stat/fixpath.c
--- djgpp-2.03.orig/src/libc/posix/sys/stat/fixpath.c	2001-12-05 18:47:18 +0000
+++ djgpp-2.03/src/libc/posix/sys/stat/fixpath.c	2011-09-24 20:31:52 +0000
@@ -1,5 +1,6 @@
+/* Copyright (C) 2011 DJ Delorie, see COPYING.DJ for details */
 /* Copyright (C) 2001 DJ Delorie, see COPYING.DJ for details */
 /* Copyright (C) 1999 DJ Delorie, see COPYING.DJ for details */
 /* Copyright (C) 1997 DJ Delorie, see COPYING.DJ for details */
 /* Copyright (C) 1996 DJ Delorie, see COPYING.DJ for details */
 /* Copyright (C) 1995 DJ Delorie, see COPYING.DJ for details */
@@ -26,20 +27,30 @@ __get_current_directory(char *out, int d
   __dpmi_regs r;
   char tmpbuf[FILENAME_MAX];
 
   memset(&r, 0, sizeof(r));
   r.x.flags = 1;		/* Set carry for safety */
-  if(use_lfn)
+  if (use_lfn)
     r.x.ax = 0x7147;
   else
     r.h.ah = 0x47;
+do_get_current_directory:
   r.h.dl = drive_number + 1;
   r.x.si = __tb_offset;
   r.x.ds = __tb_segment;
   __dpmi_int(0x21, &r);
 
-  if (r.x.flags & 1)
+  if (r.x.ax == 0x7100)
+  {
+    /*  Never assume that the complete LFN API is implemented,
+        so check that AX != 0x7100.  E.G.: MSDOS 6.22 and DOSLFN 0.40.
+        If not supported fall back on SFN API 0x47.  */
+    use_lfn = 0;
+    r.h.ah = 0x47;
+    goto do_get_current_directory;
+  }
+  else if (r.x.flags & 1)
   {
 #ifdef TEST
     errno = __doserr_to_errno(r.x.ax);
     perror("Get dir failed in fixpath");
 #endif
@@ -293,41 +304,61 @@ _fixpath(const char *in, char *out)
 int main (int argc, char *argv[])
 {
   char fixed[FILENAME_MAX];
   __dpmi_regs r;
 
-  if (argc > 2) {
+  if (argc > 2)
+  {
     _put_path(argv[1]);
-    if(_USE_LFN)
+    r.x.flags = 1;		/* Set carry for safety */
+    if (_USE_LFN)
       r.x.ax = 0x713b;
     else
       r.h.ah = 0x3b;
     r.x.dx = __tb_offset;
     r.x.ds = __tb_segment;
     __dpmi_int(0x21, &r);
-    if(r.x.flags & 1) {
+    if (r.x.ax == 0x7100)
+    {
+      /*  Never assume that the complete LFN API is implemented,
+          so check that AX != 0x7100.  E.G.: MSDOS 6.22 and DOSLFN 0.40. */
+      errno = __doserr_to_errno(r.x.ax);
+      sprintf(fixed, "Change dir to %s failed (lfn=%d).  LFN driver does not support 0x713B", argv[1], _USE_LFN);
+      perror(fixed);
+    }
+    else if (r.x.flags & 1)
+    {
       errno = __doserr_to_errno(r.x.ax);
       sprintf(fixed, "Change dir to %s failed (lfn=%d)", argv[1], _USE_LFN);
       perror(fixed);
-    } else
+    }
+    else
       printf("Set dir: %s\n", argv[1]);
     argc--;
     argv++;
   }
 
+
+  r.x.flags = 1;		/* Set carry for safety */
   if(_USE_LFN)
     r.x.ax = 0x7147;
   else
     r.h.ah = 0x47;
   r.h.dl = 0;
   r.x.si = __tb_offset;
   r.x.ds = __tb_segment;
   __dpmi_int(0x21, &r);
-  if (r.x.flags & 1) {
+  if (r.x.ax == 0x7100)
+  {
+    /*  Never assume that the complete LFN API is implemented,
+        so check that AX != 0x7100.  E.G.: MSDOS 6.22 and DOSLFN 0.40. */
     errno = __doserr_to_errno(r.x.ax);
+    printf("getcwd failed.  LFN driver does not support 0x7147");
     perror("getcwd failed");
-  } else {
+  }
+  else
+  {
     dosmemget(__tb, sizeof(fixed), fixed);
     printf("Get dir[%d]: \\%s\n", strlen(fixed), fixed);
   }
 
   if (argc > 1)
diff -aprNU5 djgpp-2.03.orig/src/libc/posix/sys/stat/fstat.c djgpp-2.03/src/libc/posix/sys/stat/fstat.c
--- djgpp-2.03.orig/src/libc/posix/sys/stat/fstat.c	2001-12-05 18:59:48 +0000
+++ djgpp-2.03/src/libc/posix/sys/stat/fstat.c	2011-09-24 20:39:46 +0000
@@ -1,5 +1,6 @@
+/* Copyright (C) 2011 DJ Delorie, see COPYING.DJ for details */
 /* Copyright (C) 2001 DJ Delorie, see COPYING.DJ for details */
 /* Copyright (C) 2000 DJ Delorie, see COPYING.DJ for details */
 /* Copyright (C) 1998 DJ Delorie, see COPYING.DJ for details */
 /* Copyright (C) 1997 DJ Delorie, see COPYING.DJ for details */
 /* Copyright (C) 1996 DJ Delorie, see COPYING.DJ for details */
@@ -785,18 +786,23 @@ fstat_assist(int fhandle, struct stat *s
 	     such handles aren't supported by 71A6h call we use here.  */
 	  if  (_USE_LFN)
 	    {
 	      __dpmi_regs r;
 
+	      r.x.flags |= 1;    /* Always set CF before calling a 0x71NN function. */
 	      r.x.ax = 0x71a6;	/* file info by handle */
 	      r.x.bx = fhandle;
 	      r.x.ds = __tb >> 4;
 	      r.x.dx = 0;
 	      __dpmi_int(0x21, &r);
-	      if ((r.x.flags & 1) == 0
+	      if (!(r.x.flags & 1) && (r.x.ax != 0x7100)
 		  && (_farpeekl(_dos_ds, __tb) & 0x07) == 0)
+	      {
+		/*  Never assume that the complete LFN API is implemented,
+		    so check that AX != 0x7100.  E.G.: MSDOS 6.22 and DOSLFN 0.40.  */
 		stat_buf->st_mode |= WRITE_ACCESS; /* no R, S or H bits set */
+	      }
 	    }
 
           /* Executables are detected if they have magic numbers.  */
           if ( (_djstat_flags & _STAT_EXEC_MAGIC) == 0 &&
                _is_executable((const char *)0, fhandle, (const char *)0))
diff -aprNU5 djgpp-2.03.orig/src/libc/posix/sys/stat/mkdir.c djgpp-2.03/src/libc/posix/sys/stat/mkdir.c
--- djgpp-2.03.orig/src/libc/posix/sys/stat/mkdir.c	2001-12-05 18:53:30 +0000
+++ djgpp-2.03/src/libc/posix/sys/stat/mkdir.c	2011-09-24 20:31:52 +0000
@@ -1,5 +1,6 @@
+/* Copyright (C) 2011 DJ Delorie, see COPYING.DJ for details */
 /* Copyright (C) 2001 DJ Delorie, see COPYING.DJ for details */
 /* Copyright (C) 1998 DJ Delorie, see COPYING.DJ for details */
 /* Copyright (C) 1996 DJ Delorie, see COPYING.DJ for details */
 /* Copyright (C) 1995 DJ Delorie, see COPYING.DJ for details */
 #include <libc/stubs.h>
@@ -20,12 +21,15 @@ mkdir(const char *mydirname, mode_t mode
   int use_lfn = _USE_LFN;
   unsigned attr;
 
   _put_path(mydirname);
  
-  if(use_lfn)
-    r.x.ax = 0x7139;
+  if (use_lfn)
+  {
+    r.x.flags |= 1;  /* Always set CF before calling a 0x71NN function. */
+     r.x.ax = 0x7139;
+  }
 #if 0
   /* It seems that no version of DOS, including DOS 8, which is part
      of Windows/ME, implements this function.  Without LFN, this fails
      mkdir on Windows/ME.  Disabled.  */
   else if ((_osmajor > 7 && _osmajor < 10) /* OS/2 returns v10 and above */
@@ -39,26 +43,35 @@ mkdir(const char *mydirname, mode_t mode
     r.h.cl = 0x39;
   }
 #endif
   else
     r.h.ah = 0x39;
+do_mkdir:
   r.x.ds = __tb_segment;
   r.x.dx = __tb_offset;
   __dpmi_int(0x21, &r);
  
-  if (r.x.flags & 1)
+  if (r.x.ax == 0x7100)
+  {
+    /*  Never assume that the complete LFN API is implemented,
+        so check that AX != 0x7100.  E.G.: MSDOS 6.22 and DOSLFN 0.40.
+        If not supported fall back on SFN API 0x39.  */
+    r.h.ah = 0x39;
+    goto do_mkdir;
+  }
+  else if (r.x.flags & 1)
   {
     int save_errno;
     save_errno = errno = __doserr_to_errno(r.x.ax);
     if (errno == EACCES)
     {
       /* see if the directory existed, in which case
-	 we should return EEXIST - DJ */
+         we should return EEXIST - DJ */
       if (access(mydirname, D_OK) == 0)
-	errno = EEXIST;
+        errno = EEXIST;
       else
-	errno = save_errno;
+        errno = save_errno;
     }
     return -1;
   }
 
   /* mkdir is stub'd, and we don't want to stub chmod also.  */
diff -aprNU5 djgpp-2.03.orig/src/libc/posix/unistd/chdir.c djgpp-2.03/src/libc/posix/unistd/chdir.c
--- djgpp-2.03.orig/src/libc/posix/unistd/chdir.c	2001-12-05 18:36:52 +0000
+++ djgpp-2.03/src/libc/posix/unistd/chdir.c	2011-09-24 20:31:52 +0000
@@ -1,5 +1,6 @@
+/* Copyright (C) 2011 DJ Delorie, see COPYING.DJ for details */
 /* Copyright (C) 2001 DJ Delorie, see COPYING.DJ for details */
 /* Copyright (C) 2000 DJ Delorie, see COPYING.DJ for details */
 /* Copyright (C) 1998 DJ Delorie, see COPYING.DJ for details */
 /* Copyright (C) 1996 DJ Delorie, see COPYING.DJ for details */
 /* Copyright (C) 1995 DJ Delorie, see COPYING.DJ for details */
@@ -46,18 +47,30 @@ __chdir (const char *mydirname)
     __dpmi_int(0x21, &r);
   }
 
   if (drv_no == -1 || _farpeekb(_dos_ds, __tb + 2) != 0)
   {
-    if(_USE_LFN)
+    if (_USE_LFN)
+    {
+      r.x.flags |= 1;  /* Always set CF before calling a 0x71NN function. */
       r.x.ax = 0x713b;
+    }
     else
       r.h.ah = 0x3b;
+do_chdir:
     r.x.dx = __tb_offset;
     r.x.ds = __tb_segment;
     __dpmi_int(0x21, &r);
-    if(r.x.flags & 1)
+    if (r.x.ax == 0x7100)
+    {
+      /*  Never assume that the complete LFN API is implemented,
+          so check that AX != 0x7100.  E.G.: MSDOS 6.22 and DOSLFN 0.40.
+          If not supported fall back on SFN API 0c3B.  */
+      r.h.ah = 0x3b;
+      goto do_chdir;
+    }
+    else if (r.x.flags & 1)
     {
       errno = __doserr_to_errno(r.x.ax);
       return -1;
     }
   }
diff -aprNU5 djgpp-2.03.orig/src/libc/posix/unistd/getcwd.c djgpp-2.03/src/libc/posix/unistd/getcwd.c
--- djgpp-2.03.orig/src/libc/posix/unistd/getcwd.c	2001-12-05 18:15:18 +0000
+++ djgpp-2.03/src/libc/posix/unistd/getcwd.c	2011-09-24 20:31:52 +0000
@@ -1,5 +1,6 @@
+/* Copyright (C) 2011 DJ Delorie, see COPYING.DJ for details */
 /* Copyright (C) 2001 DJ Delorie, see COPYING.DJ for details */
 /* 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 <unistd.h>
@@ -44,22 +45,34 @@ __getcwd(char *buf, size_t size)
   /* make sure we don't overrun the TB */
   if (size > _go32_info_block.size_of_transfer_buffer)
     size = _go32_info_block.size_of_transfer_buffer;
 
   /* get the path into the transfer buffer at least */
-  if(use_lfn)
+  if (use_lfn)
+  {
+    r.x.flags |= 1;  /* Always set CF before calling a 0x71NN function. */
     r.x.ax = 0x7147;
-  else
+  }
     r.h.ah = 0x47;
+do_getcwd:
   r.h.dl = 0;
   r.x.si = __tb_offset;
   r.x.ds = __tb_segment;
   __dpmi_int(0x21, &r);
 
-  /* current drive may be invalid (it happens) */
-  if (r.x.flags & 1)
+  if (r.x.ax == 0x7100)
+  {
+    /*  Never assume that the complete LFN API is implemented,
+        so check that AX != 0x7100.  E.G.: MSDOS 6.22 and DOSLFN 0.40.
+        If not supported fall back on SFN API 0x47.  */
+    use_lfn = 0;
+    r.h.ah = 0x47;
+    goto do_getcwd;
+  }
+  else if (r.x.flags & 1)
   {
+    /* current drive may be invalid (it happens) */
     errno = __doserr_to_errno(r.x.ax);
     return 0;
   }
 
   /* path is ASCIIZ.  Scan it, filling in buf, watching for
diff -aprNU5 djgpp-2.03.orig/src/libc/posix/unistd/rmdir.c djgpp-2.03/src/libc/posix/unistd/rmdir.c
--- djgpp-2.03.orig/src/libc/posix/unistd/rmdir.c	1998-06-29 00:15:44 +0000
+++ djgpp-2.03/src/libc/posix/unistd/rmdir.c	2011-09-24 20:31:52 +0000
@@ -1,5 +1,6 @@
+/* Copyright (C) 2011 DJ Delorie, see COPYING.DJ for details */
 /* Copyright (C) 1998 DJ Delorie, see COPYING.DJ for details */
 /* 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 <errno.h>
@@ -13,20 +14,26 @@ int
 rmdir(const char *mydirname)
 {
   __dpmi_regs r;
 
   if(_USE_LFN)
+  {
+    r.x.flags |= 1;  /* Always set CF before calling a 0x71NN function. */
     r.x.ax = 0x713a;
+  }
   else
     r.h.ah = 0x3a;
   r.x.ds = __tb_segment;
   r.x.dx = __tb_offset;
   _put_path(mydirname);
   __dpmi_int(0x21, &r);
 
-  if (r.x.flags & 1)
+  if ((r.x.flags & 1) || (r.x.ax == 0x7100))
   {
+    /*  Never assume that the complete LFN API is implemented,
+        so check that AX != 0x7100.  E.G.: MSDOS 6.22 and DOSLFN 0.40.
+        If not supported fail.  */
     errno = __doserr_to_errno(r.x.ax);
     return -1;
   }
   return 0;
 }

- Raw text -


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