ftp.delorie.com/archives/browse.cgi   search  
Mail Archives: djgpp/2011/09/17/08:56:42

X-Authentication-Warning: delorie.com: mail set sender to djgpp-bounces using -f
X-Recipient: djgpp AT delorie DOT com
DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed;
d=gmail.com; s=gamma;
h=mime-version:in-reply-to:references:date:message-id:subject:from:to
:cc:content-type:content-transfer-encoding;
bh=UT7gQafspANHAEMtRU0UPRKn9BQpnTVNLFhr6YjYZ0Q=;
b=P/5xpHHoN0q+CFo3oKwrrBiDkLcspzMfbPJ1/tdtLjGz/NMSl/SCk7+5RLy07szzPG
HNuLAjbsmEfyLjRL4f3Cqp+uN749w1L4g+7oeI9EuihQ21IDC6ddTrLcdLfcnO+C/JQY
tc5BPB7fYzNj09X7RocpIeAxODoAVdOZuL1W4=
MIME-Version: 1.0
In-Reply-To: <201109171356.53360.juan.guerrero@gmx.de>
References: <201109171356 DOT 53360 DOT juan DOT guerrero AT gmx DOT de>
Date: Sat, 17 Sep 2011 15:56:30 +0300
Message-ID: <CAA2C=vD-Lzrt2z=gkkQcrgmssdh6F7vgU_kwVgu6o9iPGykMJQ@mail.gmail.com>
Subject: Re: Isues concerning the INT 21 Windows95 - LONG FILENAME FUNCTIONS
(0x71XX) implementation.
From: Ozkan Sezer <sezeroz AT gmail DOT com>
To: Juan Manuel Guerrero <juan DOT guerrero AT gmx DOT de>
Cc: djgpp AT delorie DOT com
X-MIME-Autoconverted: from quoted-printable to 8bit by delorie.com id p8HCuZUV028554
Reply-To: djgpp AT delorie DOT com
Errors-To: nobody AT delorie DOT com
X-Mailing-List: djgpp AT delorie DOT com
X-Unsubscribes-To: listserv AT delorie DOT com

On Sat, Sep 17, 2011 at 2:56 PM, Juan Manuel Guerrero
<juan DOT guerrero AT gmx DOT de> wrote:
> Here is a patch
>  - to set always the CF flag before calling a 0x71XX function
>  - to check that AX does not contain 0x7100 after return signaling
>    that the driver supports the called function.
>  - to react if the driver does not support the function.
> In almost all cases I followed Eli Zaretskii's suggestions.
>
> I have tested it on:
>  MSDOS 6.22 with and without DOSLFN 0.40c/e
>  FreedOS 1.0 with and without DOSLFN 0.40c
>  Win 98SE (dos box/prompt)
>  MSDOS 7.0  with and without DOSLFN 0.40c/e
>  WinXP Prof SP3 (dos box/prompt)
> I have not experienced any difficulties.
> Unfortunately I have not the time to check other LFN drivers but I assume
> that if the changes work for one driver it work for all drivers.
> The procedure is always the same: set CF before calling, check that AX != 0x7100
> and react if the function is not supported.
>
> As usual suggestions, objections, comments are welcome.
>
>
> Regards,
> Juan M. Guerrero
>


