From Bugzilla Helper: User-Agent: Mozilla/5.0 (X11; U; Linux i686; en-US; rv:1.7.3) Gecko/20040922 Description of problem: unlink() doesn't seem to synchronise with readdir() while the directory holding the file is open. Test program (supplied as attachment) creates a directory, then two files. It then opens the directory and reads the entries, printing the inode number and the filename. When it finds the first entry, it deletes the second file and immediately tries to fopen() it - as I expected, the fopen() call fails [as it should]. However, the next call to readdir() which is the deleted file, shows it with a non-zero inode number as if the file still exists. Version-Release number of selected component (if applicable): glibc-2.3.3-27.1 How reproducible: Always Steps to Reproduce: 1. compile test program 2. run test program 3. observe output 4. do 'ls -al' on the created directory Actual Results: Dir = D16775 5505650: .file 5505651: file 5410128: .. 5505649: . Expected Results: Dir = D16775 5505650: .file 0: file 5410128: .. 5505649: . Additional info:
Created attachment 106508 [details] Test program to demonstrate bug Compile simply as: cc z1.c then run as: a.out
Please cite which standard mandates the behaviour you are asking for. To my knowledge POSIX doesn't require this and the current glibc behaviour (caching directory entries). If you want to see the effect on the next readdir, you need to closedir and opendir again.
The behaviour I expected has 'standard' behaviour for Unices since version 5 (and I don't mean System V, either). This behaviour destroys the ability to make a single clean pass through a directory and not get (misleading) error reports for files that have been removed as a part of processing others. In this case, I read parameters and control information from an ASCII file starting with a '.' character and use it to process images held under their own (the same) filename without a preceding '.' as generated by some graphics program. When processed, both files are unlinked. This means that I then (later on in the pass) hit what looks to be an error: a filename without a dot which doesn't have a matching '.' file which speaks of another application program error. It isn't that I want to see the effect on the next readdir(), it is that the readdir() is returning old and invalid information which needn't be because of the current program's activities. All programs that process directories know to ignore entries with a zero inode value as being a file that has been deleted but the directory slot hasn't been re-used yet, but that a file with a non-zero inode value is a good file. This behaviour breaks that long-standing assumption and calls into question the integrity of the file-system by presenting a program with what looks like a valid directory entry to a file that doesn't exist.
If your program expects this behavior, fix it. The glibc code is correct and there will be no change.