0

I found the answer to another question here to be very helpful.

There seems to be a limitation of the sys/stat.h library as when I tried to look in other directories everything was seen as a directory.

I was wondering if anyone knew of another system function or why it sees anything outside the current working directory as only a directory.

I appreciate any help anyone has to offer as this is perplexing me and various searches have turned up no help.

The code I made to test this is:

#include <sys/stat.h>
#include <dirent.h>
#include <stdio.h>

int main(void) {

        int status;

        struct stat st_buf;
        struct dirent *dirInfo;

        DIR *selDir;
        selDir = opendir("../");
                                    // ^ or wherever you want to look
        while ((dirInfo = readdir(selDir))) {

                status = stat (dirInfo->d_name, &st_buf);

                if (S_ISREG (st_buf.st_mode)) {
                        printf ("%s is a regular file.\n", dirInfo->d_name);
                }
                if (S_ISDIR (st_buf.st_mode)) {
                        printf ("%s is a directory.\n", dirInfo->d_name);
                }

        }

        return 0;

}
Community
  • 1
  • 1
Ambiguities
  • 415
  • 6
  • 18
  • You should check the return value from `opendir()` — as well as `stat()` — before using the results. You should also call `closedir()` when you're done, of course. – Jonathan Leffler Apr 10 '13 at 23:50

2 Answers2

2

You need to check the status of the stat call; it is failing.

The trouble is that you're looking for a file the_file in the current directory when it is actually only found in ../the_file. The readdir() function gives you the name relative to the other directory, but stat() works w.r.t the current directory.

To make it work, you'd have to do the equivalent of:

char fullname[1024];

snprintf(fullname, sizeof(fullname), "%s/%s", "..", dirInfo->d_name);

if (stat(fullname, &st_buf) == 0)
    ...report on success...
else
    ...report on failure...
Jonathan Leffler
  • 730,956
  • 141
  • 904
  • 1,278
  • That works wonderfully. Would you be able to recommend an if condition that would be able to check whether or not I'm looking in the current directory that would work with argv[]? – Ambiguities Apr 10 '13 at 23:25
  • Unless the current directory is the root directory, `/`, the fact that your `readdir()` is looking at `"../"` means your names are not in the current directory. If the directory name is `"."`, then it is easy. It's simplest to assume you need to create the composite name; that'll always work. If you don't want to do that, then `stat(".", &sb1)` and `stat(dirname, &sb2)` and compare `st_ino` and `st_dev` to ensure they're the same in `sb1` and `sb2` is probably the best test. – Jonathan Leffler Apr 10 '13 at 23:33
  • (Incidentally, the reason the files all directories is that the entry `".."` appears in both directories; the failing `stat()` calls don't change the `st_buf` variable, so all the files appeared to be the same directory (which would have the details of the `..` directory in the current directory). – Jonathan Leffler Apr 10 '13 at 23:44
0

If you printed out stat, you'll notice there's an error (File not found).

This is because stat takes the path to the file, but you're just providing the file name. You then call IS_REG on garbage values.

So, suppose you have a file ../test.txt You call stat on test.txt...That isn't in directory ./test.txt, but you still print out the results from IS_REG.

Lycus
  • 410
  • 1
  • 6
  • 15