delorie.com/archives/browse.cgi   search  
Mail Archives: djgpp-workers/2002/09/15/03:27:43

Message-ID: <002001c25c88$92825d80$b190adcb@p4>
From: "Andrew Cottrell" <acottrel AT ihug DOT com DOT au>
To: "Charles Sandmann" <sandmann AT clio DOT rice DOT edu>,
"Richard Dawe" <rich AT phekda DOT freeserve DOT co DOT uk>
Cc: <djgpp-workers AT delorie DOT com>
References: <10209142103 DOT AA22000 AT clio DOT rice DOT edu>
Subject: Re: Two rm.exe issues on XP
Date: Sun, 15 Sep 2002 17:19:59 +1000
MIME-Version: 1.0
X-Priority: 3
X-MSMail-Priority: Normal
X-Mailer: Microsoft Outlook Express 6.00.2800.1106
X-MimeOLE: Produced By Microsoft MimeOLE V6.00.2800.1106
Reply-To: djgpp-workers AT delorie DOT com

After Reading Ralph Brown interrupt list it indicates that for NT that the
SFT only contains the filenames. The stat code comments indicate that there
are some issues with 95 whre filenames are blank. Now assuming that W2K and
XP share the same problem as NT with regards to SFT only storing the
filenames then my testing of the fstat also show this to be the case as the
sft ftime, fdate amd fsize are all zero.

Be aware that I also found that the logic in the test parts of fstat, stat
and lstat always display the messages as displayed because fstat() returns
zero if it works and then we negate it via the ..!fstat().... and as such
the test is displayed. fstat does not fail, but instead passes and uses the
trusted ftime, fdate amd fsize and creates an inode based on the file
creation time on XP when I tested it.

....SNIP....
Summary.. fstat gives different inodes for .\ftest.exe and ftest.exe

The reason for this is that in xstat.c the following piece of code is
executed if no filename is used in the  _invent_inode as is the case in
fstat, but not the case for lstat
The offending line in stat.c whcih is a few lines above the symlink check
for trusted_fsize == 510 :
                 stat_buf->st_ino = _invent_inode("", dos_ftime,
trusted_fsize);

  /* If the passed name is empty, invent a new inode unconditionally.
   * This is for those unfortunate circumstances where we couldn't
   * get a name (e.g., fstat() under Novell).  For these we want at
   * least to ensure that no two calls will get the same inode number.
   * The lossage here is that you get different inodes even if you call
   * twice with the same file.  Sigh...
   */
  if (!*name)
    {
      ino_t retval = inode_count;

      inode_count++;
      return retval;
    }

A potential fix (may not work in 100% of cases) is to make the
fixed_filename variable a local variable for the whole fstat_assist()
function instead of just inside an if condition and then call the
invent_inode with the fixed_filename as the filename parameter if the
fixed_filename is not null. I have tested this and it works on XP when
calling the fstat test program with "fstat.c .\fstat.c".

I don't know what this will fix as the rm.exe uses lstat which does not
suffer from this when testing for files.
==========================================================

In the fileutils 4.1 rm.exe uses remove.c whioch uses lstat() which does
return the same inode for the .\ftest.exe and ftest.exe.....

In looking at remove.c from the fileutils 4.1 it uses lstat which also
hashes the inode as the code cannot get the SDA info it needs and has the
following results:

test: 2 268435458 30755 3 42 32 1032058276 Sun Sep 15 12:51:16 2002
                        Block size: 4096
_djstat_fail_bits = 14
Cannot find SDA entry which corresponds to pathname (bad SDA pointer?)
Failed to get starting cluster number; inode defaults to hashing
(if no other messages were printed, then this is either an empty
file on a local disk drive, or a file on a networked drive, or
you run under some kind of DOS clone)
_STFAIL_BADSDA      4   /* Bad pointer to SDA */
_STFAIL_HASH     0x10   /* inode defaults to hashing */


If I move the asert in remove.c to below the inode check then I get the
following :-
rm: ERROR: the directory `test/test' initially had device/inode
numbers 664472/1, but now (after a chdir into it), the numbers for `.'
are 2/268435458.  That means that while rm was running, the directory
was replaced with either another directory or a link to another directory.


This looks like there could be a problem with one of the following or some
other problem:-
1) Detecting devices as 664472 is not correct and the inode of 1 looks like
an inode for the root of a drive
2) Some code is eating characters before the "\" and then the filename gets
converted to a root drive.
3) Code is not

I ran the lstat.exe test program and never got the 664472/1 results the
closest I got was a 2/1 for "lstat \". I tried "lstat test\test" and "lstat
test\test\." and then cd'd into the test and tried "lstat test" & "lstat
test\." and then cd'd into test and repeated the tests and always got the
same results..... I think that lstat by itself may not be the problem.

Next time I will kludge a version of rm.exe which will allow me to modify
lstat.c without needing to rebuild libc for every change I want to test or
debug.

- Raw text -


  webmaster     delorie software   privacy  
  Copyright © 2019   by DJ Delorie     Updated Jul 2019