Mailing-List: contact cygwin-help AT cygwin DOT com; run by ezmlm List-Subscribe: List-Archive: List-Post: List-Help: , Sender: cygwin-owner AT cygwin DOT com Mail-Followup-To: cygwin AT cygwin DOT com Delivered-To: mailing list cygwin AT cygwin DOT com To: cygwin AT cygwin DOT com From: "Mikael" Subject: Re: Why does stat fail for some files? Date: Thu, 15 Sep 2005 22:19:59 +0200 Lines: 138 Message-ID: References: <091520052002 DOT 22143 DOT 4329D3450002AB180000567F22007614380A050E040D0C079D0A AT comcast DOT net> X-IsSubscribed: yes 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 >> #include >> #include >> #include >> #include >> >> #include >> #include >> #include >> >> 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/