Mail Archives: djgpp-workers/2005/05/15/04:42:42
X-Authentication-Warning: | delorie.com: mail set sender to djgpp-workers-bounces using -f
|
From: | <ams AT ludd DOT ltu DOT se>
|
Message-Id: | <200505140100.j4E10PQY004042@speedy.ludd.ltu.se>
|
Subject: | Re: DJGPP v2.04 Bugs - suggested patch
|
To: | DJGPP-WORKERS <djgpp-workers AT delorie DOT com>
|
Date: | Sat, 14 May 2005 03:00:25 +0200 (CEST)
|
X-Mailer: | ELM [version 2.4ME+ PL78 (25)]
|
MIME-Version: | 1.0
|
X-ltu-MailScanner-Information: | Please contact the ISP for more information
|
X-ltu-MailScanner: | Found to be clean
|
X-MailScanner-From: | ams AT ludd DOT ltu DOT se
|
Reply-To: | djgpp-workers AT delorie DOT com
|
According to Charles Sandmann:
> > I've de-spaghetti-fied it and if you tell me exactly under which
> > conditions it should retry, I'll add that and post a patch.
> >
> > Most optimal would be the if statement, something like:
> > /* Carry from INT 0x21,AX=0x716c set. */
> > if( r.x.ax == X && some other condition )
>
> I got a chance today to code for the first time in a long time. Attached
> is a fix that seems to work.
I prefer this. Much more clear. Here I understand what's
happening. But generates bigger code, ~150 bytes. As the patch seems
to bigger and much less readable I've included the source with the
headers removed.
Right,
MartinS
_open.c:
...
int
_open(const char* filename, int oflag)
{
__dpmi_regs r;
int rv;
int use_lfn = _USE_LFN;
if (filename == 0)
{
errno = EINVAL;
return -1;
}
if (__FSEXT_call_open_handlers_wrapper(__FSEXT_open, &rv, filename, oflag))
return rv;
if(use_lfn) {
if( _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.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 destinati\
on */
__dpmi_int(0x21, &r);
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;
r.x.cx = 0;
__dpmi_int(0x21, &r);
if(r.x.flags & 1) {
errno = __doserr_to_errno(r.x.ax);
return -1;
}
} 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 */
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! */
__file_handle_set(r.x.ax, O_BINARY);
return r.x.ax;
}
/* 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. */
}
}
}
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) {
r.x.bx |= 0x1000; /* 0x1000 is FAT32 extended size. */
}
r.x.dx = 1; /* Open existing file */
r.x.si = __tb_offset;
r.x.ds = __tb_segment;
_put_path(filename);
r.x.cx = 0;
__dpmi_int(0x21, &r);
if (r.x.flags & 1) {
if (r.x.ax == 80) {
/* Need to retry because XP file servers fails with error 80. */
r.h.ah = 0x3d;
r.h.al = oflag;
r.x.dx = __tb_offset;
r.x.ds = __tb_segment;
_put_path(filename);
r.x.cx = 0;
__dpmi_int(0x21, &r);
if (!(r.x.flags & 1)) {
__file_handle_set(r.x.ax, O_BINARY);
return r.x.ax;
}
/* Fall through. */
}
errno = __doserr_to_errno(r.x.ax);
return -1;
}
__file_handle_set(r.x.ax, O_BINARY);
return r.x.ax;
} 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 {
r.h.ah = 0x3d;
r.h.al = oflag;
r.x.dx = __tb_offset;
}
r.x.ds = __tb_segment;
_put_path(filename);
r.x.cx = 0;
__dpmi_int(0x21, &r);
if(r.x.flags & 1) {
errno = __doserr_to_errno(r.x.ax);
return -1;
}
__file_handle_set(r.x.ax, O_BINARY);
return r.x.ax;
}
}
- Raw text -