summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorDavid Robillard <d@drobilla.net>2020-08-05 23:35:24 +0200
committerDavid Robillard <d@drobilla.net>2020-08-06 17:34:42 +0200
commit36af38408e9e5ba2c49738ad08ff2b959bcf7e27 (patch)
tree973a4c8c1b1603ad9be6e7a075bd5265026d46c1
parentd40f2ca3498592c2ffcb6de82642dfcb5a6f301d (diff)
downloadlilv-36af38408e9e5ba2c49738ad08ff2b959bcf7e27.tar.gz
lilv-36af38408e9e5ba2c49738ad08ff2b959bcf7e27.tar.bz2
lilv-36af38408e9e5ba2c49738ad08ff2b959bcf7e27.zip
Add lilv_create_temporary_directory()
-rw-r--r--src/filesystem.c40
-rw-r--r--src/filesystem.h11
2 files changed, 51 insertions, 0 deletions
diff --git a/src/filesystem.c b/src/filesystem.c
index dc72d93..27476ec 100644
--- a/src/filesystem.c
+++ b/src/filesystem.c
@@ -339,6 +339,46 @@ lilv_dir_for_each(const char* path,
#endif
}
+char*
+lilv_create_temporary_directory(const char* pattern)
+{
+#ifdef _WIN32
+ static const char chars[] = "ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789";
+ static const int n_chars = sizeof(chars) - 1;
+
+ const size_t pattern_len = strlen(pattern);
+ if (pattern_len < 7 || strcmp(pattern + pattern_len - 6, "XXXXXX")) {
+ errno = EINVAL;
+ return NULL;
+ }
+
+ char* const tmpdir = lilv_temp_directory_path();
+ char* const path_pattern = lilv_path_join(tmpdir, pattern);
+ const size_t path_pattern_len = strlen(path_pattern);
+ char* const suffix = path_pattern + path_pattern_len - 6;
+
+ free(tmpdir);
+
+ for (unsigned attempt = 0; attempt < 128; ++attempt) {
+ for (unsigned i = 0; i < 6; ++i) {
+ suffix[i] = chars[rand() % n_chars];
+ }
+
+ if (!mkdir(path_pattern, 0700)) {
+ return path_pattern;
+ }
+ }
+
+ return NULL;
+#else
+ char* const tmpdir = lilv_temp_directory_path();
+ char* const path_pattern = lilv_path_join(tmpdir, pattern);
+
+ free(tmpdir);
+ return mkdtemp(path_pattern); // NOLINT (not a leak)
+#endif
+}
+
int
lilv_create_directories(const char* dir_path)
{
diff --git a/src/filesystem.h b/src/filesystem.h
index 09b8b5f..f5ac35c 100644
--- a/src/filesystem.h
+++ b/src/filesystem.h
@@ -129,6 +129,17 @@ lilv_dir_for_each(const char* path,
void (*f)(const char* path, const char* name, void* data));
/**
+ Create a unique temporary directory.
+
+ The last six characters of `pattern` must be `XXXXXX` and will be replaced
+ with random characters. This works roughly like mkdtemp, except the pattern
+ should only be a directory name, not a full path. The returned path will be
+ in a suitable system temporary directory.
+*/
+char*
+lilv_create_temporary_directory(const char* pattern);
+
+/**
Create the directory `dir_path` and any parent directories if necessary.
@return Zero on success, or an `errno` error code.