utils: introduce mkdir_p
authorDaniel Golle <daniel@makrotopia.org>
Sat, 12 Dec 2020 22:45:53 +0000 (22:45 +0000)
committerDaniel Golle <daniel@makrotopia.org>
Sat, 12 Dec 2020 22:50:50 +0000 (22:50 +0000)
Add new utility function mkdir_p(char *path, mode_t mode) to replace
the partially buggy implementations found accross fstools and procd.

Signed-off-by: Daniel Golle <daniel@makrotopia.org>
utils.c
utils.h

diff --git a/utils.c b/utils.c
index c22250d27ec78265b6a5ece8497b26f907cabff1..db632380f908e9da104758de25eed9374694ed72 100644 (file)
--- a/utils.c
+++ b/utils.c
  */
 
 #include <sys/mman.h>
+#include <errno.h>
 #include <stdarg.h>
 #include <stdlib.h>
 #include <stdio.h>
+#include <string.h>
 #include "utils.h"
 
 #define foreach_arg(_arg, _addr, _len, _first_addr, _first_len) \
@@ -155,3 +157,33 @@ void cbuf_free(void *ptr, unsigned int order)
 {
        munmap(ptr, cbuf_size(order) * 2);
 }
+
+int mkdir_p(char *dir, mode_t mask)
+{
+       char *l;
+       int ret;
+
+       ret = mkdir(dir, mask);
+       if (!ret || (ret && errno == EEXIST))
+               return 0;
+
+       if (ret && (errno != ENOENT))
+               return -1;
+
+       l = strrchr(dir, '/');
+       if (!l || l == dir)
+               return -1;
+
+       *l = '\0';
+
+       if (mkdir_p(dir, mask))
+               return -1;
+
+       *l = '/';
+
+       ret = mkdir(dir, mask);
+       if (!ret || (ret && errno == EEXIST))
+               return 0;
+       else
+               return -1;
+}
diff --git a/utils.h b/utils.h
index 27f81e568bf5aa2d5c1bfe8cec883215e29593f1..5c53cc0260d39b00e9bec1a8062356904e0060b1 100644 (file)
--- a/utils.h
+++ b/utils.h
@@ -19,6 +19,7 @@
 #ifndef __LIBUBOX_UTILS_H
 #define __LIBUBOX_UTILS_H
 
+#include <sys/stat.h>
 #include <sys/types.h>
 #include <sys/time.h>
 #include <stdint.h>
@@ -252,5 +253,6 @@ static inline unsigned long cbuf_size(int order)
 
 void *cbuf_alloc(unsigned int order);
 void cbuf_free(void *ptr, unsigned int order);
+int mkdir_p(char *dir, mode_t mask);
 
 #endif