Date: Thu, 31 Oct 1996 14:06:27 +0200 (IST) From: Eli Zaretskii To: Neil Jarvis Cc: djgpp-workers AT delorie DOT com Subject: Re: ar on networked drive In-Reply-To: <9610301718.AA27269@leopard.proteon.com> Message-Id: Mime-Version: 1.0 Content-Type: TEXT/PLAIN; charset=US-ASCII On Wed, 30 Oct 1996, Neil Jarvis wrote: > I think the conversion test should be moved outside the first group of > if/elses to catch all the cases of failure, where errno = ENMFILE. Thanks for your clear diagnostics. Please try the patch below and tell me if it works for you, so it could be used to fix the library and the executables in bnu27b.zip. (If you have problems installing the patch, drop me a note and I will explain how to do it.) > But > I don't understand this routine, or why it is even looking at volume > labels, so I am looking to the experts for a fix. The reason is explained in the comments in the code fragment that you've posted. We want `stat' to be able to return valid info when called on volume labels, since a volume label is a directory entry on MSDOS. An early version of `stat' used to call `findfirst' just once with all the possible attributes, including FA_LABEL. However, it turned out that some environments (and your NFS client seems to be one of them) will never fail `findfirst' if you include FA_LABEL attribute, but will instead return garbage in the ff_blk structure. Therefore, `stat' now looks for volume labels only if the call without FA_LABEL failed, and always compares the name returned with the pathname you passed as the argument to `stat' to be sure that `findfirst' indeed have found a volume label and not returned garbled values due to poor implementation of a network redirector. *** src/libc/posix/sys/stat/stat.c~0 Thu Oct 31 12:36:20 1996 --- src/libc/posix/sys/stat/stat.c Thu Oct 31 13:29:48 1996 *************** stat_assist(const char *path, struct sta *** 620,625 **** --- 620,628 ---- } else { + int i = 0; + int j = strlen (path) - 1; + /* Check for volume labels. We did not mix FA_LABEL with other attributes in the call to `__findfirst' above, because some environments will return bogus info in *************** stat_assist(const char *path, struct sta *** 630,637 **** label. Hence we test the returned name to be PATH. */ if (!__findfirst(path, &ff_blk, FA_LABEL)) { ! int i = strlen (ff_blk.ff_name) - 1; ! int j = strlen (path) - 1; if (j >= i) { --- 633,639 ---- label. Hence we test the returned name to be PATH. */ if (!__findfirst(path, &ff_blk, FA_LABEL)) { ! i = strlen (ff_blk.ff_name) - 1; if (j >= i) { *************** stat_assist(const char *path, struct sta *** 639,657 **** if (toupper (ff_blk.ff_name[i]) != toupper (path[j])) break; } ! if (i < 0 && path[j] == '/') ! { ! /* Indeed a label. */ ! statbuf->st_mode = READ_ACCESS; #ifdef S_IFLABEL ! statbuf->st_mode |= S_IFLABEL; #endif ! statbuf->st_ino = 1; ! statbuf->st_size = 0; ! dos_ftime = ! ( (unsigned)ff_blk.ff_fdate << 16 ) + ff_blk.ff_ftime; ! } } else { --- 641,658 ---- if (toupper (ff_blk.ff_name[i]) != toupper (path[j])) break; } + } ! if (i < 0 && path[j] == '/') ! { ! /* Indeed a label. */ ! statbuf->st_mode = READ_ACCESS; #ifdef S_IFLABEL ! statbuf->st_mode |= S_IFLABEL; #endif ! statbuf->st_ino = 1; ! statbuf->st_size = 0; ! dos_ftime = ( (unsigned)ff_blk.ff_fdate << 16 ) + ff_blk.ff_ftime; } else {