summaryrefslogtreecommitdiff
path: root/src/libotutil/ot-fs-utils.c
diff options
context:
space:
mode:
authorColin Walters <walters@verbum.org>2017-06-28 13:41:52 -0400
committerAtomic Bot <atomic-devel@projectatomic.io>2017-06-29 14:46:18 +0000
commit6f2ea23e8a96cf7dddadf0eae1b4f831db88d67f (patch)
treef3c472ab9e35f2029738d152f52f2763ceed878f /src/libotutil/ot-fs-utils.c
parent9d10bdfd0d90d6ea6a31bbd89243f3b23ff51e8d (diff)
downloadostree-6f2ea23e8a96cf7dddadf0eae1b4f831db88d67f.tar.gz
libutil: Add a helper for O_TMPFILE + mmap()
I added `glnx_open_anonymous_tmpfile()`, but then later noticed that the usage of this was really to be combined with `mmap()`, and we had two versions of that in the delta code. Add a helper. (Bigger picture...how is this different from glibc's "mmap() of /dev/zero" approach for large chunks? One advantage is the storage can be "swapped" to `/var/tmp`, but still deleted automatically, rather than requiring swap space) Closes: #973 Approved by: jlebon
Diffstat (limited to 'src/libotutil/ot-fs-utils.c')
-rw-r--r--src/libotutil/ot-fs-utils.c27
1 files changed, 27 insertions, 0 deletions
diff --git a/src/libotutil/ot-fs-utils.c b/src/libotutil/ot-fs-utils.c
index d2bde837..2f0ae19c 100644
--- a/src/libotutil/ot-fs-utils.c
+++ b/src/libotutil/ot-fs-utils.c
@@ -24,6 +24,7 @@
#include "libglnx.h"
#include <sys/xattr.h>
#include <gio/gunixinputstream.h>
+#include <gio/gunixoutputstream.h>
/* Convert a fd-relative path to a GFile* - use
* for legacy code.
@@ -181,3 +182,29 @@ ot_file_mapat_bytes (int dfd,
return g_mapped_file_get_bytes (mfile);
}
+
+/* Given an input stream, splice it to an anonymous file (O_TMPFILE).
+ * Useful for potentially large but transient files.
+ */
+GBytes *
+ot_map_anonymous_tmpfile_from_content (GInputStream *instream,
+ GCancellable *cancellable,
+ GError **error)
+{
+ g_auto(GLnxTmpfile) tmpf = { 0, };
+ if (!glnx_open_anonymous_tmpfile (O_RDWR | O_CLOEXEC, &tmpf, error))
+ return NULL;
+
+ g_autoptr(GOutputStream) out = g_unix_output_stream_new (tmpf.fd, FALSE);
+ gssize n_bytes_written = g_output_stream_splice (out, instream,
+ G_OUTPUT_STREAM_SPLICE_CLOSE_SOURCE |
+ G_OUTPUT_STREAM_SPLICE_CLOSE_TARGET,
+ cancellable, error);
+ if (n_bytes_written < 0)
+ return NULL;
+
+ g_autoptr(GMappedFile) mfile = g_mapped_file_new_from_fd (tmpf.fd, FALSE, error);
+ if (!mfile)
+ return NULL;
+ return g_mapped_file_get_bytes (mfile);
+}