]> git.sur5r.net Git - i3/i3/blob - libi3/mkdirp.c
Add "output" to IPC events referencing a container (#2489)
[i3/i3] / libi3 / mkdirp.c
1 #include "libi3.h"
2 #include <errno.h>
3 #include <stdlib.h>
4 #include <string.h>
5 #include <sys/stat.h>
6
7 /*
8  * Emulates mkdir -p (creates any missing folders)
9  *
10  */
11
12 #if !defined(__sun)
13 int mkdirp(const char *path, mode_t mode) {
14     if (mkdir(path, mode) == 0)
15         return 0;
16     if (errno == EEXIST) {
17         struct stat st;
18         /* Check that the named file actually is a directory. */
19         if (stat(path, &st)) {
20             ELOG("stat(%s) failed: %s\n", path, strerror(errno));
21             return -1;
22         }
23         if (!S_ISDIR(st.st_mode)) {
24             ELOG("mkdir(%s) failed: %s\n", path, strerror(ENOTDIR));
25             return -1;
26         }
27         return 0;
28     } else if (errno != ENOENT) {
29         ELOG("mkdir(%s) failed: %s\n", path, strerror(errno));
30         return -1;
31     }
32     char *copy = sstrdup(path);
33     /* strip trailing slashes, if any */
34     while (copy[strlen(copy) - 1] == '/')
35         copy[strlen(copy) - 1] = '\0';
36
37     char *sep = strrchr(copy, '/');
38     if (sep == NULL) {
39         if (copy != NULL) {
40             free(copy);
41             copy = NULL;
42         }
43         return -1;
44     }
45     *sep = '\0';
46     int result = -1;
47     if (mkdirp(copy, mode) == 0)
48         result = mkdirp(path, mode);
49     free(copy);
50
51     return result;
52 }
53 #endif