Add mkdir_recursive function to libcommon utils
authorDavid Goulet <dgoulet@efficios.com>
Wed, 23 Jan 2013 17:25:24 +0000 (12:25 -0500)
committerDavid Goulet <dgoulet@efficios.com>
Wed, 23 Jan 2013 17:25:24 +0000 (12:25 -0500)
src/common/utils.c
src/common/utils.h

index 2f114934fd78c654a43a9b5563f6929bc7422ec6..d8cb4a60f1574a936fab23bcf3a9535b2875a136 100644 (file)
@@ -22,6 +22,9 @@
 #include <limits.h>
 #include <stdlib.h>
 #include <string.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <unistd.h>
 
 #include <common/common.h>
 
@@ -232,3 +235,69 @@ int utils_create_pid_file(pid_t pid, const char *filepath)
 error:
        return ret;
 }
+
+/*
+ * Recursively create directory using the given path and mode.
+ *
+ * On success, return 0 else a negative error code.
+ */
+__attribute__((visibility("hidden")))
+int utils_mkdir_recursive(const char *path, mode_t mode)
+{
+       char *p, tmp[PATH_MAX];
+       struct stat statbuf;
+       size_t len;
+       int ret;
+
+       assert(path);
+
+       ret = snprintf(tmp, sizeof(tmp), "%s", path);
+       if (ret < 0) {
+               PERROR("snprintf mkdir");
+               goto error;
+       }
+
+       len = ret;
+       if (tmp[len - 1] == '/') {
+               tmp[len - 1] = 0;
+       }
+
+       for (p = tmp + 1; *p; p++) {
+               if (*p == '/') {
+                       *p = 0;
+                       if (tmp[strlen(tmp) - 1] == '.' &&
+                                       tmp[strlen(tmp) - 2] == '.' &&
+                                       tmp[strlen(tmp) - 3] == '/') {
+                               ERR("Using '/../' is not permitted in the trace path (%s)",
+                                               tmp);
+                               ret = -1;
+                               goto error;
+                       }
+                       ret = stat(tmp, &statbuf);
+                       if (ret < 0) {
+                               ret = mkdir(tmp, mode);
+                               if (ret < 0) {
+                                       if (errno != EEXIST) {
+                                               PERROR("mkdir recursive");
+                                               ret = -errno;
+                                               goto error;
+                                       }
+                               }
+                       }
+                       *p = '/';
+               }
+       }
+
+       ret = mkdir(tmp, mode);
+       if (ret < 0) {
+               if (errno != EEXIST) {
+                       PERROR("mkdir recursive last piece");
+                       ret = -errno;
+               } else {
+                       ret = 0;
+               }
+       }
+
+error:
+       return ret;
+}
index 95e1b670732a7d0f0c70a5b0893ba3837b1de91a..f63e84e5b098dd5f5d658545d04d7d15c7ef64a3 100644 (file)
@@ -25,5 +25,6 @@ void utils_close_pipe(int *src);
 char *utils_strdupdelim(const char *begin, const char *end);
 int utils_set_fd_cloexec(int fd);
 int utils_create_pid_file(pid_t pid, const char *filepath);
+int utils_mkdir_recursive(const char *path, mode_t mode);
 
 #endif /* _COMMON_UTILS_H */
This page took 0.026475 seconds and 4 git commands to generate.