第二次无法打开目录

时间:2017-05-31 09:02:32

标签: c directory

我在第二次调用时打开同一目录时遇到问题。 例如我首先打开folder1 / folder2;然后,如果我调用我在folder1上使用的函数,它说它无法打开它。我虽然会关闭路径中的所有目录并试图这样做,但没有结果。 这是我的代码

void scanDir(char *dir, int depth, char type, char *path, long gtsize, int attrib)
{
    DIR *dp;
    struct dirent *entry;
    struct stat statbuf;
    char newPath[strlen(path)+strlen(dir)];
    if((dp = opendir(dir)) == NULL) {
        fprintf(stderr,"Cannot open directory %s\n because of e", dir);
        exit(10);
        return;
    }
    strcpy(newPath, path);
    strcat(newPath, dir);
    if (type!='f' && testAttrib(attrib, dir))
        printf("%s\n", newPath); 
    strcat(newPath, "/");
    chdir(dir);
    while((entry = readdir(dp)) != NULL) {
        stat(entry->d_name,&statbuf);

        if(S_ISDIR(statbuf.st_mode) && testAttrib(attrib, entry->d_name)) {
            if(!strcmp(".",entry->d_name) || !strcmp("..",entry->d_name))
               continue; // ignore . and ..
            if (depth>1 || depth<=-1)
                scanDir(entry->d_name,depth-1,type,newPath,gtsize,attrib);
        }
        if(S_ISREG(statbuf.st_mode) && type!='d' && testAttrib(attrib, entry->d_name)) {
                off_t sizeF = statbuf.st_size;
                char filePath[100];
                strcpy(filePath, newPath);
                strcat(filePath, entry->d_name);
                if(sizeF>=gtsize)
                    printf("%s \n", filePath);
            }
    }
    chdir("..");
    closedir(dp);
}

2 个答案:

答案 0 :(得分:2)

char newPath[strlen(path)+strlen(dir)];  //WRONG!

肯定是错的。您需要为终止0保留一个额外字节,并且您要添加/。所以它应该是

char newPath[strlen(path)+strlen(dir)+2];

顺便说一句,请考虑使用snprintf(3)asprintf(3)代替strcat来电。

我不确定调用chdir(2)是一个明智的想法,你当然应该检查它是否顺利。请参阅perror(3)errno(3)strerror(3)

同时查看nftw(3)

答案 1 :(得分:1)

在struct dirent中,成员d_name包含没有路径的名称。这意味着传递给函数opendir()的参数没有文件或目录的路径,因此发生错误ENOENT。

假设你有目录/ home / usr / folder1 / folder2。你打电话给

scandir("/home/usr/folder1/", 2, type, ...) // I understood only first two parameters.

这个函数似乎有效,但是当函数递归调用自己搜索/ home / usr / folder1 / folder2时

if (depth>1 || depth<=-1) scanDir(entry->d_name,depth-1,type,newPath,gtsize,attrib);

这次传递给scandir的第一个参数是&#34; folder2&#34;不是&#34; / home / usr / folder1 / folder2&#34;所以opendir(dir)给出了一个名为ENOENT的错误

还有一点需要注意的是readdir()函数不是可重入函数,因此调用readdir()函数可能会导致预期的错误。在你的代码中,它看起来像函数提供你想要的结果。但是,我认为&#34;它如何运作&#34;可能与你的想法不同。如果代码变得复杂,我建议使用readdir_r()函数,它是readdir的重入版本

根据readdir的手册页:

  

成功时,readdir()返回指向dirent结构的指针。 (这个          结构可以静态分配;不要试图释放(3)它。)

递归调用scandir()函数后,在每个函数堆栈中,由于结构是静态分配的,因此您的条目变为NUll指针。

对你的功能的另一个建议是使用linux提供的nftw()或scandir()函数。特别是nftw非常强大,而你们大多数人都想要。