Mail Archives: djgpp/2011/09/17/08:56:42
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, ®s);
>
> /* 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, ®s);
>
> /* 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, ®s);
> 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, ®s);
> 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, ®s);
> 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, ®s);
>
> /* 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 -