GCancellable *cancellable,
GError **error)
{
- g_auto(GLnxTmpfile) tmpf = { 0, };
- g_autoptr(GBytes) ret_content = NULL;
g_autoptr(GInputStream) istream = NULL;
- g_autoptr(GOutputStream) out = NULL;
-
- if (!glnx_open_anonymous_tmpfile (O_RDWR | O_CLOEXEC, &tmpf, error))
- return FALSE;
if (!ostree_repo_load_file (repo, checksum, &istream, NULL, NULL,
cancellable, error))
return FALSE;
- out = g_unix_output_stream_new (tmpf.fd, FALSE);
- if (g_output_stream_splice (out, istream, G_OUTPUT_STREAM_SPLICE_CLOSE_TARGET,
- cancellable, error) < 0)
+ *out_content = ot_map_anonymous_tmpfile_from_content (istream, cancellable, error);
+ if (!*out_content)
return FALSE;
-
- { g_autoptr(GMappedFile) mfile = g_mapped_file_new_from_fd (tmpf.fd, FALSE, error);
- if (!mfile)
- return FALSE;
- ret_content = g_mapped_file_get_bytes (mfile);
- }
-
- if (out_content)
- *out_content = g_steal_pointer (&ret_content);
return TRUE;
}
break;
case 'x':
{
- g_autofree char *tmppath = g_strdup ("/var/tmp/ostree-delta-XXXXXX");
g_autoptr(GConverter) decomp = (GConverter*) _ostree_lzma_decompressor_new ();
g_autoptr(GInputStream) convin = g_converter_input_stream_new (source_in, decomp);
- g_autoptr(GOutputStream) unpacked_out = NULL;
- glnx_fd_close int unpacked_fd = -1;
- gssize n_bytes_written;
-
- unpacked_fd = g_mkstemp_full (tmppath, O_RDWR | O_CLOEXEC, 0640);
- if (unpacked_fd < 0)
- {
- glnx_set_error_from_errno (error);
- goto out;
- }
-
- /* Now make it autocleanup on process exit - in the future, we
- * should consider caching unpacked deltas as well.
- */
- if (unlink (tmppath) < 0)
- {
- glnx_set_error_from_errno (error);
- goto out;
- }
-
- unpacked_out = g_unix_output_stream_new (unpacked_fd, FALSE);
-
- n_bytes_written = g_output_stream_splice (unpacked_out, convin,
- G_OUTPUT_STREAM_SPLICE_CLOSE_SOURCE |
- G_OUTPUT_STREAM_SPLICE_CLOSE_TARGET,
- cancellable, error);
- if (n_bytes_written < 0)
+ g_autoptr(GBytes) buf = ot_map_anonymous_tmpfile_from_content (convin, cancellable, error);
+ if (!buf)
goto out;
- if (!ot_util_variant_map_fd (unpacked_fd, 0, G_VARIANT_TYPE (OSTREE_STATIC_DELTA_PART_PAYLOAD_FORMAT_V0),
- trusted, &ret_part, error))
- goto out;
+ ret_part = g_variant_new_from_bytes (G_VARIANT_TYPE (OSTREE_STATIC_DELTA_PART_PAYLOAD_FORMAT_V0),
+ buf, FALSE);
}
break;
default:
#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.
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);
+}
gboolean *out_exists,
GError **error);
+GBytes *
+ot_map_anonymous_tmpfile_from_content (GInputStream *instream,
+ GCancellable *cancellable,
+ GError **error);
+
GBytes *ot_file_mapat_bytes (int dfd,
const char *path,
GError **error);