This is the mail archive of the cygwin mailing list for the Cygwin project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

Re: Why does stat fail for some files?


Eric Blake wrote:
>> Hello, I'm doing homework and I'm having some problems with stat()
>> failing.
>
> It's called homework for a reason, but here are some hints:

Come on, at least I just didn't post the assignment without a single line 
code and waited
for someone to fix it for me like I see alot on different forums and 
newsgroups. I've put effort into this and I also tried to use a readable 
coding style.

>
>> Consider the following C program:
>>
>> #include <assert.h>
>> #include <errno.h>
>> #include <stdio.h>
>> #include <stdlib.h>
>> #include <string.h>
>>
>> #include <dirent.h>
>> #include <sys/stat.h>
>> #include <sys/types.h>
>>
>> static void scan_directory(const char *);
>>
>> int
>> main(int argc, char **argv)
>> {
>>    if(argc == 1)
>>    {
>>       fprintf(stderr, "Usage: dirscan path\n");
>>
>>       return EXIT_FAILURE;
>>    }
>>
>>    scan_directory(argv[1]);
>>
>>    return EXIT_SUCCESS;
>> }
>>
>> static void
>> scan_directory(const char *path)
>> {
>>    DIR *directory = NULL;
>>    struct dirent *entry = NULL;
>>    struct stat statbuf;
>>    int return_value = 0;
>>
>>    directory = opendir(path);
>>
>>    if(!directory)
>>    {
>>       fprintf(stderr, "Directory %s could not be opened.\n", path);
>
> fprintf can clobber errno...
>
>>       fprintf(stderr, "Reason: %s\n", strerror(errno));
>
> so you may be printing the wrong reason.
>
>>
>>       /* Don't exit program, we may have been called recursively and
>>          we want to scan what we can.
>>       */ return;
>>    }
>>
>>    while((entry = readdir(directory)))
>
> You just ignored the possibility that readdir might set errno.
>
>>    {

Ok, I can set errno to 0 before I call stat(), but I was under the 
impression that if stat() fails it will overwrite the current value of errno 
with a new one indicating the error. And since I determine if an error 
occured by checking the return value of stat() and *then* checking errno if 
the return value was != 0 instead of looking at errno directly, isn't my way 
safe even if errno was nonzero before the call?

>>       return_value = stat(entry->d_name, &statbuf);
>
> Hmm - think relative vs. absolute pathname, then consider where
> you invoked your command.

Ah, that's it! readdir() is looking at the directory I supplied as a command 
line argument, but stat() is looking at the cwd. And in the cwd I happen to 
have a files called "Makefile", ".", and, "..", respectively. but not the 
other files found by readdir(). So I to change the call to stat() so it gets 
the whole path to the files found by readdir(). Thanks very much!

>
>>
>>       if(return_value)
>>          fprintf(stderr, "stat() failed for %s. Reason: %s\n",
>>                    entry->d_name, strerror(errno));
>>       else
>>          printf("stat() called successfully on: %s\n",
>>    entry->d_name); }
>>
>>    return_value = closedir(directory);
>>
>>    assert(!return_value); /* closedir() returns 0 on success */
>> }
>>
>> And this is what happens when I run it (first ls -al):
>> $ ls -al /c/cygwin/home/mikael/coding/cygwin/c++/read_directory/
>> total 773
>> drwxrwxrwx+  2 mikael None      0 Sep 15 16:36 ./
>> drwxrwxrwx+ 16 mikael None      0 May 20 22:53 ../
>> -rwxrwxrwx   1 mikael None    273 Sep 15 16:36 Makefile*
>> -rwxrwxrwx   1 mikael None    792 Aug 19  2004 read_directory.cpp*
>> -rwxr-xr-x   1 mikael None 604746 Sep 15 16:36 read_directory.exe*
>> -rw-r--r--   1 mikael None 129520 Sep 15 16:36 read_directory.o
>>
>> $ ./dirscan.exe
>> /c/cygwin/home/mikael/coding/cygwin/c++/read_directory/ stat()
>> called successfully on: .
>> stat() called successfully on: ..
>> stat() called successfully on: Makefile
>> stat() failed for read_directory.cpp. Reason: No such file or
>> directory stat() failed for read_directory.exe. Reason: No such file
>> or directory stat() failed for read_directory.o. Reason: No such
>> file or directory
>
> As a side note, Windows has the annoying habit that when a file
> is locked by another application, stat() won't get much information
> about the file, but at least it won't fail.

Interesting...I will be sure keep that in mind if I encounter other problems 
with stat() being non-informative.

Thanks for the quick reply, Eric!

/ Mikael 




--
Unsubscribe info:      http://cygwin.com/ml/#unsubscribe-simple
Problem reports:       http://cygwin.com/problems.html
Documentation:         http://cygwin.com/docs.html
FAQ:                   http://cygwin.com/faq/


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]