Mail Archives: djgpp-workers/2011/09/28/16:40:16
X-Authentication-Warning: | delorie.com: mail set sender to djgpp-workers-bounces using -f
|
X-Recipient: | djgpp-workers AT delorie DOT com
|
X-Authenticated: | #27081556
|
X-Provags-ID: | V01U2FsdGVkX19X+m0wh8tXMp1mlFG8rxSzYl0nE/CNElAOiqYeZx
|
| iVyR50RZ3jkUEN
|
From: | Juan Manuel Guerrero <juan DOT guerrero AT gmx DOT de>
|
To: | djgpp-workers AT delorie DOT com
|
Subject: | [Patch] Issues concerning the INT 21 Windows95 - LONG FILENAME FUNCTIONS (0x71XX) implementation.
|
Date: | Wed, 28 Sep 2011 22:35:01 +0200
|
User-Agent: | KMail/1.9.10
|
MIME-Version: | 1.0
|
Message-Id: | <201109282235.01944.juan.guerrero@gmx.de>
|
X-Y-GMX-Trusted: | 0
|
Reply-To: | djgpp-workers AT delorie DOT com
|
This is the last version of the patch to presented by me to fix the pending
issues concerning the use of 0x7XX functions from the LFN API of windows.
All reported bugs have been fixed. Where appropiate the CF is set by ORing
the register value, else it is simply set to 1. This patch only fixes the 2.04
version of djdev. It has been compiled and tested with gcc 4.6.1 and gcc 3.4.4.
There is no 2.03 support.
For 2.03 support a mayor effort will be required. See the thread:
<http://www.delorie.com/archives/browse.cgi?p=djgpp-workers/2011/09/17/11:39:42>
and others. This effort could only be justified if new djdev203[bs].zip files
would be uploaded. I do not think that any average djgpp user will check out
the djdev203 branch from the repository and build his one fixed libc. So DJ
must decide if this is worth to be done.
Concerning this patch, I will wait a couple of days and if no one complains
I will commit it.
Regards,
Juan M. Guerrero
2011-09-27 Juan Manuel Guerrero <juan DOT guerrero AT gmx DOT de>
* src/docs/kb/wc204.txi: Added info about the functions that have
been changed.
* src/libc/dos/io/flushdc.c: Check that 0x710D call is supported
by checking that AX does not contain 0x7100. If not supported fall
back on BIOS DISK RESET. Set CF before calling 0x710D function.
* src/libcdos/process/dosexec.c: Check that 0x7160 call is supported
by checking that AX does not contain 0x7100. If not supported ignore.
Set CF before calling 0x7160 function.
* src/libc/posix/sys/stat/fixpath.c: Check that 0x7147 call is supported
by checking that AX does not contain 0x7100. If not supported fall
back on 0x47NN. Set CF before calling 0x713B function.
* src/libc/posix/dirent/opendir.c: Check that 0x71A1 call is supported
by checking that AX does not contain 0x7100. If not supported ignore.
Set CF before calling 0x71A1 function.
* src/libc/posix/unistd/getcwd.c: Check that 0x713B call is supported
by checking that AX does not contain 0x7100. If not supported fall
back on 0x3BNN. Set CF before calling 0x7147 function.
* src/libc/posix/sys/stat/mkdir.c: Check that 0x7139 call is supported
by checking that AX does not contain 0x7100. If not supported fall
back on 0x39NN. Set CF before calling 0x7139 function.
* src/libc/posix/unistd/rmdir.c: Check that 0x713A call is supported
by checking that AX does not contain 0x7100. If not supported fail.
Set CF before calling 0x713A function.
* src/libc/posix/unistd/chdir.c: Check that 0x713B call is supported
by checking that AX does not contain 0x7100. If not supported fall
back on 0x3BNN. Set CF before calling 0x713B function.
* src/libc/posix/sys/stat/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/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/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.
* src/libc/dos/io/_chmod.c: If 0x7143 function not supported fail.
Set CF before calling 0x7143 function.
* src/libc/dos/io/_creat_n.c: If 0x716C function not supported fall
back on SFN. Set CF before calling 0x716C function.
* src/libc/dos/io/_creat.c: If 0x716C function not supported fall
back on SFN. Set CF before calling 0x716C function.
* src/libc/ansi/stdio/remove.c: Check that 0x713A and 0x7141 calls are
supported by checking that AX does not contain 0x7100. If not supported
fail. Set CF before calling 0x71NN function.
* src/libc/ansi/stdio/findfirs.c: Check that 0x714E call is supported
by checking that AX does not contain 0x7100. If not supported fail.
Set CF before calling 0x714E function.
* src/libc/ansi/stdio/findnext.c: Check that 0x714F call is supported
by checking that AX does not contain 0x7100. If not supported fail.
Set CF before calling 0x714F function.
* src/libc/dos/dos/truename.c: Check that 0x7160 call is supported
by checking that AX does not contain 0x7100. If not supported fall
back on 0x6000. Set CF before calling 0x7160 function.
* src/libc/dos/lfn/lfnshort.c: If 0x71a8 function not supported fall
back on SFN. Set CF before calling 0x71a8 function.
* src/libc/dos/lfn/_use_lfn.c: Set CF before calling 0x71a0 function.
* src/libc/ansi/stdio/_rename.c: Check that 0x71A6 call is supported
by checking that AX does not contain 0x7100. If not supported fail.
Set CF before calling 0x71A6 function.
diff -aprNU5 djgpp.orig/src/docs/kb/wc204.txi djgpp/src/docs/kb/wc204.txi
--- djgpp.orig/src/docs/kb/wc204.txi 2011-02-26 19:52:10 +0000
+++ djgpp/src/docs/kb/wc204.txi 2011-09-27 19:39:04 +0000
@@ -1198,5 +1198,36 @@ pointer to the caller.
@pindex djtar AT r{, and empty lines in the file to change filenames}
@code{djtar} now ignores empty lines in filename change files instead
of skipping the extraction of the file named in the line before the
empty line.
+
+@findex flushdc AT r{, LFN support on plain DOS with DOSLFN and other LFN drivers}
+@findex dosexec AT r{, LFN support on plain DOS with DOSLFN and other LFN drivers}
+@findex fixpath AT r{, LFN support on plain DOS with DOSLFN and other LFN drivers}
+@findex opendir AT r{, LFN support on plain DOS with DOSLFN and other LFN drivers}
+@findex getcwd AT r{, LFN support on plain DOS with DOSLFN and other LFN drivers}
+@findex mkdir AT r{, LFN support on plain DOS with DOSLFN and other LFN drivers}
+@findex rmdir AT r{, LFN support on plain DOS with DOSLFN and other LFN drivers}
+@findex chdir AT r{, LFN support on plain DOS with DOSLFN and other LFN drivers}
+@findex filelen AT r{, LFN support on plain DOS with DOSLFN and other LFN drivers}
+@findex lfilelen AT r{, LFN support on plain DOS with DOSLFN and other LFN drivers}
+@findex fstat AT r{, LFN support on plain DOS with DOSLFN and other LFN drivers}
+@findex fchmod AT r{, LFN support on plain DOS with DOSLFN and other LFN drivers}
+@findex _open AT r{, LFN support on plain DOS with DOSLFN and other LFN drivers}
+@findex _chmod AT r{, LFN support on plain DOS with DOSLFN and other LFN drivers}
+@findex _creat_n AT r{, LFN support on plain DOS with DOSLFN and other LFN drivers}
+@findex _creat AT r{, LFN support on plain DOS with DOSLFN and other LFN drivers}
+@findex remove AT r{, LFN support on plain DOS with DOSLFN and other LFN drivers}
+@findex findfirs AT r{, LFN support on plain DOS with DOSLFN and other LFN drivers}
+@findex findnext AT r{, LFN support on plain DOS with DOSLFN and other LFN drivers}
+@findex truename AT r{, LFN support on plain DOS with DOSLFN and other LFN drivers}
+@findex lfnshort AT r{, LFN support on plain DOS with DOSLFN and other LFN drivers}
+@findex _use_lfn AT r{, LFN support on plain DOS with DOSLFN and other LFN drivers}
+@findex _rename AT r{, LFN support on plain DOS with DOSLFN and other LFN drivers}
+All these functions now check that the used LFN driver supplies the required
+@code{0x71} function from the @code{Windows 95} long filename functions API
+by inspecting the content of the @code{AX} register after return from the
+API function call. Depending on the function type, the function will ignore,
+fail or fall back on the corresponding SFN API function if the LFN API function
+is not provided by the LFN driver used.
+
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-27 20:23:36 +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 */
@@ -18,12 +19,12 @@
#include <libc/dosio.h>
int _rename(const char *old, const char *new)
{
__dpmi_regs r;
- int olen = strlen(old) + 1;
int i;
+ int olen = strlen(old) + 1;
int use_lfn = _USE_LFN;
char tempfile[FILENAME_MAX], tempfile1[FILENAME_MAX];
const char *orig = old;
int lfn_fd = -1;
int identical_but_for_case = 0;
@@ -53,10 +54,11 @@ int _rename(const char *old, const char
}
else
return 0; /* no LFN; foo and Foo are *always* the same file */
}
+ r.x.flags = 1; /* Always set CF before calling a 0x71NN function. */
r.x.dx = __tb_offset;
r.x.di = __tb_offset + olen;
r.x.ds = r.x.es = __tb_segment;
if (use_lfn && !identical_but_for_case)
@@ -67,11 +69,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 */
@@ -92,12 +94,15 @@ int _rename(const char *old, const char
r.x.ax = 0x7156;
_put_path2(tempfile, olen);
_put_path(old);
__dpmi_int(0x21, &r);
- if (r.x.flags & 1)
+ if ((r.x.flags & 1) || (r.x.ax == 0x7100))
{
+ /* Never assume that the complete LFN API is implemented,
+ so check that AX != 0x7100. E.G.: MSDOS 6.22 and DOSLFN 0.40.
+ If not supported fail. */
errno = __doserr_to_errno(r.x.ax);
return -1;
}
/* Now create a file with the original name. This will
@@ -109,14 +114,17 @@ int _rename(const char *old, const char
olen = strlen(tempfile) + 1;
old = tempfile;
r.x.di = __tb_offset + olen;
}
- for (i=0; i<2; i++)
+ for (i = 0; i < 2; i++)
{
- if(use_lfn)
+ if (use_lfn)
+ {
+ r.x.flags |= 1; /* Always set CF before calling a 0x71NN function. */
r.x.ax = 0x7156;
+ }
#if 0
/* It seems that no version of DOS, including DOS 8, which is part
of Windows/ME, implements this function. Without LFN, this fails
_rename on Windows/ME. Disabled. */
else if ((_osmajor > 7 && _osmajor < 10) /* OS/2 returns v10 and above */
@@ -133,12 +141,16 @@ 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 not supported fail. */
+
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-27 20:23:36 +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 */
@@ -42,43 +43,49 @@ remove(const char *fn)
does not exist. If it doesn't, don't bother
doing anything else, return an error, and
set errno properly. */
if (attr == -1)
{
- errno = ENOENT;
- return(-1);
+ errno = ENOENT;
+ return(-1);
}
directory_p = attr & 0x10;
/* Now, make the file writable. We must reset Vol, Dir, Sys and Hidden bits
in addition to the Read-Only bit, or else 214301 will fail. */
_chmod(real_name, 1, attr & 0xffe0);
/* Now delete it. Note, _chmod leaves dir name in transfer buffer. */
+ r.x.flags = 1; /* Always set CF before calling a 0x71NN function. */
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.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.
+ If not supported fall back on SFN API 0x3A or 0x41. */
+
/* 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-27 20:23:36 +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,25 @@ 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.
+ If not supported fall back on SFN API 0x4E. */
+
struct ffblklfn ffblk32;
unsigned long t1;
/* Recover results */
dosmemget(__tb+pathlen, sizeof(struct ffblklfn), &ffblk32);
@@ -67,11 +75,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 +95,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 +114,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-27 20:23:36 +0000
@@ -1,5 +1,6 @@
+/* Copyright (C) 2011 DJ Delorie, see COPYING.DJ for details */
/* Copyright (C) 1996 DJ Delorie, see COPYING.DJ for details */
/* Copyright (C) 1995 DJ Delorie, see COPYING.DJ for details */
#include <libc/stubs.h>
#include <stdlib.h>
#include <string.h>
@@ -19,11 +20,11 @@ findnext(struct ffblk *ffblk)
{
errno = EACCES;
return -1;
}
- if(_USE_LFN)
+ if (_USE_LFN)
{
/* si = 1 indicates DOS style dates, 0 means Win32 type dates.
DOS style dates are broken in some Win95 betas, build for either.
Release works with DOS date, it's faster, so use it. */
#define USEDOSDATE 1
@@ -31,24 +32,29 @@ findnext(struct ffblk *ffblk)
#define _Win32_to_DOS (long)
#else
extern long _Win32_to_DOS(long long WinTime);
#endif
+ r.x.flags = 1; /* Always set CF before calling a 0x71NN function. */
r.x.ax = 0x714f;
r.x.bx = ffblk->lfn_handle;
- if(!r.x.bx)
+ if (!r.x.bx)
{
errno = ENMFILE;
return 1;
}
r.x.di = __tb_offset;
r.x.es = __tb_segment;
r.x.si = USEDOSDATE;
__dpmi_int(0x21, &r);
- if (!(r.x.flags & 1))
+ if (!(r.x.flags & 1) && (r.x.ax != 0x7100))
{
+ /* Never assume that the complete LFN API is implemented,
+ so check that AX != 0x7100. E.G.: MSDOS 6.22 and DOSLFN 0.40.
+ If not supported fall back on SFN API 0x4F. */
+
unsigned long t1;
struct ffblklfn ffblk32;
/* Recover results */
dosmemget(__tb, sizeof(struct ffblklfn), &ffblk32);
@@ -69,13 +75,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 +102,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-27 20:23:36 +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,26 +104,39 @@ _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);
+ if (regs.x.ax == 0x7100)
+ {
+ /* Never assume that the complete LFN API is implemented,
+ so check that AX != 0x7100. E.G.: MSDOS 6.22 and DOSLFN 0.40.
+ If not supported fall back on 0x6000. */
+ use_lfn = 0;
+ regs.x.ax = 0x6000;
+ goto lfn_retry;
+ }
+
/* Now get the result from lower memory. */
movedata(dos_mem_selector, __tb + MAX_TRUE_NAME,
our_mem_selector, (unsigned int)true_name, MAX_TRUE_NAME);
if (regs.x.flags & 1)
diff -aprNU5 djgpp.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-27 20:23:36 +0000
@@ -1,5 +1,6 @@
+/* Copyright (C) 2011 DJ Delorie, see COPYING.DJ for details */
/* Copyright (C) 1996 DJ Delorie, see COPYING.DJ for details */
/* Copyright (C) 1995 DJ Delorie, see COPYING.DJ for details */
#include <libc/stubs.h>
#include <io.h>
#include <errno.h>
@@ -11,23 +12,29 @@
int
_chmod(const char *filename, int func, ...)
{
__dpmi_regs r;
- if(_USE_LFN) {
+ if (_USE_LFN)
+ {
+ r.x.flags = 1; /* Always set CF before calling a 0x71NN function. */
r.x.ax = 0x7143;
r.h.bl = func; /* Get or Put */
- } else
+ }
+ else
r.x.ax = 0x4300 + func;
_put_path(filename);
if (func == 1)
r.x.cx = *(&func + 1); /* Value to set */
r.x.dx = __tb_offset;
r.x.ds = __tb_segment;
__dpmi_int(0x21, &r);
- if(r.x.flags & 1)
+ if ((r.x.flags & 1) || (r.x.ax == 0x7100))
{
+ /* Never assume that the complete LFN API is implemented,
+ so check that AX != 0x7100. E.G.: MSDOS 6.22 and DOSLFN 0.40.
+ If not supported fail. */
errno = __doserr_to_errno(r.x.ax);
return -1;
}
return r.x.cx;
diff -aprNU5 djgpp.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-27 20:23:36 +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,53 +30,74 @@ _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.ax == 0x7100)
+ {
+ /* Never assume that the complete LFN API is implemented,
+ so check that AX != 0x7100. E.G.: MSDOS 6.22 and DOSLFN 0.40.
+ If not supported fall back on SFN API 0x3C. */
+ use_lfn = 0;
+ r.h.ah = 0x3c;
+ r.x.dx = __tb_offset;
+ goto do_create;
+ }
+ else if (r.x.flags & 1)
{
errno = __doserr_to_errno(r.x.ax);
return -1;
}
- if(use_lfn && _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 */
- if(rv != -1) { /* Re-open failure, continue with LFN handle */
- dup2(rv, r.x.ax); /* Replace ax, put handle in first position (bugs) */
- _close(rv);
+ if (rv != -1)
+ {
+ dup2(rv, r.x.ax); /* Re-open failure, continue with LFN handle */
+ _close(rv); /* Replace ax, put handle in first position (bugs) */
}
}
__file_handle_set(r.x.ax, O_BINARY);
return r.x.ax;
}
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-27 20:23:36 +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>
@@ -30,20 +31,20 @@ _creatnew(const char* filename, int attr
if (__FSEXT_call_open_handlers_wrapper(__FSEXT_creat, &rv,
filename, attrib, flags))
return rv;
_put_path(filename);
- r.x.bx =
- 0x2002 | (flags & 0xfff0); /* r/w, no Int 24h, use caller-defined flags */
+ 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,27 +63,43 @@ _creatnew(const char* filename, int attr
r.x.bx = 0; /* lose support for fancy flags in DOS 3.x */
r.x.dx = __tb_offset;
r.x.si = 0;
}
}
+do_create:
r.x.cx = attrib & 0xffff;
r.x.ds = __tb_segment;
__dpmi_int(0x21, &r);
- if(r.x.flags & 1)
+
+ if (r.x.ax == 0x7100)
+ {
+ /* Never assume that the complete LFN API is implemented,
+ so check that AX != 0x7100. E.G.: MSDOS 6.22 and DOSLFN 0.40.
+ If not supported fall back on SFN API 0x5B. */
+ use_lfn = 0;
+ r.h.ah = 0x5b;
+ r.x.bx = 0; /* lose support for fancy flags in DOS 3.x */
+ r.x.dx = __tb_offset;
+ r.x.si = 0;
+ goto do_create;
+ }
+ else if (r.x.flags & 1)
{
errno = __doserr_to_errno(r.x.ax);
return -1;
}
- if(use_lfn && _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 */
- dup2(rv, r.x.ax); /* Close ax, put handle in first position (bugs) */
- _close(rv);
+ if (rv != -1)
+ {
+ dup2(rv, r.x.ax); /* Re-open failure, continue with LFN handle */
+ _close(rv); /* Close ax, put handle in first position (bugs) */
}
}
__file_handle_set(r.x.ax, O_BINARY);
return r.x.ax;
}
diff -aprNU5 djgpp.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-27 20:23:36 +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,11 +30,12 @@ _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. */
@@ -42,71 +44,93 @@ _open(const char* filename, int oflag)
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.ax == 0x7100)
+ {
+ /* Never assume that the complete LFN API is implemented,
+ so check that AX != 0x7100. E.G.: MSDOS 6.22 and DOSLFN 0.40.
+ If not supported fall back on SFN API 0x3D. */
+ use_lfn = 0;
+ r.h.ah = 0x3d;
+ r.h.al = oflag;
+ r.x.dx = __tb_offset;
+ goto do_open;
+ }
+ else if (r.x.flags & 1)
{
errno = __doserr_to_errno(r.x.ax);
return -1;
}
do_hset:
diff -aprNU5 djgpp.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-27 20:23:36 +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-27 20:23:36 +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,19 +71,20 @@ _get_volume_info (const char *path, int
_farpokeb(_dos_ds, tbuf_la++, ':');
_farpokeb(_dos_ds, tbuf_la++, '\\');
_farpokeb(_dos_ds, tbuf_la++, '\0');
}
+ r.x.flags = 1; /* Always set CF before calling a 0x71NN function. */
r.x.ax = 0x71a0; /* Get Volume Information function */
r.x.ds = tbuf_seg; /* DS:DX points to root directory name */
r.x.dx = 0;
r.x.es = tbuf_seg; /* ES:DI points to a buffer for filesys name */
r.x.di = (tbuf_la - __tb) & 0xffff;
r.x.cx = 32; /* max size of filesystem name (Interrupt List) */
__dpmi_int(0x21, &r);
- if ((r.x.flags & 1) == 0 && r.x.ax != 0x7100)
+ if (!(r.x.flags & 1) && (r.x.ax != 0x7100))
{
char *p = fsystype, c;
retval = r.x.bx;
if (maxfile)
diff -aprNU5 djgpp.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-27 20:23:36 +0000
@@ -1,5 +1,6 @@
+/* Copyright (C) 2011 DJ Delorie, see COPYING.DJ for details */
/* Copyright (C) 1999 DJ Delorie, see COPYING.DJ for details */
/* Copyright (C) 1998 DJ Delorie, see COPYING.DJ for details */
/* Copyright (C) 1997 DJ Delorie, see COPYING.DJ for details */
#include <libc/stubs.h>
#include <ctype.h>
@@ -19,10 +20,11 @@ char *
_lfn_gen_short_fname (const char *long_fname, char *short_fname)
{
__dpmi_regs r;
unsigned long tbuf = __tb;
+ r.x.flags = 1; /* Always set CF before calling a 0x71NN function. */
r.x.ax = 0x7100;
if (_USE_LFN)
{
dosmemput (long_fname, strlen (long_fname) + 1, tbuf);
r.x.ax = 0x71a8;
@@ -32,11 +34,11 @@ _lfn_gen_short_fname (const char *long_f
r.x.di = 260;
r.x.dx = 0x0011; /* DH=01 would be better, but it's buggy */
__dpmi_int (0x21, &r);
}
- if ((r.x.flags & 1) == 0 && r.x.ax != 0x7100)
+ if (!(r.x.flags & 1) && (r.x.ax != 0x7100))
{
char buf[13], *s = buf, *d = short_fname;
dosmemget (tbuf + 260, sizeof buf, buf);
diff -aprNU5 djgpp.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-27 20:23:36 +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,24 @@ 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.
+ If not supported fail. */
errno = __doserr_to_errno(r.x.ax);
return -1;
}
}
dosmemget(tbuf_beg == __tb ? tbuf_ptr : __tb, FILENAME_MAX, short_name);
diff -aprNU5 djgpp.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-27 20:23:36 +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,19 @@
void
_lfn_find_close(int handle)
{
__dpmi_regs r;
+ r.x.flags = 1; /* Always set CF before calling a 0x71NN function. */
r.x.bx = handle;
r.x.ax = 0x71a1;
__dpmi_int(0x21, &r);
- if (r.x.flags & 1)
+ if ((r.x.flags & 1) || (r.x.ax == 0x7100))
{
+ /* Never assume that the complete LFN API is implemented,
+ so check that AX != 0x7100. E.G.: MSDOS 6.22 and DOSLFN 0.40.
+ If not supported fail. */
errno = __doserr_to_errno(r.x.ax);
}
}
void
diff -aprNU5 djgpp.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-27 20:23:36 +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,25 @@ 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))
+ {
+ /* Never assume that the complete LFN API is implemented,
+ so check that AX != 0x7100. E.G.: MSDOS 6.22 and DOSLFN 0.40.
+ If not supported fail. */
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:35:58 +0000
+++ djgpp/src/libc/posix/sys/stat/filelen.c 2011-09-27 20:23:36 +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,12 +50,14 @@ 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. */
- if ((regs.x.flags & 1) == 0 && regs.x.ax != 0x7100)
+ corresponding LFN function is not implemented.
+ If the 0x71A6 function is not supported fall back
+ on 0x42NN. */
+ if (!(regs.x.flags & 1) && (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-27 19:39:04 +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,20 +33,30 @@ __get_current_directory(char *out, int d
__dpmi_regs r;
char tmpbuf[FILENAME_MAX];
memset(&r, 0, sizeof(r));
r.x.flags = 1; /* Set carry for safety */
- if(use_lfn)
+ if (use_lfn)
r.x.ax = 0x7147;
else
r.h.ah = 0x47;
+do_get_current_directory:
r.h.dl = drive_number + 1;
r.x.si = __tb_offset;
r.x.ds = __tb_segment;
__dpmi_int(0x21, &r);
- if (r.x.flags & 1)
+ if (r.x.ax == 0x7100)
+ {
+ /* Never assume that the complete LFN API is implemented,
+ so check that AX != 0x7100. E.G.: MSDOS 6.22 and DOSLFN 0.40.
+ If not supported fall back on SFN API 0x47. */
+ use_lfn = 0;
+ r.h.ah = 0x47;
+ goto do_get_current_directory;
+ }
+ else if (r.x.flags & 1)
{
#ifdef TEST
errno = __doserr_to_errno(r.x.ax);
perror("Get dir failed in fixpath");
#endif
@@ -345,41 +356,67 @@ _fixpath(const char *in, char *out)
int main (int argc, char *argv[])
{
char fixed[FILENAME_MAX];
__dpmi_regs r;
- if (argc > 2) {
+ if (argc > 2)
+ {
_put_path(argv[1]);
- if(_USE_LFN)
+ r.x.flags = 1; /* Set carry for safety */
+ if (_USE_LFN)
r.x.ax = 0x713b;
else
r.h.ah = 0x3b;
r.x.dx = __tb_offset;
r.x.ds = __tb_segment;
__dpmi_int(0x21, &r);
- if(r.x.flags & 1) {
+
+ if (r.x.ax == 0x7100)
+ {
+ /* Never assume that the complete LFN API is implemented,
+ so check that AX != 0x7100. E.G.: MSDOS 6.22 and DOSLFN 0.40. */
+ errno = __doserr_to_errno(r.x.ax);
+ sprintf(fixed, "Change dir to %s failed (lfn=%d). LFN driver does not support 0x713B", argv[1], _USE_LFN);
+ perror(fixed);
+ }
+ else if (r.x.flags & 1)
+ {
errno = __doserr_to_errno(r.x.ax);
sprintf(fixed, "Change dir to %s failed (lfn=%d)", argv[1], _USE_LFN);
perror(fixed);
- } else
+ }
+ else
printf("Set dir: %s\n", argv[1]);
argc--;
argv++;
}
+ r.x.flags = 1; /* Set carry for safety */
if(_USE_LFN)
r.x.ax = 0x7147;
else
r.h.ah = 0x47;
r.h.dl = 0;
r.x.si = __tb_offset;
r.x.ds = __tb_segment;
__dpmi_int(0x21, &r);
- if (r.x.flags & 1) {
+
+ if (r.x.ax == 0x7100)
+ {
+ /* Never assume that the complete LFN API is implemented,
+ so check that AX != 0x7100. E.G.: MSDOS 6.22 and DOSLFN 0.40. */
errno = __doserr_to_errno(r.x.ax);
+ printf("getcwd failed. LFN driver does not support 0x7147");
perror("getcwd failed");
- } else {
+ }
+ else if (r.x.flags & 1)
+ {
+ errno = __doserr_to_errno(r.x.ax);
+ perror("getcwd failed");
+ }
+ else
+ {
dosmemget(__tb, sizeof(fixed), fixed);
printf("Get dir[%d]: \\%s\n", strlen(fixed), fixed);
}
if (argc > 1)
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-27 20:23:36 +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) 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 */
@@ -819,51 +820,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) && (r.x.ax != 0x7100) &&
+ !(_farpeekl(_dos_ds, __tb) & 0x07))
+ {
+ /* 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 +883,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:36:00 +0000
+++ djgpp/src/libc/posix/sys/stat/lfilelen.c 2011-09-27 20:23:36 +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
@@ -45,11 +45,11 @@ lfilelength(int fhandle)
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. */
- if ((regs.x.flags & 1) == 0 && regs.x.ax != 0x7100)
+ if (!(regs.x.flags & 1) && (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);
long retval_h = _farpeekl (_dos_ds, __tb + 0x20);
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-27 20:23:36 +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,35 @@ mkdir(const char *mydirname, mode_t mode
r.h.cl = 0x39;
}
#endif
else
r.h.ah = 0x39;
+do_mkdir:
r.x.ds = __tb_segment;
r.x.dx = __tb_offset;
__dpmi_int(0x21, &r);
- if (r.x.flags & 1)
+ if (r.x.ax == 0x7100)
+ {
+ /* Never assume that the complete LFN API is implemented,
+ so check that AX != 0x7100. E.G.: MSDOS 6.22 and DOSLFN 0.40.
+ If not supported fall back on SFN API 0x39. */
+ r.h.ah = 0x39;
+ goto do_mkdir;
+ }
+ else if (r.x.flags & 1)
{
int save_errno;
save_errno = errno = __doserr_to_errno(r.x.ax);
if (errno == EACCES)
{
/* see if the directory existed, in which case
- we should return EEXIST - DJ */
+ we should return EEXIST - DJ */
if (access(mydirname, D_OK) == 0)
- errno = EEXIST;
+ errno = EEXIST;
else
- errno = save_errno;
+ errno = save_errno;
}
return -1;
}
/* mkdir is stub'd, and we don't want to stub chmod also. */
diff -aprNU5 djgpp.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-27 20:23:36 +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,18 +51,31 @@ __chdir (const char *mydirname)
__dpmi_int(0x21, &r);
}
if (drv_no == -1 || _farpeekb(_dos_ds, __tb + 2) != 0)
{
- if(_USE_LFN)
+ if (_USE_LFN)
+ {
+ r.x.flags = 1; /* Always set CF before calling a 0x71NN function. */
r.x.ax = 0x713b;
+ }
else
r.h.ah = 0x3b;
+do_chdir:
r.x.dx = __tb_offset;
r.x.ds = __tb_segment;
__dpmi_int(0x21, &r);
- if(r.x.flags & 1)
+
+ if (r.x.ax == 0x7100)
+ {
+ /* Never assume that the complete LFN API is implemented,
+ so check that AX != 0x7100. E.G.: MSDOS 6.22 and DOSLFN 0.40.
+ If not supported fall back on SFN API 0c3B. */
+ r.h.ah = 0x3b;
+ goto do_chdir;
+ }
+ else if (r.x.flags & 1)
{
errno = __doserr_to_errno(r.x.ax);
return -1;
}
}
diff -aprNU5 djgpp.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-27 20:23:36 +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 0x47. */
+ use_lfn = 0;
+ r.h.ah = 0x47;
+ goto do_getcwd;
+ }
+ else if (r.x.flags & 1)
{
+ /* current drive may be invalid (it happens) */
errno = __doserr_to_errno(r.x.ax);
return 0;
}
/* path is ASCIIZ. Scan it, filling in buf, watching for
diff -aprNU5 djgpp.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-27 20:23:36 +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,26 @@ 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.
+ If not supported fail. */
errno = __doserr_to_errno(r.x.ax);
return -1;
}
return 0;
}
- Raw text -