Follow

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use
Contact

How to check if a folder is actually an alias in C (macOS)?

I’m writing a simple recursive program that looks for specific files in a certain directory tree on macOS.
Problem is, if it finds an alias to a folder that is above the current directory on the same branch of the tree it starts to loop infinitely and crashes after a while with segmentation fault (after only 252 levels or so of recursion it seems, which appears to be a low number to me by the way). I tried to modify my code not to navigate files which are symbolic links, but it still navigates those aliases.

Here’s an example structure of directories(every line has at the left the name of some folder, at the right its contents):

folder1: folder2

MEDevel.com: Open-source for Healthcare and Education

Collecting and validating open-source software for healthcare, education, enterprise, development, medical imaging, medical records, and digital pathology.

Visit Medevel

folder2: folder1(alias)

These are some lines taken out from the code I wrote, updated to be complete(without frees and error checks):

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);
        }
    }
}

>Solution :

I tried to modify my code not to navigate files which are symbolic links, but it still navigates those aliases

stat() will never return data such that S_ISLNK(info.st_mode) is true (except see below). Per the POSIX stat() documentation:

If the named file is a symbolic link, the stat() function shall continue pathname resolution using the contents of the symbolic link, and shall return information pertaining to the resulting file if the file exists.

and

The lstat() function shall be equivalent to stat(), except when path refers to a symbolic link. In that case lstat() shall return information about the link, while stat() shall return information about the file the link references.

You need to replace

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

with

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

Note also the return value from [l]stat() needs to be checked. The contents of the info struct will not mean anything if the [l]stat() call fails, so the checks using ISDIR() and ISLNK() could return any value.

Add a comment

Leave a Reply

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use

Discover more from Dev solutions

Subscribe now to keep reading and get access to the full archive.

Continue reading