@@ -21,61 +21,36 @@ import string;
21
21
import sys_stat local;
22
22
import unistd local;
23
23
24
- fn const char* find_char(const char* full, char delim) {
25
- while (1) {
26
- char c = *full;
27
- if (c == delim) return full;
28
- if (c == 0) break;
29
- full++;
30
- }
31
- return nil;
32
- }
33
-
34
-
35
- // return 0 on succes, -1 otherwise
36
- fn i32 create_dir(const char* path, bool follow) {
37
- i32 err = mkdir(path, 0777);
38
- if (err && errno != EEXIST) return -1;
39
-
40
- if (!follow) return 0;
41
-
42
- i32 fd = openat(AT_FDCWD, path, O_RDONLY|O_NOCTTY|O_NONBLOCK|O_NOFOLLOW|O_DIRECTORY);
43
- if (fd == -1) return errno;
44
-
45
- err = fchdir(fd);
46
- if (err == -1) return -1;
47
-
48
- close(fd);
49
- return 0;
50
- }
51
-
52
24
// returns 0 on success, errno on failure
53
25
public fn i32 create_directory(const char* path) {
54
26
i32 fd = openat(AT_FDCWD, ".", O_RDONLY);
55
27
if (fd == -1) return errno;
56
28
57
- // TODO handle . / .., empty path
58
- char[128] tmp;
29
+ char[256] tmp;
59
30
const char* cp = path;
60
- i32 err = 0;
61
- while (*cp) {
62
- const char* slash = find_char(cp, '/');
63
- // TODO check for empty string (//)
31
+ i32 errno_ = 0;
32
+ if (*cp == '/') {
33
+ cp++;
34
+ if (chdir("/")) errno_ = errno;
35
+ }
36
+ while (!errno_ && *cp) {
37
+ const char* slash = string.strchr(cp, '/');
64
38
if (slash) {
65
39
usize len = cast<usize>(slash - cp);
40
+ assert(len < elemsof(tmp));
66
41
string.memcpy(tmp, cp, len);
67
- tmp[len] = 0 ;
42
+ tmp[len] = '\0' ;
68
43
cp = slash + 1;
69
- err = create_dir(tmp, true);
70
- if (err != 0) break;
44
+ if (!len) continue; // ignore // and trailing slash
45
+ if ((mkdir(tmp, 0777) && errno != EEXIST) || chdir(tmp)) {
46
+ errno_ = errno;
47
+ break;
48
+ }
71
49
} else {
72
- err = create_dir( cp, false) ;
50
+ if (mkdir( cp, 0777) && errno != EEXIST) errno_ = errno ;
73
51
break;
74
52
}
75
53
}
76
- i32 errno_ = 0;
77
- if (err) errno_ = errno;
78
-
79
54
fchdir(fd);
80
55
close(fd);
81
56
return errno_;
0 commit comments