X-Git-Url: http://git.tuebingen.mpg.de/?p=adu.git;a=blobdiff_plain;f=fd.c;h=a4d18a1f8f1684f81564e02084cab2f193756d4a;hp=e1d243e1e8f34006326bdfab72f24455ad801eff;hb=61a9284a7dbcffd2a770135d5f2482ae10459ab9;hpb=4e757d60f7642c61e09a20a2a1de442b23208966 diff --git a/fd.c b/fd.c index e1d243e..a4d18a1 100644 --- a/fd.c +++ b/fd.c @@ -9,9 +9,11 @@ #include #include #include +#include #include "adu.h" #include "error.h" +#include "string.h" /** * Wrapper for the write system call. @@ -122,7 +124,7 @@ out: * * \return Standard. */ -int __chdir(const char *path) +static int __chdir(const char *path) { int ret = chdir(path); @@ -273,3 +275,54 @@ int adu_munmap(void *start, size_t length) strerror(err)); return -ERRNO_TO_ERROR(err); } + +__must_check __malloc static char *adu_dirname(const char *name) +{ + char *p, *ret; + + if (!name || !*name) + return NULL; + ret = adu_strdup(name); + p = strrchr(ret, '/'); + if (!p) + *ret = '\0'; + else + *p = '\0'; + return ret; +} + +/** + * Recursive mkdir + * + * \param p Full path that should be created. + * + * \param mode Use this mode when creating directories. + * + * \return 0 if successful, -E_MKDIR on errors. + */ +int mkpath(const char *p, mode_t mode) +{ + char *parent, *path; + int ret = -E_MKDIR; + + DEBUG_LOG("%s\n", p); + if (strcmp(p, ".") == 0 || strcmp(p, "/") == 0 || strcmp(p, "") == 0) { + DEBUG_LOG("reached beginning of path\n"); + return 0; + } + path = adu_strdup(p); + parent = adu_dirname(p); + if (!parent) + goto out; + ret = mkpath(parent, mode); + if (ret < 0) + goto out; + INFO_LOG("making dir %s\n", path); + ret = 0; + if ((mkdir(path, mode) == -1) && (errno != EEXIST)) + ret = -E_MKDIR; +out: + free(parent); + free(path); + return ret; +}