80

How can I check if a directory exists on Linux in C?

alk
  • 69,737
  • 10
  • 105
  • 255
user1543915
  • 1,025
  • 1
  • 10
  • 16
  • Possible duplicate of [C faster way to check if a directory exists](http://stackoverflow.com/questions/9314586/c-faster-way-to-check-if-a-directory-exists) – patryk.beza Dec 22 '16 at 11:50
  • Does this answer your question? [Checking if a directory exists in Unix (system call)](https://stackoverflow.com/questions/3828192/checking-if-a-directory-exists-in-unix-system-call) – MasterHD Jan 19 '21 at 10:40

6 Answers6

106

You can use opendir() and check if ENOENT == errno on failure:

#include <dirent.h>
#include <errno.h>

DIR* dir = opendir("mydir");
if (dir) {
    /* Directory exists. */
    closedir(dir);
} else if (ENOENT == errno) {
    /* Directory does not exist. */
} else {
    /* opendir() failed for some other reason. */
}
pevik
  • 4,523
  • 3
  • 33
  • 44
hmjd
  • 120,187
  • 20
  • 207
  • 252
  • If the folder does not exists, then how can I create one right away after confirming it does not exists? – Pototo Apr 20 '17 at 18:15
  • In case you're using Visual Studio, `dirent.h` isn't available, see [this SO post](https://stackoverflow.com/questions/5530933/dirent-h-in-visual-studio-2010-or-2008) for alternatives – gezzahead Apr 09 '18 at 08:49
57

Use the following code to check if a folder exists. It works on both Windows & Linux platforms.

#include <stdio.h>
#include <sys/stat.h>

int main(int argc, char* argv[])
{
    const char* folder;
    //folder = "C:\\Users\\SaMaN\\Desktop\\Ppln";
    folder = "/tmp";
    struct stat sb;

    if (stat(folder, &sb) == 0 && S_ISDIR(sb.st_mode)) {
        printf("YES\n");
    } else {
        printf("NO\n");
    }
}
pevik
  • 4,523
  • 3
  • 33
  • 44
Saman
  • 767
  • 6
  • 11
  • Are you sure the included headers are sufficient, for Linux at least? – alk May 22 '17 at 19:05
  • 2
    S_ISDIR is only for POSIX, not Windows, see [this SO post](https://stackoverflow.com/questions/11238918/s-isreg-macro-undefined) – gezzahead Apr 09 '18 at 08:45
19

You might use stat() and pass it the address of a struct stat, then check its member st_mode for having S_IFDIR set.

#include <stdio.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <unistd.h>

...

char d[] = "mydir";

struct stat s = {0};

if (!stat(d, &s))
  printf("'%s' is %sa directory.\n", d, (s.st_mode & S_IFDIR)  : "" ? "not ");
  // (s.st_mode & S_IFDIR) can be replaced with S_ISDIR(s.st_mode)
else
  perror("stat()");
alk
  • 69,737
  • 10
  • 105
  • 255
  • I was wondering about `S_IFDIR` vs `S_ISDIR` and found this on the `stat` man page: _"POSIX.1-1990 did not describe the S_IFMT, S_IFSOCK, S_IFLNK, S_IFREG, S_IFBLK, S_IFDIR, S_IFCHR, S_IFIFO, S_ISVTX constants, but instead demanded the use of the macros S_ISDIR(), etc. The S_IF* constants are present in POSIX.1-2001 and later."_ – domsson May 25 '21 at 08:28
  • `(s.st_mode & S_IFDIR) : "" ? "not "` You seem to have mixed up the `?` and `:` – user16217248 Aug 06 '21 at 22:28
11

The best way is probably trying to open it, using just opendir() for instance.

Note that it's always best to try to use a filesystem resource, and handling any errors occuring because it doesn't exist, rather than just checking and then later trying. There is an obvious race condition in the latter approach.

unwind
  • 391,730
  • 64
  • 469
  • 606
4

According to man(2)stat you can use the S_ISDIR macro on the st_mode field:

bool isdir = S_ISDIR(st.st_mode);

Side note, I would recommend using Boost and/or Qt4 to make cross-platform support easier if your software can be viable on other OSs.

4

You may also use access in combination with opendir to determine if the directory exists, and, if the name exists, but is not a directory. For example:

#include <sys/stat.h>
#include <dirent.h>
#include <unistd.h>

/* test that dir exists (1 success, -1 does not exist, -2 not dir) */
int
xis_dir (const char *d)
{
    DIR *dirptr;

    if (access ( d, F_OK ) != -1 ) {
        // file exists
        if ((dirptr = opendir (d)) != NULL) {
            closedir (dirptr); /* d exists and is a directory */
        } else {
            return -2; /* d exists but is not a directory */
        }
    } else {
        return -1;     /* d does not exist */
    }

    return 1;
}
pevik
  • 4,523
  • 3
  • 33
  • 44
David C. Rankin
  • 81,885
  • 6
  • 58
  • 85
  • 1
    nice one, but I would change `int xis_dir (char *d)` to `int xis_dir (const char *d)` as d is not modified. – Danny Aug 12 '18 at 08:43