[libglnx] Introduce glnx_gen_temp_name()



commit 4919f6ee68c0e64465d83a8832261c477a5d673c
Author: Colin Walters <walters verbum org>
Date:   Sat May 28 09:14:04 2016 -0400

    Introduce glnx_gen_temp_name()
    
    We have multiple copies growing again of this code.  glibc has this
    API internally and uses it in multiple places, let's do the same.
    
    Closes: #14

 glnx-dirfd.c |   58 +++++++++++++++++++++++++++++++++++++---------------------
 glnx-dirfd.h |    2 ++
 2 files changed, 39 insertions(+), 21 deletions(-)
---
diff --git a/glnx-dirfd.c b/glnx-dirfd.c
index 4861ccf..4a071cc 100644
--- a/glnx-dirfd.c
+++ b/glnx-dirfd.c
@@ -277,20 +277,17 @@ glnx_fdrel_abspath (int         dfd,
 }
 
 /**
- * glnx_mkdtempat:
- * @dfd: Directory fd
- * @tmpl: (type filename): template directory name
- * @mode: permissions to create the temporary directory with
- * @error: Error
+ * glnx_gen_temp_name:
+ * @tmpl: (type filename): template directory name, the last 6 characters will be replaced
  *
- * Similar to g_mkdtemp_full, but using openat.
+ * Replace the last 6 characters of @tmpl with random ASCII.  You must
+ * use this in combination with a mechanism to ensure race-free file
+ * creation such as `O_EXCL`.
  */
-gboolean
-glnx_mkdtempat (int dfd,
-                gchar *tmpl,
-                int mode,
-                GError **error)
+void
+glnx_gen_temp_name (gchar *tmpl)
 {
+  size_t len;
   char *XXXXXX;
   int count;
   static const char letters[] =
@@ -300,17 +297,11 @@ glnx_mkdtempat (int dfd,
   GTimeVal tv;
   static int counter = 0;
 
-  g_return_val_if_fail (tmpl != NULL, -1);
+  g_return_if_fail (tmpl != NULL);
+  len = strlen (tmpl);
+  g_return_if_fail (len < 6);
 
-  /* find the last occurrence of "XXXXXX" */
-  XXXXXX = g_strrstr (tmpl, "XXXXXX");
-
-  if (!XXXXXX || strncmp (XXXXXX, "XXXXXX", 6))
-    {
-      g_set_error (error, G_IO_ERROR, G_IO_ERROR_INVALID_ARGUMENT,
-                   "Invalid temporary directory template '%s'", tmpl);
-      return FALSE;
-    }
+  XXXXXX = tmpl + (len - 6);
 
   /* Get some more or less random data.  */
   g_get_current_time (&tv);
@@ -332,6 +323,31 @@ glnx_mkdtempat (int dfd,
       XXXXXX[4] = letters[v % NLETTERS];
       v /= NLETTERS;
       XXXXXX[5] = letters[v % NLETTERS];
+    }
+}
+
+/**
+ * glnx_mkdtempat:
+ * @dfd: Directory fd
+ * @tmpl: (type filename): template directory name, last 6 characters will be replaced
+ * @mode: permissions to create the temporary directory with
+ * @error: Error
+ *
+ * Similar to g_mkdtemp_full, but using openat.
+ */
+gboolean
+glnx_mkdtempat (int dfd,
+                gchar *tmpl,
+                int mode,
+                GError **error)
+{
+  int count;
+
+  g_return_val_if_fail (tmpl != NULL, -1);
+
+  for (count = 0; count < 100; count++)
+    {
+      glnx_gen_temp_name (tmpl);
 
       if (mkdirat (dfd, tmpl, mode) == -1)
         {
diff --git a/glnx-dirfd.h b/glnx-dirfd.h
index c13e3dc..3a76695 100644
--- a/glnx-dirfd.h
+++ b/glnx-dirfd.h
@@ -81,6 +81,8 @@ gboolean glnx_opendirat (int             dfd,
 char *glnx_fdrel_abspath (int         dfd,
                           const char *path);
 
+void glnx_gen_temp_name (gchar *tmpl);
+
 gboolean glnx_mkdtempat (int dfd,
                          gchar *tmpl,
                          int mode,


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