From a522c55155a1e9bbb127cd1880992afcf8c3eece Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Nils=20O=2E=20Sel=C3=A5sdal?= Date: Fri, 30 Jan 2015 20:50:50 +0100 Subject: [PATCH] Finalize mkdirp --- src/mkdirp.c | 74 +++++++++++++++++++++++++++++++++------------------- 1 file changed, 47 insertions(+), 27 deletions(-) diff --git a/src/mkdirp.c b/src/mkdirp.c index 7deed44..009147e 100644 --- a/src/mkdirp.c +++ b/src/mkdirp.c @@ -5,15 +5,40 @@ #include #include + +static int uc_mkdir(const char *full_path, mode_t mode) +{ + struct stat st; + int rc; + int created = 0; + + rc = stat(full_path, &st); + if (rc == -1 && errno == ENOENT) { + rc = mkdir(full_path, mode); + if (rc == -1 && errno != EEXIST) { + return -1; + } + } else if (rc == 0) { + if (!S_ISDIR(st.st_mode)) { + errno = ENOTDIR; + return -1; + } + } else { + return -1; + } + + return 0; +} + int uc_mkdir_p(const char *full_path, mode_t mode) { struct stat st; - int rc = 0; + int rc; char *path; char *p; + int create_final = 1; if (full_path == NULL || full_path[0] == 0) { - errno = EINVAL; return -1; } @@ -24,9 +49,8 @@ int uc_mkdir_p(const char *full_path, mode_t mode) errno = ENOTDIR; return -1; } - if (st.st_mode != (mode | S_IFDIR) && chmod(full_path, mode) != 0) { - return -1; - } + + return 0; } path = strdup(full_path); @@ -46,34 +70,28 @@ int uc_mkdir_p(const char *full_path, mode_t mode) *p = 0; - rc = stat(path, &st); - if (rc != 0) { //doesn't exist - if (mkdir(path, mode) != 0) { - free(path); - return -1; - } - } else if (!S_ISDIR(st.st_mode)) { - errno = ENOTDIR; - free(path); - return -1; - } else { //dir already exist - - if (st.st_mode != (mode | S_IFDIR) && chmod(path, mode) != 0) { - free(path); - return -1; - } + rc = uc_mkdir(path, mode); + if (rc != 0) { + free(path); + return -1; } - //in case of multiple / , e.g. foo//bar *p = '/'; + //in case of multiple / , e.g. foo//bar for (; *p == '/'; p++) ; + + if (*p == 0) { + create_final = 0; + break; + } } //last part, in case full_path does not end with a / - rc = stat(path, &st); - if (rc != 0) { - rc = mkdir(path, mode); + if (create_final) { + rc = uc_mkdir(path, mode); + } else { + rc = 0; } free(path); @@ -82,7 +100,9 @@ int uc_mkdir_p(const char *full_path, mode_t mode) } -int main(int argc, char *argv[]) +int main() { - uc_mkdir_p("a/b//c/d", 0777); + int rc = uc_mkdir_p("/tmp/a///", 0777); + printf("rc = %d\n", rc); } +