X-Authentication-Warning: delorie.com: mail set sender to djgpp-workers-bounces using -f From: Message-Id: <200505140100.j4E10PQY004042@speedy.ludd.ltu.se> Subject: Re: DJGPP v2.04 Bugs - suggested patch To: DJGPP-WORKERS Date: Sat, 14 May 2005 03:00:25 +0200 (CEST) X-Mailer: ELM [version 2.4ME+ PL78 (25)] MIME-Version: 1.0 Content-Transfer-Encoding: 7bit Content-Type: text/plain; charset=US-ASCII 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; } }