diff options
author | David Robillard <d@drobilla.net> | 2020-08-05 23:35:24 +0200 |
---|---|---|
committer | David Robillard <d@drobilla.net> | 2020-08-06 17:34:42 +0200 |
commit | 36af38408e9e5ba2c49738ad08ff2b959bcf7e27 (patch) | |
tree | 973a4c8c1b1603ad9be6e7a075bd5265026d46c1 /src | |
parent | d40f2ca3498592c2ffcb6de82642dfcb5a6f301d (diff) | |
download | lilv-36af38408e9e5ba2c49738ad08ff2b959bcf7e27.tar.gz lilv-36af38408e9e5ba2c49738ad08ff2b959bcf7e27.tar.bz2 lilv-36af38408e9e5ba2c49738ad08ff2b959bcf7e27.zip |
Add lilv_create_temporary_directory()
Diffstat (limited to 'src')
-rw-r--r-- | src/filesystem.c | 40 | ||||
-rw-r--r-- | src/filesystem.h | 11 |
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. |