From ab0ce78a00e85b7a8644cdb2a874c332f7119fab Mon Sep 17 00:00:00 2001 From: Christopher Wellons Date: Tue, 11 Jul 2017 20:28:10 -0400 Subject: [PATCH] Before mkdir(2), check if directory exists. On Cygwin, mkdir(2) reports EACCES if the directory exists but the system call would have failed had it not existed. This is a little odd since EEXIST would be a much more sensible error code, but this odd behavior seems to be permitted by POSIX. If mkdir(2) fails, but the path exists as a directory, then continue as normal. --- src/enchive.c | 27 +++++++++++++++++---------- 1 file changed, 17 insertions(+), 10 deletions(-) diff --git a/src/enchive.c b/src/enchive.c index e527904..ae78b03 100644 --- a/src/enchive.c +++ b/src/enchive.c @@ -242,8 +242,17 @@ static char *storage_directory(char *file); #if defined(__unix__) || defined(__APPLE__) #include #include +#include #include +/* Return non-zero if path exists and is a directory. */ +static int +dir_exists(const char *path) +{ + struct stat info; + return !stat(path, &info) && S_ISDIR(info.st_mode); +} + /* Use $XDG_CONFIG_HOME/enchive, or $HOME/.config/enchive. */ static char * storage_directory(char *file) @@ -282,16 +291,14 @@ storage_directory(char *file) s = strchr(path + 1, '/'); while (s) { *s = 0; - if (mkdir(path, 0700)) { - if (errno == EEXIST) { - DIR *dir = opendir(path); - if (dir) - closedir(dir); - else - fatal("%s -- %s", path, strerror(errno)); - } else { - fatal("%s -- %s", path, strerror(errno)); - } + if (dir_exists(path) || !mkdir(path, 0700)) { + DIR *dir = opendir(path); + if (dir) + closedir(dir); + else + fatal("opendir(%s) -- %s", path, strerror(errno)); + } else { + fatal("mkdir(%s) -- %s", path, strerror(errno)); } *s = '/'; s = strchr(s + 1, '/');