diff --git a/unix/unix.h b/unix/unix.h index 0e12d042..029d32ff 100644 --- a/unix/unix.h +++ b/unix/unix.h @@ -11,6 +11,7 @@ #include /* Dynamic library loading */ #endif /* NO_LIBDL */ #include "charset.h" +#include /* for mode_t */ #ifdef OSX_GTK /* @@ -197,6 +198,7 @@ void noncloexec(int); int nonblock(int); int no_nonblock(int); char *make_dir_and_check_ours(const char *dirname); +char *make_dir_path(const char *path, mode_t mode); /* * Exports from unicode.c. diff --git a/unix/uxmisc.c b/unix/uxmisc.c index a7a2fcb9..05d741c5 100644 --- a/unix/uxmisc.c +++ b/unix/uxmisc.c @@ -322,3 +322,28 @@ char *make_dir_and_check_ours(const char *dirname) return NULL; } + +char *make_dir_path(const char *path, mode_t mode) +{ + int pos = 0; + char *prefix; + + while (1) { + pos += strcspn(path + pos, "/"); + + if (pos > 0) { + prefix = dupprintf("%.*s", pos, path); + + if (mkdir(prefix, mode) < 0 && errno != EEXIST) { + char *ret = dupprintf("%s: mkdir: %s", + prefix, strerror(errno)); + sfree(prefix); + return ret; + } + } + + if (!path[pos]) + return NULL; + pos += strspn(path + pos, "/"); + } +}