[libglnx] glnx-shutil: Add glnx_shutil_mkdir_p_at_open()



commit 9307f51893702e9bdd2292e46de64e9e5aecb50f
Author: Philip Withnall <withnall endlessm com>
Date:   Thu Apr 20 17:03:24 2017 +0100

    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>

 glnx-shutil.c |   37 +++++++++++++++++++++++++++++++++++++
 glnx-shutil.h |    8 ++++++++
 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


[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]