'Checking if a directory exists in Unix (system call)

I am not able to find a solution to my problem online.

I would like to call a function in Unix, pass in the path of a directory, and know if it exists. opendir() returns an error if a directory does not exist, but my goal is not to actually open, check the error, close it if no error, but rather just check if a file is a directory or not.

Is there any convenient way to do that please?



Solution 1:[1]

You can make use of the stat system call by passing it the name of the directory as the first argument. If the directory exists a 0 is returned else -1 is returned and errno will be set to ENOENT

EDIT:

If the return value is 0 you would need an additional check to ensure that the argument is actually a directory and not a file/symlink/char special file/blk special file/FIFO file. You can make use of the st_mode field of the stat structure for this.

Solution 2:[2]

If you don't really care about type of this filesystem object, access(name, F_OK) checks for exsistence of something with this name. If you need to be sure this is directory, use stat() and check type with S_ISDIR() macro.

Solution 3:[3]

Another simple way would be:

int check(unsigned const char type) {
    if(type == DT_REG)
        return 1;
    if(type == DT_DIR)
        return 0;
    return -1;
}

You can then pass struct dirent* object's d_type to check function.

If check returns 1, then that path points to regular file.

If check returns 0, then that path points to a directory.

Otherwise, it is neither a file or a directory (it can be a Block Device/Symbolic Link, etc..)

Solution 4:[4]

C++17

Use std::filesystem::is_directory:

#include <filesystem>

void myFunc(const std::filesystem::path& directoryPath_c)
{
    if (std::filesystem::is_directory(directoryPath_c)) {
    //if (std::filesystem::exists(directoryPath_c)) { // Alternative*
        // do something.
    }
}

Or in its noexept version:

#include <filesystem>

void myFunc(const std::filesystem::path& directoryPath_c)
{
    std::error_code ec{};
    if (std::filesystem::is_directory(directoryPath_c, ec)) {
    //if (std::filesystem::exists(directoryPath_c, ec)) { // An alternative*
        // do something.
    }
}
  • The disadvantage of the alternative is, that if directoryPath_c exists as a regular-file, std::filesystem::exists(directoryPath_c) returns true despite the folder does not exists.

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1
Solution 2 blaze
Solution 3
Solution 4