util: when creating temporary file names, allow including extra id string in it
authorLennart Poettering <lennart@poettering.net>
Mon, 15 Jun 2015 17:09:02 +0000 (19:09 +0200)
committerLennart Poettering <lennart@poettering.net>
Mon, 15 Jun 2015 17:28:55 +0000 (19:28 +0200)
This adds a "char *extra" parameter to tempfn_xxxxxx(), tempfn_random(),
tempfn_ranomd_child(). If non-NULL this string is included in the middle
of the newly created file name. This is useful for being able to
distuingish the kind of temporary file when we see one.

This also adds tests for the three call.

For now, we don't make use of this at all, but port all users over.

15 files changed:
src/basic/copy.c
src/basic/util.c
src/basic/util.h
src/import/export-raw.c
src/import/export-tar.c
src/import/import-raw.c
src/import/import-tar.c
src/import/pull-dkr.c
src/import/pull-raw.c
src/import/pull-tar.c
src/journal/coredump.c
src/nspawn/nspawn.c
src/shared/machine-pool.c
src/systemctl/systemctl.c
src/test/test-util.c

index 1282cb8..230e7e4 100644 (file)
@@ -396,7 +396,7 @@ int copy_file_atomic(const char *from, const char *to, mode_t mode, bool replace
         assert(from);
         assert(to);
 
-        r = tempfn_random(to, &t);
+        r = tempfn_random(to, NULL, &t);
         if (r < 0)
                 return r;
 
index 6f6906f..b7c70af 100644 (file)
@@ -2521,7 +2521,7 @@ int fopen_temporary(const char *path, FILE **_f, char **_temp_path) {
         assert(_f);
         assert(_temp_path);
 
-        r = tempfn_xxxxxx(path, &t);
+        r = tempfn_xxxxxx(path, NULL, &t);
         if (r < 0)
                 return r;
 
@@ -2551,7 +2551,7 @@ int symlink_atomic(const char *from, const char *to) {
         assert(from);
         assert(to);
 
-        r = tempfn_random(to, &t);
+        r = tempfn_random(to, NULL, &t);
         if (r < 0)
                 return r;
 
@@ -2594,7 +2594,7 @@ int mknod_atomic(const char *path, mode_t mode, dev_t dev) {
 
         assert(path);
 
-        r = tempfn_random(path, &t);
+        r = tempfn_random(path, NULL, &t);
         if (r < 0)
                 return r;
 
@@ -2615,7 +2615,7 @@ int mkfifo_atomic(const char *path, mode_t mode) {
 
         assert(path);
 
-        r = tempfn_random(path, &t);
+        r = tempfn_random(path, NULL, &t);
         if (r < 0)
                 return r;
 
@@ -4969,7 +4969,7 @@ int fflush_and_check(FILE *f) {
         return 0;
 }
 
-int tempfn_xxxxxx(const char *p, char **ret) {
+int tempfn_xxxxxx(const char *p, const char *extra, char **ret) {
         const char *fn;
         char *t;
 
@@ -4981,24 +4981,27 @@ int tempfn_xxxxxx(const char *p, char **ret) {
          *         /foo/bar/waldo
          *
          * Into this:
-         *         /foo/bar/.#waldoXXXXXX
+         *         /foo/bar/.#<extra>waldoXXXXXX
          */
 
         fn = basename(p);
         if (!filename_is_valid(fn))
                 return -EINVAL;
 
-        t = new(char, strlen(p) + 2 + 6 + 1);
+        if (extra == NULL)
+                extra = "";
+
+        t = new(char, strlen(p) + 2 + strlen(extra) + 6 + 1);
         if (!t)
                 return -ENOMEM;
 
-        strcpy(stpcpy(stpcpy(mempcpy(t, p, fn - p), ".#"), fn), "XXXXXX");
+        strcpy(stpcpy(stpcpy(stpcpy(mempcpy(t, p, fn - p), ".#"), extra), fn), "XXXXXX");
 
         *ret = path_kill_slashes(t);
         return 0;
 }
 
-int tempfn_random(const char *p, char **ret) {
+int tempfn_random(const char *p, const char *extra, char **ret) {
         const char *fn;
         char *t, *x;
         uint64_t u;
@@ -5012,18 +5015,21 @@ int tempfn_random(const char *p, char **ret) {
          *         /foo/bar/waldo
          *
          * Into this:
-         *         /foo/bar/.#waldobaa2a261115984a9
+         *         /foo/bar/.#<extra>waldobaa2a261115984a9
          */
 
         fn = basename(p);
         if (!filename_is_valid(fn))
                 return -EINVAL;
 
-        t = new(char, strlen(p) + 2 + 16 + 1);
+        if (!extra)
+                extra = "";
+
+        t = new(char, strlen(p) + 2 + strlen(extra) + 16 + 1);
         if (!t)
                 return -ENOMEM;
 
-        x = stpcpy(stpcpy(mempcpy(t, p, fn - p), ".#"), fn);
+        x = stpcpy(stpcpy(stpcpy(mempcpy(t, p, fn - p), ".#"), extra), fn);
 
         u = random_u64();
         for (i = 0; i < 16; i++) {
@@ -5037,7 +5043,7 @@ int tempfn_random(const char *p, char **ret) {
         return 0;
 }
 
-int tempfn_random_child(const char *p, char **ret) {
+int tempfn_random_child(const char *p, const char *extra, char **ret) {
         char *t, *x;
         uint64_t u;
         unsigned i;
@@ -5048,14 +5054,17 @@ int tempfn_random_child(const char *p, char **ret) {
         /* Turns this:
          *         /foo/bar/waldo
          * Into this:
-         *         /foo/bar/waldo/.#3c2b6219aa75d7d0
+         *         /foo/bar/waldo/.#<extra>3c2b6219aa75d7d0
          */
 
-        t = new(char, strlen(p) + 3 + 16 + 1);
+        if (!extra)
+                extra = "";
+
+        t = new(char, strlen(p) + 3 + strlen(extra) + 16 + 1);
         if (!t)
                 return -ENOMEM;
 
-        x = stpcpy(stpcpy(t, p), "/.#");
+        x = stpcpy(stpcpy(stpcpy(t, p), "/.#"), extra);
 
         u = random_u64();
         for (i = 0; i < 16; i++) {
index 467ae23..7aca46d 100644 (file)
@@ -828,9 +828,9 @@ int bind_remount_recursive(const char *prefix, bool ro);
 
 int fflush_and_check(FILE *f);
 
-int tempfn_xxxxxx(const char *p, char **ret);
-int tempfn_random(const char *p, char **ret);
-int tempfn_random_child(const char *p, char **ret);
+int tempfn_xxxxxx(const char *p, const char *extra, char **ret);
+int tempfn_random(const char *p, const char *extra, char **ret);
+int tempfn_random_child(const char *p, const char *extra, char **ret);
 
 int take_password_lock(const char *root);
 
index 4b6d8da..8f9c9bb 100644 (file)
@@ -265,7 +265,7 @@ static int reflink_snapshot(int fd, const char *path) {
         if (new_fd < 0) {
                 _cleanup_free_ char *t = NULL;
 
-                r = tempfn_random(path, &t);
+                r = tempfn_random(path, NULL, &t);
                 if (r < 0)
                         return r;
 
index d312957..5adc748 100644 (file)
@@ -290,7 +290,7 @@ int tar_export_start(TarExport *e, const char *path, int fd, ImportCompressType
                 free(e->temp_path);
                 e->temp_path = NULL;
 
-                r = tempfn_random(path, &e->temp_path);
+                r = tempfn_random(path, NULL, &e->temp_path);
                 if (r < 0)
                         return r;
 
index 97e1254..43cd413 100644 (file)
@@ -180,7 +180,7 @@ static int raw_import_maybe_convert_qcow2(RawImport *i) {
                 return 0;
 
         /* This is a QCOW2 image, let's convert it */
-        r = tempfn_random(i->final_path, &t);
+        r = tempfn_random(i->final_path, NULL, &t);
         if (r < 0)
                 return log_oom();
 
@@ -267,7 +267,7 @@ static int raw_import_open_disk(RawImport *i) {
         if (!i->final_path)
                 return log_oom();
 
-        r = tempfn_random(i->final_path, &i->temp_path);
+        r = tempfn_random(i->final_path, NULL, &i->temp_path);
         if (r < 0)
                 return log_oom();
 
index 12701bf..2bf0b06 100644 (file)
@@ -223,7 +223,7 @@ static int tar_import_fork_tar(TarImport *i) {
         if (!i->final_path)
                 return log_oom();
 
-        r = tempfn_random(i->final_path, &i->temp_path);
+        r = tempfn_random(i->final_path, NULL, &i->temp_path);
         if (r < 0)
                 return log_oom();
 
index d7476dc..78e3184 100644 (file)
@@ -520,7 +520,7 @@ static int dkr_pull_job_on_open_disk(PullJob *j) {
         assert(!i->temp_path);
         assert(i->tar_pid <= 0);
 
-        r = tempfn_random(i->final_path, &i->temp_path);
+        r = tempfn_random(i->final_path, NULL, &i->temp_path);
         if (r < 0)
                 return log_oom();
 
index b65bb0c..5bfaf01 100644 (file)
@@ -208,7 +208,7 @@ static int raw_pull_maybe_convert_qcow2(RawPull *i) {
                 return 0;
 
         /* This is a QCOW2 image, let's convert it */
-        r = tempfn_random(i->final_path, &t);
+        r = tempfn_random(i->final_path, NULL, &t);
         if (r < 0)
                 return log_oom();
 
@@ -280,7 +280,7 @@ static int raw_pull_make_local_copy(RawPull *i) {
         if (i->force_local)
                 (void) rm_rf(p, REMOVE_ROOT|REMOVE_PHYSICAL|REMOVE_SUBVOLUME);
 
-        r = tempfn_random(p, &tp);
+        r = tempfn_random(p, NULL, &tp);
         if (r < 0)
                 return log_oom();
 
@@ -424,7 +424,7 @@ static int raw_pull_job_on_open_disk(PullJob *j) {
         if (r < 0)
                 return log_oom();
 
-        r = tempfn_random(i->final_path, &i->temp_path);
+        r = tempfn_random(i->final_path, NULL, &i->temp_path);
         if (r < 0)
                 return log_oom();
 
index 27a9af8..a6605d2 100644 (file)
@@ -324,7 +324,7 @@ static int tar_pull_job_on_open_disk(PullJob *j) {
         if (r < 0)
                 return log_oom();
 
-        r = tempfn_random(i->final_path, &i->temp_path);
+        r = tempfn_random(i->final_path, NULL, &i->temp_path);
         if (r < 0)
                 return log_oom();
 
index 1c747aa..62483a2 100644 (file)
@@ -301,7 +301,7 @@ static int save_external_coredump(
         if (r < 0)
                 return log_error_errno(r, "Failed to determine coredump file name: %m");
 
-        r = tempfn_random(fn, &tmp);
+        r = tempfn_random(fn, NULL, &tmp);
         if (r < 0)
                 return log_error_errno(r, "Failed to determine temporary file name: %m");
 
@@ -347,7 +347,7 @@ static int save_external_coredump(
                         goto uncompressed;
                 }
 
-                r = tempfn_random(fn_compressed, &tmp_compressed);
+                r = tempfn_random(fn_compressed, NULL, &tmp_compressed);
                 if (r < 0) {
                         log_error_errno(r, "Failed to determine temporary file name for %s: %m", fn_compressed);
                         goto uncompressed;
index c87956b..7b22b8c 100644 (file)
@@ -350,7 +350,7 @@ static int custom_mounts_prepare(void) {
                 if (m->read_only)
                         continue;
 
-                r = tempfn_random(m->source, &m->work_dir);
+                r = tempfn_random(m->source, NULL, &m->work_dir);
                 if (r < 0)
                         return log_error_errno(r, "Failed to generate work directory from %s: %m", m->source);
         }
@@ -4522,9 +4522,9 @@ int main(int argc, char *argv[]) {
                                 goto finish;
                         }
                         if (r > 0)
-                                r = tempfn_random_child(arg_directory, &np);
+                                r = tempfn_random_child(arg_directory, NULL, &np);
                         else
-                                r = tempfn_random(arg_directory, &np);
+                                r = tempfn_random(arg_directory, NULL, &np);
                         if (r < 0) {
                                 log_error_errno(r, "Failed to generate name for snapshot: %m");
                                 goto finish;
index 8c64908..8af78f4 100644 (file)
@@ -75,7 +75,7 @@ static int setup_machine_raw(uint64_t size, sd_bus_error *error) {
         if (errno != ENOENT)
                 return sd_bus_error_set_errnof(error, errno, "Failed to open /var/lib/machines.raw: %m");
 
-        r = tempfn_xxxxxx("/var/lib/machines.raw", &tmp);
+        r = tempfn_xxxxxx("/var/lib/machines.raw", NULL, &tmp);
         if (r < 0)
                 return r;
 
index a2eb435..40bea87 100644 (file)
@@ -5687,7 +5687,7 @@ static int create_edit_temp_file(const char *new_path, const char *original_path
         assert(original_path);
         assert(ret_tmp_fn);
 
-        r = tempfn_random(new_path, &t);
+        r = tempfn_random(new_path, NULL, &t);
         if (r < 0)
                 return log_error_errno(r, "Failed to determine temporary filename for \"%s\": %m", new_path);
 
index 9d5516a..ed8db45 100644 (file)
@@ -1507,6 +1507,42 @@ static void test_parse_mode(void) {
         assert_se(parse_mode("0", &m) >= 0 && m == 0);
 }
 
+static void test_tempfn(void) {
+        char *ret = NULL, *p;
+
+        assert_se(tempfn_xxxxxx("/foo/bar/waldo", NULL, &ret) >= 0);
+        assert_se(streq_ptr(ret, "/foo/bar/.#waldoXXXXXX"));
+        free(ret);
+
+        assert_se(tempfn_xxxxxx("/foo/bar/waldo", "[miau]", &ret) >= 0);
+        assert_se(streq_ptr(ret, "/foo/bar/.#[miau]waldoXXXXXX"));
+        free(ret);
+
+        assert_se(tempfn_random("/foo/bar/waldo", NULL, &ret) >= 0);
+        assert_se(p = startswith(ret, "/foo/bar/.#waldo"));
+        assert_se(strlen(p) == 16);
+        assert_se(in_charset(p, "0123456789abcdef"));
+        free(ret);
+
+        assert_se(tempfn_random("/foo/bar/waldo", "[wuff]", &ret) >= 0);
+        assert_se(p = startswith(ret, "/foo/bar/.#[wuff]waldo"));
+        assert_se(strlen(p) == 16);
+        assert_se(in_charset(p, "0123456789abcdef"));
+        free(ret);
+
+        assert_se(tempfn_random_child("/foo/bar/waldo", NULL, &ret) >= 0);
+        assert_se(p = startswith(ret, "/foo/bar/waldo/.#"));
+        assert_se(strlen(p) == 16);
+        assert_se(in_charset(p, "0123456789abcdef"));
+        free(ret);
+
+        assert_se(tempfn_random_child("/foo/bar/waldo", "[kikiriki]", &ret) >= 0);
+        assert_se(p = startswith(ret, "/foo/bar/waldo/.#[kikiriki]"));
+        assert_se(strlen(p) == 16);
+        assert_se(in_charset(p, "0123456789abcdef"));
+        free(ret);
+}
+
 int main(int argc, char *argv[]) {
         log_parse_environment();
         log_open();
@@ -1582,6 +1618,7 @@ int main(int argc, char *argv[]) {
         test_sparse_write();
         test_shell_maybe_quote();
         test_parse_mode();
+        test_tempfn();
 
         return 0;
 }