aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorBruce Hill <bruce@bruce-hill.com>2025-11-27 12:05:49 -0500
committerBruce Hill <bruce@bruce-hill.com>2025-11-27 12:07:34 -0500
commit437be558a893ac70c030794df99a866e8ed01879 (patch)
tree63126858e06f14db9e23306d7d9d4c7e25f3f421 /src
parent35053e65b946264715aca2b348ee25313b55d2f6 (diff)
Add `recursive` arg to Path.create_directory()
Diffstat (limited to 'src')
-rw-r--r--src/environment.c3
-rw-r--r--src/modules.c4
-rw-r--r--src/stdlib/paths.c12
-rw-r--r--src/stdlib/paths.h2
4 files changed, 15 insertions, 6 deletions
diff --git a/src/environment.c b/src/environment.c
index 6075ce49..88a15bb5 100644
--- a/src/environment.c
+++ b/src/environment.c
@@ -310,7 +310,8 @@ env_t *global_env(bool source_mapping) {
{"child", "Path$child", "func(path:Path, child:Text -> Path)"}, //
{"children", "Path$children", "func(path:Path, include_hidden=no -> [Path])"}, //
{"concatenated_with", "Path$concat", "func(a,b:Path -> Path)"}, //
- {"create_directory", "Path$create_directory", "func(path:Path, permissions=Int32(0o755))"}, //
+ {"create_directory", "Path$create_directory",
+ "func(path:Path, permissions=Int32(0o755), recursive=yes)"}, //
{"current_dir", "Path$current_dir", "func(->Path)"}, //
{"exists", "Path$exists", "func(path:Path -> Bool)"}, //
{"expand_home", "Path$expand_home", "func(path:Path -> Path)"}, //
diff --git a/src/modules.c b/src/modules.c
index 23b8a0a0..df6bade3 100644
--- a/src/modules.c
+++ b/src/modules.c
@@ -153,10 +153,10 @@ bool try_install_module(module_info_t mod, bool ask_confirmation) {
const char *extension = p + 1;
Path_t tmpdir = Path$unique_directory(Path("/tmp/tomo-module-XXXXXX"));
tmpdir = Path$child(tmpdir, Text$from_str(mod.name));
- Path$create_directory(tmpdir, 0755);
+ Path$create_directory(tmpdir, 0755, true);
xsystem("curl ", mod.url, " -o ", tmpdir);
- Path$create_directory(dest, 0755);
+ Path$create_directory(dest, 0755, true);
if (streq(extension, ".zip")) xsystem("unzip ", tmpdir, "/", filename, " -d ", dest);
else if (streq(extension, ".tar.gz") || streq(extension, ".tar"))
xsystem("tar xf ", tmpdir, "/", filename, " -C ", dest);
diff --git a/src/stdlib/paths.c b/src/stdlib/paths.c
index 22effad7..6c99cf0b 100644
--- a/src/stdlib/paths.c
+++ b/src/stdlib/paths.c
@@ -468,11 +468,19 @@ void Path$remove(Path_t path, bool ignore_missing) {
}
public
-void Path$create_directory(Path_t path, int permissions) {
+void Path$create_directory(Path_t path, int permissions, bool recursive) {
+retry:
path = Path$expand_home(path);
const char *c_path = Path$as_c_string(path);
int status = mkdir(c_path, (mode_t)permissions);
- if (status != 0 && errno != EEXIST) fail("Could not create directory: ", c_path, " (", strerror(errno), ")");
+ if (status != 0) {
+ if (recursive && errno == ENOENT) {
+ Path$create_directory(Path$parent(path), permissions, recursive);
+ goto retry;
+ } else if (errno != EEXIST) {
+ fail("Could not create directory: ", c_path, " (", strerror(errno), ")");
+ }
+ }
}
static List_t _filtered_children(Path_t path, bool include_hidden, mode_t filter) {
diff --git a/src/stdlib/paths.h b/src/stdlib/paths.h
index 3b1f3ce6..677631b2 100644
--- a/src/stdlib/paths.h
+++ b/src/stdlib/paths.h
@@ -41,7 +41,7 @@ void Path$set_owner(Path_t path, OptionalText_t owner, OptionalText_t group, boo
OptionalText_t Path$owner(Path_t path, bool follow_symlinks);
OptionalText_t Path$group(Path_t path, bool follow_symlinks);
void Path$remove(Path_t path, bool ignore_missing);
-void Path$create_directory(Path_t path, int permissions);
+void Path$create_directory(Path_t path, int permissions, bool recursive);
List_t Path$children(Path_t path, bool include_hidden);
List_t Path$files(Path_t path, bool include_hidden);
List_t Path$subdirectories(Path_t path, bool include_hidden);