readdir(3) strange behavior : finding non existing files in /dev/
I'm using opendir / readdir / closedir to reproduce a program similar to ls, it went pretty well until I tried to ls "/dev/" when it comes to "/dev/fd/" with the recursive options, it find more files than it actually exists, those are not hidden files (I mean '.' commencing files ). The true ls give me : "/dev/fd/ :" "0 1 2 3" Mine too. But, the thing is that in gdb, it find 3 more files that are 4,5 and 6. I heard that gdb create his own environement so let's forget this. When I try ls "/dev/fd/" -R the true ls stop immediately the listing while my program gives :
"/dev/fd/3:"
"/dev/fd/3/3/"
"/dev/fd/3/3/......../10"
stat return -1 after 40 files at least but the execution continues : segmentation fault.
In my computer, "/dev/fd/3/" and so are symbolic links, the macro "S_ISDIR" ret开发者_开发技巧urns me 0 on the existing files but on the non existing files like : "/dev/fd/6/" it return 1...
I wanted to know why my program goes wrong while the true ls doesn't, I noticed that ls use stat64 in my computer but when I do it still goes wrong.. it also use fstat64, futex and others syscall that I don't know.
I can show you some sample of my codes or detail a bit more it's really hard to explain for me I'm sorry for that.
Thanks you.
PS : I don't get that statement in the readdir manpage : "The data returned by readdir may be overwritten by subsequent calls to readdir for the same directory stream"
PS : I don't get that statement in the readdir manpage : "The data returned by readdir may be overwritten by subsequent calls to readdir for the same directory stream"
What they are basically saying is that the function is not re-entrant, and that the pointer returned by readdir
shouldn't simply be cached as a unique value, as the underlying data that is being pointed to will change the next time you call the readdir
function. Basically they are allowing for implementations to either define statically allocated data that can be recycled by the function, or dynamic memory managed by the OS, so that the caller of readdir
does not have to worry about managing the memory pointed to by the return value of readdir
. For instance, for a sample function like:
int* my_sample_increment()
{
static int val = 0;
val++;
return &val;
}
if you were to-do something like
int* int_ptr_1 = my_sample_increment();
int* int_ptr_2 = my_sample_increment();
Then both int_ptr_1
and int_ptr_2
will point to the same value, and in this case it will be the value 1
. Each pointer won't be pointing to a unique integer value.
So the same is true with readdir
. You cannot simply call readdir
and store the pointer being returned, expecting to use it at a later date without the data that is being pointed to being modified by any subsequent calls to readdir
between the time you saved the pointer, and the time you use it. If you need such functionality, that is what the re-entrant version, readdir_r
is for.
精彩评论