Search code examples
cposixsymlink

Is there a programmatic way to tell if a symlink points to a file or directory in C?


I am iterating directories recursively with readdir.

struct dirent is documented here, and notes that d_type can have different values including DT_LNK and DT_DIR and DT_REG. However, when d_type is DT_LNK, there is no hint about whether the link is to a file or directory.

Is there a a way to check whether the target of a symlink is a file or directory?


Solution

  • The dirent structure might tell you if the entry is a directory or a symbolic link, but some file systems do not provide this information in d_type and set it to DT_UNKNOWN.

    In any case, the simplest way to tell if a symbolic link points to a directory or not, is via a stat system call that will resolve the symbolic link and if successful, will populate the stat structure, allowing for S_ISDIR to give you the information:

    #include <sys/types.h>
    #include <sys/stat.h>
    #include <unistd.h>
    
    int is_directory(const char *path) {
        struct stat st;
        return !stat(path, &st) && S_ISDIR(st.st_mode);
    }
    

    Note these caveats:

    • you must construct the path from the directory name and the entry name to pass to is_directory().
    • recursing on directories linked to by symbolic links may cause infinite recursion as the symbolic link may point to a parent directory or the directory itself where it is located.