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.
w32-compat
Christopher Wellons 2017-07-11 20:28:10 -04:00
parent 949c649d90
commit ab0ce78a00
1 changed files with 17 additions and 10 deletions

View File

@ -242,8 +242,17 @@ static char *storage_directory(char *file);
#if defined(__unix__) || defined(__APPLE__)
#include <dirent.h>
#include <unistd.h>
#include <sys/stat.h>
#include <sys/types.h>
/* 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, '/');