user1867748
user1867748

Reputation: 49

While loop stopping without apparent reason

I have the following C code:

#include <dirent.h>
#include <stdio.h>
#include <string.h>
#include <signal.h>
#include <unistd.h>


int main(int argc, const char *argv[]){
    const char *directory_path;
    directory_path = argv[1];
    char *dirname;
    dirname = strdup(directory_path);
    recursive_ls(dirname);

}


int recursive_ls(char *dirname){
    printf("%s\n",dirname);
    DIR *d;
    struct dirent *dir;

    if ((d=opendir(dirname))==-1) {
        perror("Oops");
        return(0);
    }
    if(d){
        while((dir = readdir(d)) !=NULL){
            char *dname = dir->d_name;
            puts(dname);
/*          if(strcmp(dir->d_type,DT_REG)){
                puts("I am a regular file");
            } else if(strcmp(dir->d_type,DT_DIR)){
                puts("I am a directory.");
                            recursive_ls(strcat(strcat(dirname,"/"),dir->d_name));
                } else {
                    puts("I am not a file");
            }
*/    
        }

        closedir(d);
    }
return(0);
}

if I comment out the if(){} else if(){} else(){} inside the while loop, I get the following output:

Debug
.project
pipe_test.c
.
..

Which is everything in the directory. If on the other hand, I uncomment it, then I get the following:

/home/wilbert/workspace/pipe_test
.cproject

I figure I should at least get the "I am not a file" part if everything if the recursive step is screwing things up; however, for some reason I don't so I am puzzled. The thing compiles and shows no syntactic errors so I am really puzzled. Why is this happening?

Upvotes: 2

Views: 121

Answers (2)

David Ranieri
David Ranieri

Reputation: 41046

As Jonathon suggest d_type is an unsigned char, so change to:

if(dir->d_type == DT_REG){
   puts("I am a regular file");
} else if(dir->d_type == DT_DIR){
   puts("I am a directory.");
   recursive_ls(strcat(strcat(dirname,"/"),dir->d_name));
} else {
   puts("I am not a file");
}

Upvotes: 4

Henrik
Henrik

Reputation: 4314

The d_type member of struct dirent is not a string (char *), but an unsigned char. This is really just an 8 bit integer, which is a primitive type. When comparing primitive types we use the == operator. strcmp is strictly for comparing strings.

if (dir->d_type == DT_REG) {
   puts("I am a regular file");
} else if (dir->d_type == DT_DIR) {
   puts("I am a directory.");
   recursive_ls(strcat(strcat(dirname,"/"),dir->d_name));
} else {
   puts("I am not a file");
}

See the manual for more info.

And, even though your original code compiles without errors, it gives lots of warnings when you include the commented body. A good tip is to always consider compiler warnings as bugs.

Upvotes: 2

Related Questions