diff options
Diffstat (limited to 'src/launcherutil.c')
| -rw-r--r-- | src/launcherutil.c | 42 |
1 files changed, 22 insertions, 20 deletions
diff --git a/src/launcherutil.c b/src/launcherutil.c index b31b2df..f7a38fd 100644 --- a/src/launcherutil.c +++ b/src/launcherutil.c @@ -12,6 +12,7 @@ #include <errno.h> #include <sys/stat.h> #include <stdarg.h> +#include <alloca.h> /* handcoded string functions * @@ -44,13 +45,13 @@ char *l2_launcher_sprintf_alloc(const char *fmt, ...) size_t len = vsnprintf(NULL, 0, fmt, pva); va_end(pva); - char *ret = calloc(len, sizeof(char)); + char *ret = calloc(len + 1, sizeof(char)); if (!ret) { return ret; } va_start(pva, fmt); - vsnprintf(ret, len, fmt, pva); + vsnprintf(ret, len + 1, fmt, pva); va_end(pva); return ret; } @@ -129,16 +130,28 @@ int l2_launcher_open_config(const char *path, int flags, mode_t mode) return instfd; } -/* NOTE: There's no portable (or otherwise - see open(2) BUGS) way to do this without race conditions. */ int l2_launcher_mkdir_parents(const char *path) { + return l2_launcher_mkdir_parents_ex(path, 0); +} + +/* NOTE: There's no portable (or otherwise - see open(2) BUGS) way to do this without race conditions. */ +int l2_launcher_mkdir_parents_ex(const char *path, unsigned ignore) +{ if (*path != '/') return -1; - int reserrno = 0; + char *pathbuf; + size_t pathlen; + L2_ASTRDUP(pathbuf, pathlen, path); - char *pathbuf = strdup(path); char *pcurelem = pathbuf; - if (!pathbuf) return -1; + + for (char *cur = pathbuf + pathlen; ignore && cur != pathbuf; --cur) { + if (*cur == '/') { + --ignore; + *cur = '\0'; + } + } struct stat stbuf = { 0 }; @@ -155,29 +168,18 @@ int l2_launcher_mkdir_parents(const char *path) if (errno == EEXIST) { /* racy: stat the file and continue if it is a directory */ if (stat(pathbuf, &stbuf) < 0) { - reserrno = errno; - goto mdcleanup; + return -1; } if (!S_ISDIR(stbuf.st_mode)) { - reserrno = ENOTDIR; - goto mdcleanup; + return -1; } } else { - reserrno = errno; - goto mdcleanup; + return -1; } } } while (pcurelem); -mdcleanup: - - free(pathbuf); - if (reserrno != 0) { - errno = reserrno; - return -1; - } - return 0; } |