Tested this _very_ briefly on IBM PC-DOS 7 + DOSLFN 0.40e
(from http://adoxa.110mb.com/doslfn/) by running hexen2 for dos,
no problems so far with or without doslfn loaded in memory.
FWIW, though, I have to note that all disk access was in 8.3 style.

<rant>
With doslfn loaded, the hard disk scratching was unbearable to
hear. Living with conventional dos is a bliss..
</rant>

--
O.S.


>
> 2011-09-16  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.
>
>
> 2011-09-15  Juan Manuel Guerrero  <juan DOT guerrero AT gmx DOT de>
>
>        * 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/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/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/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/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.
>
>
> 2011-09-13  Juan Manuel Guerrero  <juan DOT guerrero AT gmx DOT de>
>
>        * 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/posix/sys/stat/filelen.c:  Check that 0x71A6 call is
>        supported by checking that AX does not contain 0x7100.  If not
>        supported fall back on 0x42NN.  Set CF before calling 0x71A6
>        function.
>
>        * src/libc/posix/sys/stat/lfilelen.c:  Check that 0x71A6 call is
>        supported by checking that AX does not contain 0x7100.  If not
>        supported fall back on 0x42NN.  Set CF before calling 0x71A6
>        function.
>
>        * src/libc/posix/sys/stat/fchmod.c: If 0x71A6 function not supported
>        fail.  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.
>
>
> 2011-09-12  Juan Manuel Guerrero  <juan DOT guerrero AT gmx DOT de>
>
>        * 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/dos/io/_chmod.c: If 0x7143 function not supported fail.
>        Set CF before calling 0x7143 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.
>
>
> 2011-09-09  Juan Manuel Guerrero  <juan DOT guerrero AT gmx DOT de>
>
>        * 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.
>
>        * 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.
>
>
>
>
>
>
> diff -aprNU5 djgpp.orig/src/libc/ansi/stdio/_rename.c djgpp/src/libc/ansi/stdio/_rename.c
> --- djgpp.orig/src/libc/ansi/stdio/_rename.c    2001-03-18 16:52:40 +0000
> +++ djgpp/src/libc/ansi/stdio/_rename.c 2011-09-16 20:06: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,19 @@ 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.  */
>       errno = __doserr_to_errno(r.x.ax);
>       return -1;
>     }
>
>     /* Now create a file with the original name.  This will
> @@ -109,14 +113,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,12 +140,15 @@ 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)
>     {
> +      /*  Never assume that the complete LFN API is implemented,
> +          so check that AX != 0x7100.  E.G.: MSDOS 6.22 and DOSLFN 0.40.  */
> +
>       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.  */
>              || r.x.ax == 0xb7))
> diff -aprNU5 djgpp.orig/src/libc/ansi/stdio/remove.c djgpp/src/libc/ansi/stdio/remove.c
> --- djgpp.orig/src/libc/ansi/stdio/remove.c     2006-01-18 16:13:10 +0000
> +++ djgpp/src/libc/ansi/stdio/remove.c  2011-09-16 20:06:46 +0000
> @@ -1,5 +1,6 @@
> +/* Copyright (C) 2011 DJ Delorie, see COPYING.DJ for details */
>  /* Copyright (C) 2003 DJ Delorie, see COPYING.DJ for details */
>  /* Copyright (C) 2002 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 */
> @@ -57,28 +58,33 @@ remove(const char *fn)
>   /* Now delete it.  Note, _chmod leaves dir name in transfer buffer. */
>   if (directory_p)
>     r.h.ah = 0x3a;             /* DOS Remove Directory function */
>   else
>     r.h.ah = 0x41;             /* DOS Remove File function */
> -  if(use_lfn) {
> +  if (use_lfn)
> +  {
> +    r.x.flags |= 1;            /* Always set CF before calling a 0x71NN function. */
>     r.h.al = r.h.ah;
>     r.h.ah = 0x71;
>     r.x.si = 0;                        /* No Wildcards */
>   }
>   r.x.cx = 0;                  /* Fix for ROM-DOS */
>   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.  */
> +
>     /* We failed.  Leave the things as we've found them.  */
>     int e = __doserr_to_errno(r.x.ax);
>
>     /* We know the file exists, so ENOENT at this point means a bug.
>        Since write-protected floppies are the most probable cause,
>        return EACCES instead.  */
> -    if(e == ENOENT)
> +    if (e == ENOENT)
>       e = EACCES;
>
>     _chmod(real_name, 1, attr & 0xffe7);
>     errno = e;
>     return -1;
> diff -aprNU5 djgpp.orig/src/libc/dos/dir/findfirs.c djgpp/src/libc/dos/dir/findfirs.c
> --- djgpp.orig/src/libc/dos/dir/findfirs.c      2008-04-09 04:13:38 +0000
> +++ djgpp/src/libc/dos/dir/findfirs.c   2011-09-16 20:06:46 +0000
> @@ -1,5 +1,6 @@
> +/* Copyright (C) 2011 DJ Delorie, see COPYING.DJ for details */
>  /* Copyright (C) 2002 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>
> @@ -30,11 +31,12 @@ findfirst(const char *pathname, struct f
>   attrib &= 0xff;
>
>   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
> @@ -42,19 +44,24 @@ findfirst(const char *pathname, struct f
>       #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.  */
> +
>       struct ffblklfn ffblk32;
>       unsigned long t1;
>       /* Recover results */
>       dosmemget(__tb+pathlen, sizeof(struct ffblklfn), &ffblk32);
>
> @@ -67,11 +74,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;
>       }
> @@ -85,11 +94,13 @@ findfirst(const char *pathname, struct f
>       ffblk->lfn_atime = t1;
>       ffblk->lfn_adate = t1 >> 16;
>
>       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. */
> @@ -102,13 +113,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.orig/src/libc/dos/dir/findnext.c djgpp/src/libc/dos/dir/findnext.c
> --- djgpp.orig/src/libc/dos/dir/findnext.c      2008-04-09 04:13:38 +0000
> +++ djgpp/src/libc/dos/dir/findnext.c   2011-09-16 20:06:46 +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,28 @@ 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.  */
> +
>       unsigned long t1;
>       struct ffblklfn ffblk32;
>       /* Recover results */
>       dosmemget(__tb, sizeof(struct ffblklfn), &ffblk32);
>
> @@ -69,13 +74,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;
> @@ -95,11 +101,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.orig/src/libc/dos/dos/truename.c djgpp/src/libc/dos/dos/truename.c
> --- djgpp.orig/src/libc/dos/dos/truename.c      2003-08-09 12:32:10 +0000
> +++ djgpp/src/libc/dos/dos/truename.c   2011-09-16 20:06:46 +0000
> @@ -1,5 +1,6 @@
> +/* Copyright (C) 2011 DJ Delorie, see COPYING.DJ for details */
>  /* Copyright (C) 2003 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
> @@ -103,57 +104,72 @@ _truename_internal(const char *file, cha
>       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;
>     /* Get Long Path Name (if there is one) and we want it. */
>     regs.x.cx = try_lfn ? 2 : 0;
> -  } 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);
>
>   /* 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)
> +  {
> +    if (use_lfn)
>     {
> -      if (use_lfn && first_time)
> -       {
> -         /* If the file doesn't exist, 217160/CX=2 fails.  Try again
> -            with CX=0, so that this time it won't validate the path.  */
> -         first_time = 0;
> -         regs.x.ax = 0x7160;
> -         regs.x.cx = 0;
> -         goto lfn_retry;
> -       }
> -      errno = __doserr_to_errno(regs.x.ax);
> -      return (char *)0;
> +      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;
> +      }
> +      else if (first_time)
> +      {
> +        /* If the file doesn't exist, 217160/CX=2 fails.  Try again
> +           with CX=0, so that this time it won't validate the path.  */
> +        first_time = 0;
> +        regs.x.ax = 0x7160;
> +        regs.x.cx = 0;
> +        goto lfn_retry;
> +      }
>     }
> +    errno = __doserr_to_errno(regs.x.ax);
> +    return (char *)0;
> +  }
>   else
> +  {
> +    if (buf == (char *)0)
> +      buf = (char *)malloc(strlen(true_name) + 1);
> +    if (buf == (char *)0)
> +      errno = ENOMEM;
> +    else
>     {
> -      if (buf == (char *)0)
> -        buf = (char *)malloc(strlen(true_name)+1);
> -      if (buf == (char *)0)
> -        errno = ENOMEM;
> -      else
> -        {
> -          errno = e;
> -          strcpy(buf, true_name);
> -        }
> -      return buf;
> +      errno = e;
> +      strcpy(buf, true_name);
>     }
> +    return buf;
> +  }
>  }
>
>  char *
>  _truename(const char *file, char *buf)
>  {
> diff -aprNU5 djgpp.orig/src/libc/dos/io/_chmod.c djgpp/src/libc/dos/io/_chmod.c
> --- djgpp.orig/src/libc/dos/io/_chmod.c 1996-08-31 22:09:32 +0000
> +++ djgpp/src/libc/dos/io/_chmod.c      2011-09-16 20:06:46 +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,22 +12,25 @@
>  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)
>   {
>     errno = __doserr_to_errno(r.x.ax);
>     return -1;
>   }
>
> diff -aprNU5 djgpp.orig/src/libc/dos/io/_creat.c djgpp/src/libc/dos/io/_creat.c
> --- djgpp.orig/src/libc/dos/io/_creat.c 2002-06-14 14:25:20 +0000
> +++ djgpp/src/libc/dos/io/_creat.c      2011-09-16 20:06:46 +0000
> @@ -1,5 +1,6 @@
> +/* Copyright (C) 2011 DJ Delorie, see COPYING.DJ for details */
>  /* Copyright (C) 2002 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>
> @@ -29,45 +30,62 @@ _creat(const char* filename, int attrib)
>   }
>
>   if (__FSEXT_call_open_handlers_wrapper(__FSEXT_creat, &rv, filename, attrib))
>     return rv;
>
> -  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. */
>     /* The FAT32 bit should _not_ be set on Windows 2000, because
>        that bit fails function 716Ch on W2K.  The test below is
>        based on the assumption that W2K returns DOS version 5.  */
> -    if (7 <= _osmajor && _osmajor < 10) {
> +    if (7 <= _osmajor && _osmajor < 10)
>       r.x.bx |= 0x1000; /* 0x1000 is FAT32 extended size. */
> -    }
>     r.x.dx = 0x0012;           /* Create, truncate if exists */
>     r.x.si = __tb_offset;
> -  } else {
> -    if (7 <= _osmajor && _osmajor < 10) {
> +  }
> +  else
> +  {
> +    if (7 <= _osmajor && _osmajor < 10)
> +    {
>       r.x.ax = 0x6c00;
>       r.x.bx = 0x1002;           /* Open r/w with FAT32 extended size. */
>       /* FAT32 extended size flag doesn't help on WINDOZE 4.1 (98). It
>         seems it has a bug which only lets you create these big files
>         if LFN is enabled. */
>       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;
>   _put_path(filename);
>   __dpmi_int(0x21, &r);
> -  if(r.x.flags & 1)
> +  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.  */
> +      use_lfn = 0;
> +      r.h.ah = 0x3c;
> +      r.x.dx = __tb_offset;
> +      goto do_create;
> +    }
>     errno = __doserr_to_errno(r.x.ax);
>     return -1;
>   }
> -  if(use_lfn && _os_trueversion == 0x532) {
> +  if (use_lfn && _os_trueversion == 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 */
> diff -aprNU5 djgpp.orig/src/libc/dos/io/_creat_n.c djgpp/src/libc/dos/io/_creat_n.c
> --- djgpp.orig/src/libc/dos/io/_creat_n.c       2002-06-14 14:25:26 +0000
> +++ djgpp/src/libc/dos/io/_creat_n.c    2011-09-16 20:06:46 +0000
> @@ -1,5 +1,6 @@
> +/* Copyright (C) 2011 DJ Delorie, see COPYING.DJ for details */
>  /* Copyright (C) 2002 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 <stdarg.h>
> @@ -34,16 +35,17 @@ _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)
>   {
>     if (7 <= _osmajor && _osmajor < 10)
>     {
>       r.x.bx |= 0x1000;        /* FAT32 extended size. */
>     }
> +    r.x.flags |= 1;            /* Always set CF before calling a 0x71NN function. */
>     r.x.ax = 0x716c;
>   }
>   else
>   {
>     if (7 <= _osmajor && _osmajor < 10)
> @@ -62,25 +64,38 @@ _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.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.  */
> +      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;
> +    }
>     errno = __doserr_to_errno(r.x.ax);
>     return -1;
>   }
> -  if(use_lfn && _os_trueversion == 0x532) {
> +  if (use_lfn && _os_trueversion == 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 */
> +    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);
>     }
>   }
>   __file_handle_set(r.x.ax, O_BINARY);
> diff -aprNU5 djgpp.orig/src/libc/dos/io/_open.c djgpp/src/libc/dos/io/_open.c
> --- djgpp.orig/src/libc/dos/io/_open.c  2002-06-14 14:25:34 +0000
> +++ djgpp/src/libc/dos/io/_open.c       2011-09-16 20:06:46 +0000
> @@ -1,5 +1,6 @@
> +/* Copyright (C) 2011 DJ Delorie, see COPYING.DJ for details */
>  /* Copyright (C) 2002 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>
> @@ -29,85 +30,108 @@ _open(const char* filename, int oflag)
>   }
>
>   if (__FSEXT_call_open_handlers_wrapper(__FSEXT_open, &rv, filename, oflag))
>     return rv;
>
> -  if(use_lfn && _os_trueversion == 0x532) {
> +  if (use_lfn && _os_trueversion == 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.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);
>     /* The FAT32 bit should _not_ be set on Windows 2000, because
>        that bit fails function 716Ch on W2K.  The test below is
>        based on the assumption that W2K returns DOS version 5.  */
> -    if (7 <= _osmajor && _osmajor < 10) {
> +    if (7 <= _osmajor && _osmajor < 10)
>       r.x.bx |= 0x1000; /* 0x1000 is FAT32 extended size. */
> -    }
>     r.x.dx = 1;                        /* Open existing file */
>     r.x.si = __tb_offset;
> -  } else {
> -    if (7 <= _osmajor && _osmajor < 10) {
> +  }
> +  else
> +  {
> +    if (7 <= _osmajor && _osmajor < 10)
> +    {
>       r.x.ax = 0x6c00;
>       r.x.bx = (oflag & 0xff) | 0x1000; /* 0x1000 is FAT32 extended size. */
>       /* FAT32 extended size flag doesn't help on WINDOZE 4.1 (98). It
>         seems it has a bug which only lets you create these big files
>         if LFN is enabled. */
>       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.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.  */
> +      use_lfn = 0;
> +      r.h.ah = 0x3d;
> +      r.h.al = oflag;
> +      r.x.dx = __tb_offset;
> +      goto do_open;
> +    }
>     errno = __doserr_to_errno(r.x.ax);
>     return -1;
>   }
>  do_hset:
>   __file_handle_set(r.x.ax, O_BINARY);
> diff -aprNU5 djgpp.orig/src/libc/dos/io/flushdc.c djgpp/src/libc/dos/io/flushdc.c
> --- djgpp.orig/src/libc/dos/io/flushdc.c        1996-09-19 23:38:56 +0000
> +++ djgpp/src/libc/dos/io/flushdc.c     2011-09-16 23:12:04 +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.orig/src/libc/dos/lfn/_use_lfn.c djgpp/src/libc/dos/lfn/_use_lfn.c
> --- djgpp.orig/src/libc/dos/lfn/_use_lfn.c      2007-12-11 07:27:38 +0000
> +++ djgpp/src/libc/dos/lfn/_use_lfn.c   2011-09-16 20:06: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) 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 */
> @@ -70,10 +71,11 @@ _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;
> diff -aprNU5 djgpp.orig/src/libc/dos/lfn/lfnshort.c djgpp/src/libc/dos/lfn/lfnshort.c
> --- djgpp.orig/src/libc/dos/lfn/lfnshort.c      1999-06-03 17:27:34 +0000
> +++ djgpp/src/libc/dos/lfn/lfnshort.c   2011-09-16 20:06:46 +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;
> diff -aprNU5 djgpp.orig/src/libc/dos/process/dosexec.c djgpp/src/libc/dos/process/dosexec.c
> --- djgpp.orig/src/libc/dos/process/dosexec.c   2005-01-31 08:14:46 +0000
> +++ djgpp/src/libc/dos/process/dosexec.c        2011-09-16 20:06:46 +0000
> @@ -1,5 +1,6 @@
> +/* Copyright (C) 2011 DJ Delorie, see COPYING.DJ for details */
>  /* Copyright (C) 2003 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 */
> @@ -208,19 +209,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)
> +  {
>     unsigned pgm_name_loc = tbuf_beg == __tb ? tbuf_ptr : __tb;
> +    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 = pgm_name_loc / 16;
>     r.x.si = r.x.di = pgm_name_loc & 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.  */
>       errno = __doserr_to_errno(r.x.ax);
>       return -1;
>     }
>   }
>   dosmemget(tbuf_beg == __tb ? tbuf_ptr : __tb, FILENAME_MAX, short_name);
> diff -aprNU5 djgpp.orig/src/libc/posix/dirent/opendir.c djgpp/src/libc/posix/dirent/opendir.c
> --- djgpp.orig/src/libc/posix/dirent/opendir.c  2008-12-08 17:48:50 +0000
> +++ djgpp/src/libc/posix/dirent/opendir.c       2011-09-16 20:06:46 +0000
> @@ -1,5 +1,6 @@
> +/* Copyright (C) 2011 DJ Delorie, see COPYING.DJ for details */
>  /* Copyright (C) 2008 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 */
> @@ -40,15 +41,18 @@
>  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.  */
>     errno = __doserr_to_errno(r.x.ax);
>   }
>  }
>
>  void
> diff -aprNU5 djgpp.orig/src/libc/posix/sys/stat/fchmod.c djgpp/src/libc/posix/sys/stat/fchmod.c
> --- djgpp.orig/src/libc/posix/sys/stat/fchmod.c 2003-03-08 00:41:16 +0000
> +++ djgpp/src/libc/posix/sys/stat/fchmod.c      2011-09-16 22:52:50 +0000
> @@ -1,5 +1,6 @@
> +/* Copyright (C) 2011 DJ Delorie, see COPYING.DJ for details */
>  /* Copyright (C) 2003 DJ Delorie, see COPYING.DJ for details */
>  #include <libc/stubs.h>
>  #include <string.h>
>  #include <unistd.h>
>  #include <sys/stat.h>
> @@ -18,19 +19,22 @@ static int
>  get_current_mode (const int fd)
>  {
>   __dpmi_regs r;
>   int         mode = 0; /* Fail by default */
>
> -  if (_USE_LFN) {
> +  if (_USE_LFN)
> +  {
> +    r.x.flags |= 1;  /* Always set CF before calling a 0x71NN function. */
>     r.x.ax = 0x71a6; /* File info by handle */
>     r.x.bx = fd;
>     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)
> +    {
>       int attr = _farpeekl(_dos_ds, __tb);
>
>       mode = S_IRUSR; /* Files are always readable. */
>       if ((attr & 1) == 0)
>        mode |= S_IWUSR;
> diff -aprNU5 djgpp.orig/src/libc/posix/sys/stat/filelen.c djgpp/src/libc/posix/sys/stat/filelen.c
> --- djgpp.orig/src/libc/posix/sys/stat/filelen.c        2011-09-04 21:16:44 +0000
> +++ djgpp/src/libc/posix/sys/stat/filelen.c     2011-09-16 20:06:46 +0000
> @@ -34,15 +34,15 @@ filelength(int fhandle)
>      combos work properly.  This assumes this routine is called from fstat()
>      before we get the magic number or other things that do both seeks and
>      reads. */
>   if (_USE_LFN && (fhandle != 0 || _os_trueversion != 0x532))
>   {
> +    regs.x.flags |= 1;  /* Always set CF before calling a 0x71NN function. */
>     regs.x.ax = 0x71A6;
>     regs.x.bx = fhandle;
>     regs.x.ds = __tb >> 4;
>     regs.x.dx = 0;
> -    regs.x.flags |= 1;
>     __dpmi_int(0x21, &regs);
>
>     /*  It is always necessary to test if LFN function
>         has been implemented because the assumption has
>         been proven false that a driver will set the CF
> @@ -50,11 +50,13 @@ filelength(int fhandle)
>         E.g.: all DOSLFN drivers do not implement
>         0x71A6 and DOSLFN 0.40e does not set CF
>         making MSDOS 6.22 fail.  If FreeDOS 1.0 is
>         used, the same LFN driver sets the CF.
>         If the ax register contains 0x7100 then the
> -        corresponding LFN function is not implemented.  */
> +        corresponding LFN function is not implemented.
> +        If the 0x71A6 function is not supported fall back
> +        on 0x42NN.  */
>     if ((regs.x.flags & 1) == 0 && regs.x.ax != 0x7100)
>     {
>       /* Offset 0x24 contains the low 32-bits of the file size.
>          Offset 0x20 contains the high 32-bits.  */
>       retval = _farpeekl(_dos_ds, __tb + 0x24);
> @@ -73,37 +75,37 @@ filelength(int fhandle)
>   regs.x.ax = 0x4201;      /* set pointer from current position */
>   regs.x.bx = fhandle;
>   regs.x.cx = regs.x.dx = 0; /* move 0 bytes (i.e., stay put) */
>   __dpmi_int(0x21, &regs);
>   if (regs.x.flags & 1)
> -    {
> -      errno = __doserr_to_errno(regs.x.ax);
> -      return -1L;
> -    }
> +  {
> +    errno = __doserr_to_errno(regs.x.ax);
> +    return -1L;
> +  }
>   fpos_high = regs.x.dx;   /* save current position */
>   fpos_low  = regs.x.ax;
>
>   regs.x.cx = regs.x.dx = 0;
>   regs.x.ax = 0x4202;      /* set pointer 0 bytes from the end of file */
>   __dpmi_int(0x21, &regs);
>   if (regs.x.flags & 1)
> -    {
> -      errno = __doserr_to_errno(regs.x.ax);
> -      return -1L;
> -    }
> +  {
> +    errno = __doserr_to_errno(regs.x.ax);
> +    return -1L;
> +  }
>
>   /* The absolute byte offset returned in DX:AX is the file size. */
>   retval = ( (long)regs.x.dx << 16 ) + regs.x.ax;
>
>   /* Leave things as we have found them. */
>   regs.x.ax = 0x4200;      /* set pointer from the beginning of file */
>   regs.x.cx = fpos_high;
>   regs.x.dx = fpos_low;
>   __dpmi_int(0x21, &regs);
>   if (regs.x.flags & 1)
> -    {
> -      errno = __doserr_to_errno(regs.x.ax);
> -      return -1L;
> -    }
> +  {
> +    errno = __doserr_to_errno(regs.x.ax);
> +    return -1L;
> +  }
>
>   return retval;
>  }
> diff -aprNU5 djgpp.orig/src/libc/posix/sys/stat/fixpath.c djgpp/src/libc/posix/sys/stat/fixpath.c
> --- djgpp.orig/src/libc/posix/sys/stat/fixpath.c        2008-12-06 13:53:42 +0000
> +++ djgpp/src/libc/posix/sys/stat/fixpath.c     2011-09-16 22:17:32 +0000
> @@ -1,5 +1,6 @@
> +/* Copyright (C) 2011 DJ Delorie, see COPYING.DJ for details */
>  /* Copyright (C) 2008 DJ Delorie, see COPYING.DJ for details */
>  /* Copyright (C) 2002 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 */
> @@ -32,14 +33,15 @@ __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);
>
> @@ -47,10 +49,19 @@ __get_current_directory(char *out, int d
>   {
>  #ifdef TEST
>     errno = __doserr_to_errno(r.x.ax);
>     perror("Get dir failed in fixpath");
>  #endif
> +    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.  */
> +      use_lfn = 0;
> +      r.h.ah = 0x47;
> +      goto do_get_current_directory;
> +    }
>     *out++ = '.';      /* Return relative path (lfn=n on Win9x) */
>     return out;
>   }
>   else
>   {
> @@ -347,27 +358,29 @@ int main (int argc, char *argv[])
>   char fixed[FILENAME_MAX];
>   __dpmi_regs r;
>
>   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.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
>       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;
> diff -aprNU5 djgpp.orig/src/libc/posix/sys/stat/fstat.c djgpp/src/libc/posix/sys/stat/fstat.c
> --- djgpp.orig/src/libc/posix/sys/stat/fstat.c  2008-03-26 23:37:40 +0000
> +++ djgpp/src/libc/posix/sys/stat/fstat.c       2011-09-16 20:06:46 +0000
> @@ -819,51 +819,56 @@ fstat_assist(int fhandle, struct stat *s
>                = _invent_inode(filename, dos_ftime, trusted_fsize);
>             }
>
>           if (trusted_fsize == 510)
>           {
> -             int old_errno = errno;
> -             char buf[2];
> -             int bytes_read = __internal_readlink(NULL, fhandle, buf, 1);
> -             if (bytes_read != -1)
> -             {
> -                stat_buf->st_mode = S_IFLNK;
> -                is_link = 1;
> -             }
> -             else
> -                errno = old_errno;
> +            int old_errno = errno;
> +            char buf[2];
> +            int bytes_read = __internal_readlink(NULL, fhandle, buf, 1);
> +            if (bytes_read != -1)
> +            {
> +              stat_buf->st_mode = S_IFLNK;
> +              is_link = 1;
> +            }
> +            else
> +              errno = old_errno;
>           }
>           if (!is_link)
>           {
> -              /* Return the minimum access bits every file has under DOS. */
> -              stat_buf->st_mode |= (S_IFREG | READ_ACCESS);
> -              if (_djstat_flags & _STAT_ACCESS)
> +            /* Return the minimum access bits every file has under DOS. */
> +            stat_buf->st_mode |= (S_IFREG | READ_ACCESS);
> +            if (_djstat_flags & _STAT_ACCESS)
>                 _djstat_fail_bits |= _STFAIL_WRITEBIT;
> -
> -             /* If we are runing on Windows 9X, NT 4.0 with LFN or 2000 or XP
> -                with LFN is enabled, try harder. Note that we deliberately do
> -                NOT use this call when LFN is disabled, even if we are on
> -                Windows, because then we open the file with function 3Ch, and
> -                such handles aren't supported by 71A6h call we use here.  */
> -             if  (_USE_LFN)
> -                {
> -                  __dpmi_regs r;
> -
> -                  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
> -                     && (_farpeekl(_dos_ds, __tb) & 0x07) == 0)
> -                   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 &&
> +
> +            /* If we are runing on Windows 9X, NT 4.0 with LFN or 2000 or XP
> +               with LFN is enabled, try harder. Note that we deliberately do
> +               NOT use this call when LFN is disabled, even if we are on
> +               Windows, because then we open the file with function 3Ch, and
> +               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 && 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))
> -                stat_buf->st_mode |= EXEC_ACCESS;
> +              stat_buf->st_mode |= EXEC_ACCESS;
>           }
>           /* Lower 6 bits of IOCTL return value give the device number. */
>           stat_buf->st_dev = dev_info & 0x3f;
>  #ifdef  HAVE_ST_RDEV
>           stat_buf->st_rdev = dev_info & 0x3f;
> @@ -877,11 +882,11 @@ fstat_assist(int fhandle, struct stat *s
>           stat_buf->st_size  = trusted_fsize;
>           stat_buf->st_atime = stat_buf->st_ctime = stat_buf->st_mtime =
>             _file_time_stamp(dos_ftime);
>
>          /* Additional time info for LFN platforms.  */
> -         set_fstat_times (fhandle, stat_buf);
> +         set_fstat_times(fhandle, stat_buf);
>         }
>       return 0;
>     }
>
>   /* Don't have even values from conventional DOS calls.
> diff -aprNU5 djgpp.orig/src/libc/posix/sys/stat/lfilelen.c djgpp/src/libc/posix/sys/stat/lfilelen.c
> --- djgpp.orig/src/libc/posix/sys/stat/lfilelen.c       2011-09-04 21:16:44 +0000
> +++ djgpp/src/libc/posix/sys/stat/lfilelen.c    2011-09-16 20:06:46 +0000
> @@ -28,15 +28,15 @@ lfilelength(int fhandle)
>
>   /* DOS 7 provides a way to get the file size directly.
>      Prefer it when available.  */
>   if (_USE_LFN)
>   {
> +    regs.x.flags |= 1;  /* Always set CF before calling a 0x71NN function. */
>     regs.x.ax = 0x71A6;
>     regs.x.bx = fhandle;
>     regs.x.ds = __tb >> 4;
>     regs.x.dx = 0;
> -    regs.x.flags |= 1;
>     __dpmi_int (0x21, &regs);
>
>     /*  It is always necessary to test if LFN function
>         has been implemented because the assumption has
>         been proven false that a driver will set the CF
> @@ -44,11 +44,13 @@ lfilelength(int fhandle)
>         E.g.: all DOSLFN drivers do not implement
>         0x71A6 and DOSLFN 0.40e does not set CF
>         making MSDOS 6.22 fail.  If FreeDOS 1.0 is
>         used, the same LFN driver sets the CF.
>         If the ax register contains 0x7100 then the
> -        corresponding LFN function is not implemented.  */
> +        corresponding LFN function is not implemented.
> +        If the 0x71A6 function is not supported fall back
> +        on 0x42NN.  */
>     if ((regs.x.flags & 1) == 0 && regs.x.ax != 0x7100)
>     {
>       /* Offset 0x24 contains the low 32-bits of the file size.
>          Offset 0x20 contains the high 32-bits.  */
>       long retval_l = _farpeekl (_dos_ds, __tb + 0x24);
> diff -aprNU5 djgpp.orig/src/libc/posix/sys/stat/mkdir.c djgpp/src/libc/posix/sys/stat/mkdir.c
> --- djgpp.orig/src/libc/posix/sys/stat/mkdir.c  2001-03-18 16:52:40 +0000
> +++ djgpp/src/libc/posix/sys/stat/mkdir.c       2011-09-16 20:06: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) 1996 DJ Delorie, see COPYING.DJ for details */
>  /* Copyright (C) 1995 DJ Delorie, see COPYING.DJ for details */
> @@ -27,12 +28,15 @@ mkdir(const char *mydirname, mode_t mode
>   if (!__solve_symlinks(mydirname, dir_name))
>      return -1;
>
>   _put_path(dir_name);
>
> -  if(use_lfn)
> +  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 */
> @@ -46,26 +50,38 @@ 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)
>   {
> -    int save_errno;
> -    save_errno = errno = __doserr_to_errno(r.x.ax);
> -    if (errno == EACCES)
> +    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.  */
> +      r.h.ah = 0x39;
> +      goto do_mkdir;
> +    }
> +    else
>     {
> -      /* see if the directory existed, in which case
> -        we should return EEXIST - DJ */
> -      if (access(mydirname, D_OK) == 0)
> -       errno = EEXIST;
> -      else
> -       errno = save_errno;
> +      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 */
> +        if (access(mydirname, D_OK) == 0)
> +          errno = EEXIST;
> +        else
> +          errno = save_errno;
> +      }
>     }
>     return -1;
>   }
>
>   /* mkdir is stub'd, and we don't want to stub chmod also.  */
> diff -aprNU5 djgpp.orig/src/libc/posix/unistd/chdir.c djgpp/src/libc/posix/unistd/chdir.c
> --- djgpp.orig/src/libc/posix/unistd/chdir.c    2007-12-10 20:16:00 +0000
> +++ djgpp/src/libc/posix/unistd/chdir.c 2011-09-16 20:06: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) 1996 DJ Delorie, see COPYING.DJ for details */
>  /* Copyright (C) 1995 DJ Delorie, see COPYING.DJ for details */
> @@ -50,19 +51,32 @@ __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.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.  */
> +        r.h.ah = 0x3b;
> +        goto do_chdir;
> +      }
> +
>       errno = __doserr_to_errno(r.x.ax);
>       return -1;
>     }
>   }
>
> diff -aprNU5 djgpp.orig/src/libc/posix/unistd/getcwd.c djgpp/src/libc/posix/unistd/getcwd.c
> --- djgpp.orig/src/libc/posix/unistd/getcwd.c   2003-05-10 15:31:12 +0000
> +++ djgpp/src/libc/posix/unistd/getcwd.c        2011-09-16 20:06:46 +0000
> @@ -1,5 +1,6 @@
> +/* Copyright (C) 2011 DJ Delorie, see COPYING.DJ for details */
>  /* Copyright (C) 2003 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>
> @@ -45,22 +46,35 @@ __getcwd(char *buf, size_t size)
>   /* make sure we don't overrun the TB */
>   if (size > __tb_size)
>     size = __tb_size;
>
>   /* 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.  */
> +      use_lfn = 0;
> +      r.h.ah = 0x47;
> +      goto do_getcwd;
> +    }
>     errno = __doserr_to_errno(r.x.ax);
>     return 0;
>   }
>
>   /* path is ASCIIZ.  Scan it, filling in buf, watching for
> diff -aprNU5 djgpp.orig/src/libc/posix/unistd/rmdir.c djgpp/src/libc/posix/unistd/rmdir.c
> --- djgpp.orig/src/libc/posix/unistd/rmdir.c    2000-08-25 11:40:48 +0000
> +++ djgpp/src/libc/posix/unistd/rmdir.c 2011-09-16 20:06:46 +0000
> @@ -1,5 +1,6 @@
> +/* Copyright (C) 2011 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 */
>  #include <libc/stubs.h>
> @@ -20,20 +21,25 @@ rmdir(const char *mydirname)
>
>   if (!__solve_dir_symlinks(mydirname, real_dir))
>     return -1;
>
>   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(real_dir);
>   __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.  */
>     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