core: Add ot_gfile_create_tmp() to utils, use it

This commit is contained in:
Colin Walters 2011-11-30 20:14:24 -05:00
parent 247e027125
commit 99bf19314e
3 changed files with 89 additions and 24 deletions

View File

@ -574,25 +574,19 @@ write_gvariant_to_tmp (OstreeRepo *self,
GVariant *serialized = NULL; GVariant *serialized = NULL;
gboolean ret = FALSE; gboolean ret = FALSE;
gsize bytes_written; gsize bytes_written;
char *tmp_name = NULL; GFile *tmp_f = NULL;
char *dest_name = NULL; GOutputStream *stream = NULL;
int fd = -1;
GUnixOutputStream *stream = NULL;
GChecksum *checksum = NULL; GChecksum *checksum = NULL;
GFile *ret_tmpname = NULL;
serialized = ostree_wrap_metadata_variant (type, variant); serialized = ostree_wrap_metadata_variant (type, variant);
tmp_name = g_build_filename (ot_gfile_get_path_cached (priv->tmp_dir), "variant-tmp-XXXXXX", NULL); if (!ot_gfile_create_tmp (priv->tmp_dir, "variant-tmp-", NULL, 0666,
fd = g_mkstemp (tmp_name); &tmp_f, &stream, NULL, error))
if (fd < 0) goto out;
{
ot_util_set_error_from_errno (error, errno);
goto out;
}
checksum = g_checksum_new (G_CHECKSUM_SHA256); checksum = g_checksum_new (G_CHECKSUM_SHA256);
stream = (GUnixOutputStream*)g_unix_output_stream_new (fd, FALSE);
if (!g_output_stream_write_all ((GOutputStream*)stream, if (!g_output_stream_write_all ((GOutputStream*)stream,
g_variant_get_data (serialized), g_variant_get_data (serialized),
g_variant_get_size (serialized), g_variant_get_size (serialized),
@ -607,29 +601,27 @@ write_gvariant_to_tmp (OstreeRepo *self,
NULL, error)) NULL, error))
goto out; goto out;
dest_name = g_build_filename (ot_gfile_get_path_cached (priv->tmp_dir), g_checksum_get_string (checksum), NULL); ret_tmpname = g_file_get_child (priv->tmp_dir, g_checksum_get_string (checksum));
if (rename (tmp_name, dest_name) < 0) if (rename (ot_gfile_get_path_cached (tmp_f), ot_gfile_get_path_cached (ret_tmpname)) < 0)
{ {
ot_util_set_error_from_errno (error, errno); ot_util_set_error_from_errno (error, errno);
goto out; goto out;
} }
g_free (tmp_name); g_clear_object (&tmp_f);
tmp_name = NULL;
ret = TRUE; ret = TRUE;
*out_tmpname = ot_gfile_new_for_path (dest_name); *out_tmpname = ret_tmpname;
ret_tmpname = NULL;
*out_checksum = checksum; *out_checksum = checksum;
checksum = NULL; checksum = NULL;
out: out:
if (tmp_name) if (tmp_f)
(void) unlink (tmp_name); (void) g_file_delete (tmp_f, NULL, NULL);
g_free (tmp_name); g_clear_object (&tmp_f);
if (fd != -1) g_clear_object (&stream);
close (fd); g_clear_object (&ret_tmpname);
ot_clear_checksum (&checksum); ot_clear_checksum (&checksum);
ot_clear_gvariant (&serialized); ot_clear_gvariant (&serialized);
g_free (dest_name);
g_clear_object (&stream);
return ret; return ret;
} }
@ -817,6 +809,8 @@ link_object_trusted (OstreeRepo *self,
|| rename (tmp_dest_path, dest_path) < 0) || rename (tmp_dest_path, dest_path) < 0)
{ {
ot_util_set_error_from_errno (error, errno); ot_util_set_error_from_errno (error, errno);
g_prefix_error (error, "Storing file '%s': ",
ot_gfile_get_path_cached (file));
goto out; goto out;
} }
g_free (tmp_dest_path); g_free (tmp_dest_path);

View File

@ -24,11 +24,16 @@
#include <gio/gio.h> #include <gio/gio.h>
#include <gio/gunixinputstream.h> #include <gio/gunixinputstream.h>
#include <gio/gunixoutputstream.h>
#include <string.h> #include <string.h>
#include "otutil.h" #include "otutil.h"
#ifndef O_BINARY
#define O_BINARY 0
#endif
gboolean gboolean
ot_gfile_ensure_directory (GFile *dir, ot_gfile_ensure_directory (GFile *dir,
gboolean with_parents, gboolean with_parents,
@ -133,6 +138,64 @@ ot_gfile_get_basename_cached (GFile *file)
return name; return name;
} }
gboolean
ot_gfile_create_tmp (GFile *dir,
const char *prefix,
const char *suffix,
int mode,
GFile **out_file,
GOutputStream **out_stream,
GCancellable *cancellable,
GError **error)
{
gboolean ret = FALSE;
GString *tmp_name = NULL;
int tmpfd = -1;
GFile *ret_file = NULL;
GOutputStream *ret_stream = NULL;
if (g_cancellable_set_error_if_cancelled (cancellable, error))
return FALSE;
if (!prefix)
prefix = "tmp-";
if (!suffix)
suffix = ".tmp";
tmp_name = g_string_new (ot_gfile_get_path_cached (dir));
g_string_append_c (tmp_name, '/');
g_string_append (tmp_name, prefix);
g_string_append (tmp_name, "XXXXXX");
g_string_append (tmp_name, suffix);
tmpfd = g_mkstemp_full (tmp_name->str, O_WRONLY | O_BINARY, mode);
if (tmpfd == -1)
{
ot_util_set_error_from_errno (error, errno);
goto out;
}
ret_file = ot_gfile_new_for_path (tmp_name->str);
ret_stream = g_unix_output_stream_new (tmpfd, TRUE);
ret = TRUE;
if (out_file)
{
*out_file = ret_file;
ret_file = NULL;
}
if (out_stream)
{
*out_stream = ret_stream;
ret_stream = NULL;
}
out:
g_clear_object (&ret_file);
g_clear_object (&ret_stream);
g_string_free (tmp_name, TRUE);
return ret;
}
gboolean gboolean
ot_gfile_merge_dirs (GFile *destination, ot_gfile_merge_dirs (GFile *destination,
GFile *src, GFile *src,

View File

@ -43,6 +43,14 @@ gboolean ot_gfile_load_contents_utf8 (GFile *file,
GCancellable *cancellable, GCancellable *cancellable,
GError **error); GError **error);
gboolean ot_gfile_create_tmp (GFile *dir,
const char *prefix,
const char *suffix,
int mode,
GFile **out_file,
GOutputStream **out_stream,
GCancellable *cancellable,
GError **error);
gboolean ot_gfile_merge_dirs (GFile *destination, gboolean ot_gfile_merge_dirs (GFile *destination,
GFile *src, GFile *src,