aboutsummaryrefslogtreecommitdiff
path: root/common.c
diff options
context:
space:
mode:
Diffstat (limited to 'common.c')
-rw-r--r--common.c43
1 files changed, 43 insertions, 0 deletions
diff --git a/common.c b/common.c
index 8470171..0d34591 100644
--- a/common.c
+++ b/common.c
@@ -54,6 +54,49 @@ str_vector_find (const struct str_vector *v, const char *s)
return -1;
}
+/// This differs from the non-unique version in that we expect the filename
+/// to be something like a pattern for mkstemp(), so the resulting path can
+/// reside in a system-wide directory with no risk of a conflict.
+static char *
+resolve_relative_runtime_unique_filename (const char *filename)
+{
+ struct str path;
+ str_init (&path);
+
+ const char *runtime_dir = getenv ("XDG_RUNTIME_DIR");
+ if (runtime_dir && *runtime_dir == '/')
+ str_append (&path, runtime_dir);
+ else
+ str_append (&path, "/tmp");
+ str_append_printf (&path, "/%s/%s", PROGRAM_NAME, filename);
+
+ // Try to create the file's ancestors;
+ // typically the user will want to immediately create a file in there
+ const char *last_slash = strrchr (path.str, '/');
+ if (last_slash && last_slash != path.str)
+ {
+ char *copy = xstrndup (path.str, last_slash - path.str);
+ (void) mkdir_with_parents (copy, NULL);
+ free (copy);
+ }
+ return str_steal (&path);
+}
+
+static bool
+xwrite (int fd, const char *data, size_t len, struct error **e)
+{
+ size_t written = 0;
+ while (written < len)
+ {
+ ssize_t res = write (fd, data + written, len - written);
+ if (res >= 0)
+ written += res;
+ else if (errno != EINTR)
+ FAIL ("%s", strerror (errno));
+ }
+ return true;
+}
+
// --- Logging -----------------------------------------------------------------
static void