summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorPhilip Withnall <withnall@endlessm.com>2017-04-20 17:03:24 +0100
committerPhilip Withnall <withnall@endlessm.com>2017-04-21 14:06:19 +0100
commit9307f51893702e9bdd2292e46de64e9e5aecb50f (patch)
tree4d9a959fbc574e08fd716c2bf959c4db04f3474f
parent2576a07e6e5a400501b126e0c73b042519bb5001 (diff)
downloadlibglnx-9307f51893702e9bdd2292e46de64e9e5aecb50f.tar.gz
glnx-shutil: Add glnx_shutil_mkdir_p_at_open()
This is a variant of glnx_shutil_mkdir_p_at() which opens the given directory and returns a dirfd to it. Currently, the implementation cannot be race-free (due to a kernel bug), but it could eventually be made race-free. Signed-off-by: Philip Withnall <withnall@endlessm.com>
-rw-r--r--glnx-shutil.c37
-rw-r--r--glnx-shutil.h8
2 files changed, 45 insertions, 0 deletions
diff --git a/glnx-shutil.c b/glnx-shutil.c
index 6ff9fa6..4c62ba2 100644
--- a/glnx-shutil.c
+++ b/glnx-shutil.c
@@ -246,3 +246,40 @@ glnx_shutil_mkdir_p_at (int dfd,
out:
return ret;
}
+
+/**
+ * glnx_shutil_mkdir_p_at_open:
+ * @dfd: Directory fd
+ * @path: Directory path to be created
+ * @mode: Mode for newly created directories
+ * @out_dfd: (out caller-allocates): Return location for an FD to @dfd/@path,
+ * or `-1` on error
+ * @cancellable: (nullable): Cancellable, or %NULL
+ * @error: Return location for a #GError, or %NULL
+ *
+ * Similar to glnx_shutil_mkdir_p_at(), except it opens the resulting directory
+ * and returns a directory FD to it. Currently, this is not guaranteed to be
+ * race-free.
+ *
+ * Returns: %TRUE on success, %FALSE otherwise
+ * Since: UNRELEASED
+ */
+gboolean
+glnx_shutil_mkdir_p_at_open (int dfd,
+ const char *path,
+ int mode,
+ int *out_dfd,
+ GCancellable *cancellable,
+ GError **error)
+{
+ /* FIXME: It’s not possible to eliminate the race here until
+ * openat(O_DIRECTORY | O_CREAT) works (and returns a directory rather than a
+ * file). It appears to be not supported in current kernels. (Tested with
+ * 4.10.10-200.fc25.x86_64.) */
+ *out_dfd = -1;
+
+ if (!glnx_shutil_mkdir_p_at (dfd, path, mode, cancellable, error))
+ return FALSE;
+
+ return glnx_opendirat (dfd, path, TRUE, out_dfd, error);
+}
diff --git a/glnx-shutil.h b/glnx-shutil.h
index 8cc732c..56a99fa 100644
--- a/glnx-shutil.h
+++ b/glnx-shutil.h
@@ -37,4 +37,12 @@ glnx_shutil_mkdir_p_at (int dfd,
GCancellable *cancellable,
GError **error);
+gboolean
+glnx_shutil_mkdir_p_at_open (int dfd,
+ const char *path,
+ int mode,
+ int *out_dfd,
+ GCancellable *cancellable,
+ GError **error);
+
G_END_DECLS