代码之家  ›  专栏  ›  技术社区  ›  Ernaldo

如何在C(macOS)中检查文件夹是否真的是别名?

  •  1
  • Ernaldo  · 技术社区  · 3 年前

    我正在编写一个简单的递归程序,在macOS上的某个目录树中查找特定的文件。 问题是,如果它在树的同一分支上找到当前目录上方的文件夹的别名,它就会开始无限循环,并在一段时间后因分段错误而崩溃(似乎只经过252级左右的递归,顺便说一句,这对我来说似乎是一个低数字)。我试图修改我的代码,不导航作为符号链接的文件,但它仍然导航那些别名。

    以下是目录结构的示例(每行左边都有某个文件夹的名称,右边是其内容):

    文件夹1:文件夹2

    folder2:folder1(别名)

    以下是从我编写的代码中提取的一些行,更新为完整(没有释放和错误检查):

    char *name = //target file name
    int myfind(){
        DIR *curr_dir = opendir(".");
        struct dirent *next_entry;
        struct stat info;
        char *entry_name;
        char *path;
        while((next_entry = readdir(curr_dir)) != NULL){
            entry_name = next_entry->d_name;
            //ignore . and ..
            if(strcmp(entry_name,".") == 0 || strcmp(entry_name,"..") == 0)
                continue;
            stat(entry_name, &info);
            if(strncmp(name, entry_name, 255) == 0){
                path = realpath(entry_name, NULL);
                //print info about file found
            }
            if(S_ISDIR(info.st_mode) && !S_ISLNK(info.st_mode)){ 
                char *prev_path = getwd(NULL);
                chdir(entry_name);
                myfind();
                chdir(prev_path);
            }
        }
    }
    
    1 回复  |  直到 3 年前
        1
  •  4
  •   Andrew Henle    3 年前

    我试图修改我的代码,而不是导航作为符号链接的文件,但它仍然导航那些别名

    stat() 永远不会返回这样的数据 S_ISLNK(info.st_mode) 为真(见下文除外)。每 the POSIX stat() documentation :

    如果命名文件是符号链接,则 stat() 函数应使用符号链接的内容继续进行路径名解析,并应返回与结果文件有关的信息(如果文件存在)。

    这个 lstat() 函数应等效于stat(),除非path指的是符号链接。那样的话 lstat() 应返回链接的信息,而stat()应返回链接引用的文件的信息。

    你需要更换

    stat(entry_name, &info);
    if(S_ISDIR(info.st_mode) && !S_ISLNK(info.st_mode)){ 
      //navigate to next_entry
    }
    

    具有

    int rc = lstat(entry_name, &info);
    if((rc==0) && S_ISDIR(info.st_mode) && !S_ISLNK(info.st_mode)){ 
      //navigate to next_entry
    }
    

    还请注意的返回值来自 [l]stat() 需要检查。的内容 info 如果 [l] stat() 调用失败,因此使用的检查 ISDIR() ISLNK() 可以返回任何值。