Mail Archives: djgpp-workers/1996/10/31/07:25:54
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
{
- Raw text -