Recursive dir creation
authorRobert Swiecki <swiecki@google.com>
Thu, 18 Aug 2016 16:59:06 +0000 (18:59 +0200)
committerRobert Swiecki <swiecki@google.com>
Thu, 18 Aug 2016 16:59:06 +0000 (18:59 +0200)
mount.c
util.c
util.h

diff --git a/mount.c b/mount.c
index cd50d7bbdc28153332a475f7c3165e3e3dea6a52..9f6b8e311e94cdb995976aa5be60e52531215cf1 100644 (file)
--- a/mount.c
+++ b/mount.c
@@ -37,6 +37,7 @@
 #include <unistd.h>
 
 #include "log.h"
+#include "util.h"
 
 static bool mountIsDir(const char *path)
 {
@@ -89,12 +90,20 @@ static bool mountMount(struct nsjconf_t *nsjconf, struct mounts_t *mpt, const ch
        }
 
        if (mountIsDir(src) == true) {
+               if (utilCreateDirRecursively(dst) == false) {
+                       LOG_W("Couldn't create upper directories for '%s'", dst);
+                       return false;
+               }
                if (mkdir(dst, 0711) == -1 && errno != EEXIST) {
                        PLOG_W("mkdir('%s')", dst);
                }
        }
 
        if (mountNotIsDir(src) == true) {
+               if (utilCreateDirRecursively(dst) == false) {
+                       LOG_W("Couldn't create upper directories for '%s'", dst);
+                       return false;
+               }
                int fd = TEMP_FAILURE_RETRY(open(dst, O_CREAT | O_RDONLY, 0644));
                if (fd >= 0) {
                        close(fd);
diff --git a/util.c b/util.c
index f154d0c9c6afe79cb44ad7d6d3154de971b5f1ad..0cbca281bd9a047df52e4cd101fc829a27fdfee9 100644 (file)
--- a/util.c
+++ b/util.c
@@ -23,7 +23,9 @@
 
 #include <errno.h>
 #include <fcntl.h>
+#include <stdio.h>
 #include <stdlib.h>
+#include <string.h>
 #include <unistd.h>
 #include <sys/stat.h>
 #include <sys/types.h>
@@ -88,7 +90,7 @@ ssize_t utilWriteToFd(int fd, const void *buf, size_t len)
        return true;
 }
 
-bool utilWriteBufToFile(char *filename, const void *buf, size_t len, int open_flags)
+bool utilWriteBufToFile(const char *filename, const void *buf, size_t len, int open_flags)
 {
        int fd;
        TEMP_FAILURE_RETRY(fd = open(filename, open_flags, 0644));
@@ -109,3 +111,47 @@ bool utilWriteBufToFile(char *filename, const void *buf, size_t len, int open_fl
        close(fd);
        return true;
 }
+
+bool utilCreateDirRecursively(const char *dir)
+{
+       int prev_dir_fd = AT_FDCWD;
+       char path[PATH_MAX];
+       snprintf(path, sizeof(path), "%s", dir);
+
+       char *curr = path;
+       if (*curr == '/') {
+               prev_dir_fd = open("/", O_RDONLY | O_CLOEXEC);
+               if (prev_dir_fd == -1) {
+                       PLOG_E("open('/', O_RDONLY | O_CLOEXEC)");
+                       return false;
+               }
+       }
+
+       for (;;) {
+               while (*curr == '/') {
+                       curr++;
+               }
+
+               char *next = strchr(curr, '/');
+               if (next == NULL) {
+                       close(prev_dir_fd);
+                       return true;
+               }
+               *next = '\0';
+
+               if (mkdirat(prev_dir_fd, curr, 0755) == -1 && errno != EEXIST) {
+                       PLOG_E("mkdir('%s', 0755)", curr);
+                       return false;
+               }
+
+               int dir_fd = openat(prev_dir_fd, curr, O_DIRECTORY | O_CLOEXEC);
+               if (dir_fd == -1) {
+                       PLOG_E("openat('%d', '%s', O_DIRECTORY | O_CLOEXEC)", prev_dir_fd, curr);
+                       close(prev_dir_fd);
+                       return false;
+               }
+               close(prev_dir_fd);
+               prev_dir_fd = dir_fd;
+               curr = next + 1;
+       }
+}
diff --git a/util.h b/util.h
index f1885eb9c49204e08a5c6ace57487cbb4334caaf..b3d64384e3c483cae7960fefc41ffd4da3f6b0f1 100644 (file)
--- a/util.h
+++ b/util.h
@@ -31,6 +31,7 @@ void *utilMalloc(size_t sz);
 ssize_t utilReadFromFd(int fd, void *buf, size_t len);
 ssize_t utilReadFromFile(const char *fname, void *buf, size_t len);
 ssize_t utilWriteToFd(int fd, const void *buf, size_t len);
-bool utilWriteBufToFile(char *filename, const void *buf, size_t len, int open_flags);
+bool utilWriteBufToFile(const char *filename, const void *buf, size_t len, int open_flags);
+bool utilCreateDirRecursively(const char *dir);
 
 #endif                         /* NS_UTIL_H */