00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017 #include <unistd.h>
00018 #include <errno.h>
00019 #include <sys/stat.h>
00020
00021 #include "misc.h"
00022 #include "open.h"
00023 #include "str.h"
00024 #include "strtok.h"
00025
00026 int mkdirp(const char *path, mode_t mode)
00027 {
00028 int ok = 1;
00029 struct stat sb;
00030
00031 if (str_isempty(path) || str_path_isdot(path))
00032 return errno = EINVAL, -1;
00033
00034 strtok_t _st, *st = &_st, *p;
00035
00036 int curdir = open_read(".");
00037
00038 if (curdir == -1)
00039 return -1;
00040
00041 if (!strtok_init_str(st, path, "/", 0))
00042 return -1;
00043
00044 strtok_for_each(st, p) {
00045 if (mkdir(p->token, 0755) == -1) {
00046 if (errno != EEXIST || stat(p->token, &sb) == -1) {
00047 ok = 0;
00048 break;
00049 }
00050
00051 if (!S_ISDIR(sb.st_mode)) {
00052 errno = ENOTDIR;
00053 ok = 0;
00054 break;
00055 }
00056 }
00057
00058 if (chdir(p->token) == -1) {
00059 ok = 0;
00060 break;
00061 }
00062 }
00063
00064 if (ok && chmod(".", mode) == -1)
00065 ok = 0;
00066
00067 fchdir(curdir);
00068 close(curdir);
00069
00070 strtok_free(st);
00071 return ok ? 0 : -1;
00072 }