Date: Sun, 13 Dec 1998 10:01:18 +0200 (IST) From: Eli Zaretskii X-Sender: eliz AT is To: DJ Delorie cc: djgpp-workers AT delorie DOT com Subject: Re: djgpp 2.02 and the /dev/x/foo feature In-Reply-To: Message-ID: MIME-Version: 1.0 Content-Type: TEXT/PLAIN; charset=US-ASCII Reply-To: djgpp-workers AT delorie DOT com On Thu, 3 Dec 1998, I wrote: > I know about at least one problem which I didn't finish to work out: > the /dev/x/foo feature doesn't work with all library functions. I am > in the middle of writing a test program that will run all the relevant > library functions through such file names and reveal those which need > to be fixed (I expect to see about 2 or 3 such functions). I'm delivering as promised ;-). It turned out there were 9 functions that didn't work correctly with /dev/x/foo file names. Fortunately, I was able to correct these problems by patching only 5 files. See the patch below; I tried to make the patches as simple and localized as I possibly could, to avoid introducing any more bugs. The fixed versions were tested using the same test program I used to discover the bugs (for the source of the test program, see my other mail). *** src/libc/compat/sys/vfs/statfs.c~0 Sun Nov 16 14:05:50 1997 --- src/libc/compat/sys/vfs/statfs.c Sat Dec 12 13:53:34 1998 *************** statfs(const char *path, struct statfs * *** 19,28 **** int cdrom_calls_used = 0; int blocks = 0; ! /* Get the drive number */ ! if (path[0] && path[1] == ':') ! drive_number = (path[0] & 0x1f) - 1; ! else { regs.h.ah = 0x19; __dpmi_int(0x21, ®s); --- 19,29 ---- int cdrom_calls_used = 0; int blocks = 0; ! /* Get the drive number, including the case of magic ! names like /dev/c/foo. */ ! _put_path(path); ! drive_number = (_farpeekb(_dos_ds, __tb) & 0x1f) - 1; ! if (_farpeekb(_dos_ds, __tb + 1) != ':' || drive_number == -1) { regs.h.ah = 0x19; __dpmi_int(0x21, ®s); *** src/libc/dos/lfn/_use_lfn.c~0 Sun Jun 28 22:18:02 1998 --- src/libc/dos/lfn/_use_lfn.c Sat Dec 12 14:17:00 1998 *************** *** 17,22 **** --- 17,23 ---- #include #include #include + #include static int use_lfn_bss_count = -1; /* if we are restarted (emacs) */ static unsigned filesystem_flags = _FILESYS_UNKNOWN; *************** _get_volume_info (const char *path, int *** 35,58 **** if (path && *path) { ! if (path[1] == ':') { - dosmemput (path, 3, tbuf_la); tbuf_la += 3; ! if (path[2] != '\\') ! _farpokeb(_dos_ds, tbuf_la - 1, '\\'); ! _farpokeb(_dos_ds, tbuf_la++, '\0'); } ! else if (*path == '\\' && path[1] == '\\') { - int plen = strlen (path) + 1; - /* FIXME: what should we do with the UNC pathnames like "\\machine\vol\path"? We need to know either their DOS drive letter or where does the root directory path ends. For now, we assume the entire path is the root path. */ ! dosmemput (path, plen, tbuf_la); ! tbuf_la += plen + 1; } } --- 36,59 ---- if (path && *path) { ! _put_path(path); ! _farsetsel(_dos_ds); ! if (_farnspeekb(tbuf_la + 1) == ':') { tbuf_la += 3; ! if (_farnspeekb(tbuf_la - 1) != '\\') ! _farnspokeb(tbuf_la - 1, '\\'); ! _farnspokeb(tbuf_la++, '\0'); } ! else if (_farnspeekb(tbuf_la) == '\\' && _farnspeekb(tbuf_la + 1) == '\\') { /* FIXME: what should we do with the UNC pathnames like "\\machine\vol\path"? We need to know either their DOS drive letter or where does the root directory path ends. For now, we assume the entire path is the root path. */ ! for (tbuf_la += 2; _farnspeekb(tbuf_la) != 0; tbuf_la++) ! ; ! tbuf_la++; } } *************** _use_lfn (const char *path) *** 135,144 **** } same_drive_as_last_time = 1; ! if (path) { /* FIXME: a UNC PATH will always force a call to `_get_volume_info'. */ ! if ((path[1] == ':' && toupper (*path) != last_drive) || (*path == '\\' && path[1] == '\\')) same_drive_as_last_time = 0; else --- 136,147 ---- } same_drive_as_last_time = 1; ! if (path && *path) { + _put_path(path); /* FIXME: a UNC PATH will always force a call to `_get_volume_info'. */ ! if ((_farpeekb(_dos_ds, __tb + 1) == ':' ! && toupper (_farpeekb(_dos_ds, __tb)) != last_drive) || (*path == '\\' && path[1] == '\\')) same_drive_as_last_time = 0; else *** src/libc/dos/process/dosexec.c~0 Sun Nov 15 13:45:14 1998 --- src/libc/dos/process/dosexec.c Sat Dec 12 14:41:46 1998 *************** direct_exec_tail(const char *program, co *** 177,184 **** proglen = strlen(program)+1; if (!check_talloc(proglen)) return -1; if(lfn) { - dosmemput(program, proglen, tbuf_ptr); r.x.ax = 0x7160; /* Truename */ r.x.cx = 1; /* Get short name */ r.x.ds = r.x.es = tbuf_ptr / 16; --- 177,186 ---- proglen = strlen(program)+1; 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) { r.x.ax = 0x7160; /* Truename */ r.x.cx = 1; /* Get short name */ r.x.ds = r.x.es = tbuf_ptr / 16; *************** direct_exec_tail(const char *program, co *** 189,199 **** errno = __doserr_to_errno(r.x.ax); return -1; } ! dosmemget(tbuf_ptr, FILENAME_MAX, short_name); ! progname = short_name; ! proglen = strlen(short_name)+1; ! } else ! progname = program; if (!check_talloc(proglen + strlen(args) + 3 + sizeof(Execp) + 48)) return -1; --- 191,200 ---- errno = __doserr_to_errno(r.x.ax); return -1; } ! } ! dosmemget(tbuf_beg == __tb ? tbuf_ptr : __tb, FILENAME_MAX, short_name); ! progname = short_name; ! proglen = strlen(short_name)+1; if (!check_talloc(proglen + strlen(args) + 3 + sizeof(Execp) + 48)) return -1; *** src/libc/posix/sys/stat/fixpath.c~0 Sun Aug 31 13:12:54 1997 --- src/libc/posix/sys/stat/fixpath.c Sat Dec 12 13:29:14 1998 *************** void *** 78,90 **** _fixpath(const char *in, char *out) { int drive_number; ! const char *ip = in; char *op = out; int preserve_case = _preserve_fncase(); char *name_start; int mbsize; ! use_lfn = _USE_LFN; /* Add drive specification to output string */ if (((*ip >= 'a' && *ip <= 'z') || --- 78,96 ---- _fixpath(const char *in, char *out) { int drive_number; ! char in1[FILENAME_MAX]; ! char *ip; char *op = out; int preserve_case = _preserve_fncase(); char *name_start; int mbsize; ! use_lfn = _use_lfn(in); ! ! /* Perform the same magic conversions that _put_path does. */ ! _put_path(in); ! dosmemget(__tb, sizeof(in1), in1); ! ip = in1; /* Add drive specification to output string */ if (((*ip >= 'a' && *ip <= 'z') || *** src/libc/posix/unistd/chdir.c~0 Mon Jun 29 00:15:08 1998 --- src/libc/posix/unistd/chdir.c Sat Dec 12 13:40:50 1998 *************** *** 9,19 **** --- 9,21 ---- #include #include #include + #include int __chdir (const char *mydirname) { __dpmi_regs r; + int drv_no = -1; if (mydirname == 0) { *************** __chdir (const char *mydirname) *** 27,33 **** return -1; } ! if (mydirname[1] != ':' || mydirname[2]) { if(_USE_LFN) r.x.ax = 0x713b; --- 29,43 ---- return -1; } ! _put_path(mydirname); ! ! /* _put_path performs some magic conversions of file names, so ! the path in the transfer buffer can include a drive even though ! MYDIRNAME doesn't seem to. */ ! if (_farpeekb(_dos_ds, __tb + 1) == ':') ! drv_no = (_farpeekb(_dos_ds, __tb) & 0x1f) - 1; ! ! if (drv_no == -1 || _farpeekb(_dos_ds, __tb + 2) != 0) { if(_USE_LFN) r.x.ax = 0x713b; *************** __chdir (const char *mydirname) *** 35,41 **** r.h.ah = 0x3b; r.x.dx = __tb_offset; r.x.ds = __tb_segment; - _put_path(mydirname); __dpmi_int(0x21, &r); if(r.x.flags & 1) { --- 45,50 ---- *************** __chdir (const char *mydirname) *** 44,55 **** } } ! if (mydirname[1] == ':') { /* Change current drive also. This *will* work if the directory change above worked. */ r.h.ah = 0x0e; ! r.h.dl = (mydirname[0] & 0x1f) - 1; __dpmi_int(0x21, &r); } --- 53,64 ---- } } ! if (drv_no != -1) { /* Change current drive also. This *will* work if the directory change above worked. */ r.h.ah = 0x0e; ! r.h.dl = drv_no; __dpmi_int(0x21, &r); }