diff options
| author | Bruce Hill <bruce@bruce-hill.com> | 2024-09-23 14:53:44 -0400 |
|---|---|---|
| committer | Bruce Hill <bruce@bruce-hill.com> | 2024-09-23 14:53:44 -0400 |
| commit | 89c427172a25bdb7802d142c03f3504a53a304fc (patch) | |
| tree | 78fe65ee8a6466649e0aa6ef7aebb31ffc1769fe /stdlib | |
| parent | b432fc82c78bb890eca5938c7754950f089c7abe (diff) | |
Support creating parent directories as needed (mkdir -p) and also set a
better default permission for new dirs
Diffstat (limited to 'stdlib')
| -rw-r--r-- | stdlib/paths.c | 23 |
1 files changed, 21 insertions, 2 deletions
diff --git a/stdlib/paths.c b/stdlib/paths.c index 01228537..0119dbf0 100644 --- a/stdlib/paths.c +++ b/stdlib/paths.c @@ -322,8 +322,27 @@ public void Path$remove(Path_t path, bool ignore_missing) public void Path$create_directory(Path_t path, int permissions) { path = Path$_expand_home(path); - if (mkdir(Text$as_c_string(path), (mode_t)permissions) != 0) - fail("Could not create directory: %k (%s)", &path, strerror(errno)); + char *c_path = Text$as_c_string(path); + char *end = c_path + strlen(c_path); + if (*end == '/' && end > c_path) { + *end = '\0'; + --end; + } + char *end_of_component = strchrnul(c_path + 1, '/'); + for (;;) { + if (end_of_component < end) + *end_of_component = '\0'; + + int status = mkdir(c_path, (mode_t)permissions); + if (status != 0 && errno != EEXIST) + fail("Could not create directory: %s (%s)", c_path, strerror(errno)); + + if (end_of_component >= end) + break; + + *end_of_component = '/'; + end_of_component = strchrnul(end_of_component + 1, '/'); + } } static Array_t _filtered_children(Path_t path, bool include_hidden, mode_t filter) |
