-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathmkdir.c
More file actions
64 lines (57 loc) · 1.61 KB
/
mkdir.c
File metadata and controls
64 lines (57 loc) · 1.61 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
#include <errno.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/stat.h>
#include <unistd.h>
int main(int argc, char **argv) {
int parents = 0;
int opt;
while ((opt = getopt(argc, argv, "p")) != -1) {
if (opt == 'p')
parents = 1;
else {
fprintf(stderr, "usage: %s [-p] <dir>\n", argv[0]);
return EXIT_FAILURE;
}
}
if ((argc - optind) != 1) {
fprintf(stderr, "usage: %s [-p] <dir>\n", argv[0]);
return EXIT_FAILURE;
}
const char *dir = argv[optind];
size_t dirlen = strlen(dir);
struct stat st;
for (size_t i = 1; parents && (i + 1) < dirlen; i++) {
if (dir[i] != '/')
continue;
char *partial = malloc((i + 1) * sizeof(char));
memcpy(partial, dir, i);
partial[i] = '\0';
if (mkdir(partial, 0777) >= 0) {
// mkdir ok, pass
} else if (errno != EEXIST) {
// mkdir error
fprintf(stderr, "(%s: cannot make '%s': %s)\n", argv[0], partial,
strerror(errno));
return EXIT_FAILURE;
} else if (stat(partial, &st) < 0) {
// stat error
fprintf(stderr, "(%s: cannot stat '%s': %s)\n", argv[0], partial,
strerror(errno));
return EXIT_FAILURE;
} else if (!S_ISDIR(st.st_mode)) {
// mkdir EEXIST and stat is not directory
fprintf(stderr, "(%s: cannot make '%s': %s)\n", argv[0], partial,
strerror(ENOTDIR));
return EXIT_FAILURE;
}
free(partial);
}
if (mkdir(dir, 0777) < 0) {
fprintf(stderr, "(%s: cannot make '%s': %s)\n", argv[0], dir,
strerror(errno));
return EXIT_FAILURE;
}
return EXIT_SUCCESS;
}