From e55fd8ee318b858c8fadd223157d60952746200f Mon Sep 17 00:00:00 2001
From: Colin Walters <walters@verbum.org>
Date: Tue, 27 Jun 2017 21:09:53 -0400
Subject: [PATCH] fdio: Introduce glnx_open_anonymous_tmpfile()

There was a user of this in the libostree static delta code.
---
 glnx-fdio.c | 23 +++++++++++++++++++++++
 glnx-fdio.h |  6 ++++++
 2 files changed, 29 insertions(+)

diff --git a/glnx-fdio.c b/glnx-fdio.c
index ad43e61d7..c8da35e87 100644
--- a/glnx-fdio.c
+++ b/glnx-fdio.c
@@ -244,6 +244,27 @@ glnx_open_tmpfile_linkable_at (int dfd,
   return FALSE;
 }
 
+/* A variant of `glnx_open_tmpfile_linkable_at()` which doesn't support linking.
+ * Useful for true temporary storage. The fd will be allocated in /var/tmp to
+ * ensure maximum storage space.
+ */
+gboolean
+glnx_open_anonymous_tmpfile (int          flags,
+                             GLnxTmpfile *out_tmpf,
+                             GError     **error)
+{
+  if (!glnx_open_tmpfile_linkable_at (AT_FDCWD, "/var/tmp", flags, out_tmpf, error))
+    return FALSE;
+  if (out_tmpf->path)
+    {
+      (void) unlinkat (out_tmpf->src_dfd, out_tmpf->path, 0);
+      g_clear_pointer (&out_tmpf->path, g_free);
+    }
+  out_tmpf->anonymous = TRUE;
+  out_tmpf->src_dfd = -1;
+  return TRUE;
+}
+
 /* Use this after calling glnx_open_tmpfile_linkable_at() to give
  * the file its final name (link into place).
  */
@@ -257,7 +278,9 @@ glnx_link_tmpfile_at (GLnxTmpfile *tmpf,
   const gboolean replace = (mode == GLNX_LINK_TMPFILE_REPLACE);
   const gboolean ignore_eexist = (mode == GLNX_LINK_TMPFILE_NOREPLACE_IGNORE_EXIST);
 
+  g_return_val_if_fail (!tmpf->anonymous, FALSE);
   g_return_val_if_fail (tmpf->fd >= 0, FALSE);
+  g_return_val_if_fail (tmpf->src_dfd == AT_FDCWD || tmpf->src_dfd >= 0, FALSE);
 
   /* Unlike the original systemd code, this function also supports
    * replacing existing files.
diff --git a/glnx-fdio.h b/glnx-fdio.h
index bdccbe55f..14ae57e55 100644
--- a/glnx-fdio.h
+++ b/glnx-fdio.h
@@ -52,6 +52,7 @@ const char *glnx_basename (const char *path)
 
 typedef struct {
   gboolean initialized;
+  gboolean anonymous;
   int src_dfd;
   int fd;
   char *path;
@@ -59,6 +60,11 @@ typedef struct {
 void glnx_tmpfile_clear (GLnxTmpfile *tmpf);
 G_DEFINE_AUTO_CLEANUP_CLEAR_FUNC(GLnxTmpfile, glnx_tmpfile_clear);
 
+gboolean
+glnx_open_anonymous_tmpfile (int flags,
+                             GLnxTmpfile *out_tmpf,
+                             GError **error);
+
 gboolean
 glnx_open_tmpfile_linkable_at (int dfd,
                                const char *subpath,
-- 
GitLab