Message-ID: <002001c25c88$92825d80$b190adcb@p4> From: "Andrew Cottrell" To: "Charles Sandmann" , "Richard Dawe" Cc: 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 Content-Type: text/plain; charset="iso-8859-1" Content-Transfer-Encoding: 7bit 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.