简体   繁体   中英

stat using S_ISDIR Don't seem to always work

I've noticed something strange in the output of my function (in c). This function detect in a directory if an element is a file or a subdirectory.

// i cant detected properly if an element is a file or a dir 
int RecursiveSearch(char *Dir){
    DIR *Directory;
    //DIR *SubDirectory;
    struct dirent *entry;
    struct stat filestat;

    printf("I am Reading %s Directory\n", Dir);

    Directory = opendir(Dir);
    if(Directory == NULL)
    {
        perror("Unable to read directory.. i'm leaving\n");
        return(1); // leave
    }

    /* Read directory entries */
    while( (entry=readdir(Directory)) )
    {
        stat(entry->d_name,&filestat);
        if( S_ISDIR(filestat.st_mode) ){
            printf("%4s: %s\n","Dir",entry->d_name);
            if (strstr(entry->d_name, ".") == NULL && strstr(entry->d_name, "..") == NULL ) // to not infinit loop
            {
                // Recursion
                printf("\n*Entering a subDirectory*\n");
                RecursiveSearch(entry->d_name);
                printf("\n*Leaving a subDirectory*\n");
            }


        }
        else
            printf("%4s: %s\n","File",entry->d_name);
    }
    closedir(Directory);

    return(0);
}

I call it in the main like this to test it RecursiveSearch("./Directories");

And this is my output在此处输入图片说明

My problem is under "Starting Recursive Research.."

As you can see SubDir is not a file. I can't see what i did wrong in the function.

If you need any additional clarification please ask.

EDIT :

int RecursiveSearch(char *Dir){
    DIR *Directory;
    struct dirent *entry;
    struct stat filestat;

    printf("I am Reading %s Directory\n", Dir);

    Directory = opendir(Dir);
    if(Directory == NULL)
    {
        perror("Unable to read directory.. i'm leaving\n");
        return(1); // leave
    }

    /* Read directory entries */
    while( (entry=readdir(Directory)) )
    {
        char fullname[100];
        sprintf(fullname, "%s/%s",Dir,entry->d_name);
        stat(fullname,&filestat);
        if( S_ISDIR(filestat.st_mode) ){
            printf("%4s: %s\n","Dir",fullname);
            if (strcmp(entry->d_name, ".") != 0 && strcmp(entry->d_name, "..") != 0 ) // to not infinite loop
            {
                // Recursion
                printf("\n*Entering a subDirectory*\n");
                RecursiveSearch(fullname);
                printf("\n*Leaving a subDirectory*\n");
            }
        }
        else
            printf("%4s: %s\n","File",fullname);
    }
    closedir(Directory);

    return(0);
}

entry->d_name is just the name, it doesn't have the directory prefix. It's interpreted relative to the process's working directory, not the current directory in the recursion of the function.

You need to prefix the name with the directory name when calling other functions, including the recursion.

Also, you need to use strcmp() to compare the name to . and .. . Using strstr() prevents recursing into directories that have . anywhere in the names.

int RecursiveSearch(char *Dir){
    DIR *Directory;
    struct dirent *entry;
    struct stat filestat;

    printf("I am Reading %s Directory\n", Dir);

    Directory = opendir(Dir);
    if(Directory == NULL)
    {
        perror("Unable to read directory.. i'm leaving\n");
        return(1); // leave
    }

    /* Read directory entries */
    while( (entry=readdir(Directory)) )
    {
        char fullname[MAXPATH];
        sprintf(fullname, "%s/%s", Dir, entry->d_name);
        stat(fullname,&filestat);
        if( S_ISDIR(filestat.st_mode) ){
            printf("%4s: %s\n","Dir",fullname);
            if (strcmp(entry->d_name, ".") != 0 && strcmp(entry->d_name, "..") != 0 ) // to not infinite loop
            {
                // Recursion
                printf("\n*Entering a subDirectory*\n");
                RecursiveSearch(fullname);
                printf("\n*Leaving a subDirectory*\n");
            }
        }
        else
            printf("%4s: %s\n","File",fullname);
    }
    closedir(Directory);

    return(0);
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM