#include "gfileoutputstream.h"
#include "glocalfileoutputstream.h"
#include "glocalfileiostream.h"
+#include "glocalfile.h"
#include "gcancellable.h"
#include "gasyncresult.h"
#include "gioerror.h"
do_set_attributes = TRUE;
}
- if (flags & G_FILE_COPY_OVERWRITE)
+ /* In the local file path, we pass down the source info which
+ * includes things like unix::mode, to ensure that the target file
+ * is not created with different permissions from the source file.
+ *
+ * If a future API like g_file_replace_with_info() is added, switch
+ * this code to use that.
+ */
+ if (G_IS_LOCAL_FILE (destination))
+ {
+ if (flags & G_FILE_COPY_OVERWRITE)
+ out = (GOutputStream*)_g_local_file_output_stream_replace (_g_local_file_get_filename (G_LOCAL_FILE (destination)),
+ FALSE, NULL,
+ flags & G_FILE_COPY_BACKUP,
+ G_FILE_CREATE_REPLACE_DESTINATION,
+ info,
+ cancellable, error);
+ else
+ out = (GOutputStream*)_g_local_file_output_stream_create (_g_local_file_get_filename (G_LOCAL_FILE (destination)),
+ FALSE, 0, info,
+ cancellable, error);
+ }
+ else if (flags & G_FILE_COPY_OVERWRITE)
{
out = (GOutputStream *)g_file_replace (destination,
NULL,
{
}
+const char *
+_g_local_file_get_filename (GLocalFile *file)
+{
+ return file->filename;
+}
static char *
canonicalize_filename (const char *filename)
GError **error)
{
return _g_local_file_output_stream_create (G_LOCAL_FILE (file)->filename,
- FALSE,
- flags, cancellable, error);
+ FALSE, flags, NULL,
+ cancellable, error);
}
static GFileOutputStream *
GError **error)
{
return _g_local_file_output_stream_replace (G_LOCAL_FILE (file)->filename,
- FALSE,
- etag, make_backup, flags,
- cancellable, error);
+ FALSE,
+ etag, make_backup, flags, NULL,
+ cancellable, error);
}
static GFileIOStream *
GFileIOStream *res;
output = _g_local_file_output_stream_create (G_LOCAL_FILE (file)->filename,
- TRUE, flags,
+ TRUE, flags, NULL,
cancellable, error);
if (output == NULL)
return NULL;
GFileIOStream *res;
output = _g_local_file_output_stream_replace (G_LOCAL_FILE (file)->filename,
- TRUE,
- etag, make_backup, flags,
- cancellable, error);
+ TRUE,
+ etag, make_backup, flags, NULL,
+ cancellable, error);
if (output == NULL)
return NULL;
GFile * _g_local_file_new (const char *filename);
+const char * _g_local_file_get_filename (GLocalFile *file);
+
G_END_DECLS
#endif /* __G_LOCAL_FILE_H__ */
#include "gioerror.h"
#include "gcancellable.h"
#include "glocalfileoutputstream.h"
+#include "gfileinfo.h"
#include "glocalfileinfo.h"
#ifdef G_OS_UNIX
return output_stream_open (filename, open_flags, 0666, cancellable, error);
}
+static gint
+mode_from_flags_or_info (GFileCreateFlags flags,
+ GFileInfo *reference_info)
+{
+ if (flags & G_FILE_CREATE_PRIVATE)
+ return 0600;
+ else if (reference_info && g_file_info_has_attribute (reference_info, "unix::mode"))
+ return g_file_info_get_attribute_uint32 (reference_info, "unix::mode") & (~S_IFMT);
+ else
+ return 0666;
+}
+
GFileOutputStream *
_g_local_file_output_stream_create (const char *filename,
gboolean readable,
GFileCreateFlags flags,
+ GFileInfo *reference_info,
GCancellable *cancellable,
GError **error)
{
if (g_cancellable_set_error_if_cancelled (cancellable, error))
return NULL;
- if (flags & G_FILE_CREATE_PRIVATE)
- mode = 0600;
- else
- mode = 0666;
+ mode = mode_from_flags_or_info (flags, reference_info);
open_flags = O_CREAT | O_EXCL | O_BINARY;
if (readable)
gboolean create_backup,
char **temp_filename,
GFileCreateFlags flags,
+ GFileInfo *reference_info,
GCancellable *cancellable,
GError **error)
{
int res;
int mode;
- if (flags & G_FILE_CREATE_PRIVATE)
- mode = 0600;
- else
- mode = 0666;
+ mode = mode_from_flags_or_info (flags, reference_info);
/* We only need read access to the original file if we are creating a backup.
* We also add O_CREATE to avoid a race if the file was just removed */
const char *etag,
gboolean create_backup,
GFileCreateFlags flags,
+ GFileInfo *reference_info,
GCancellable *cancellable,
GError **error)
{
temp_file = NULL;
- if (flags & G_FILE_CREATE_PRIVATE)
- mode = 0600;
- else
- mode = 0666;
+ mode = mode_from_flags_or_info (flags, reference_info);
sync_on_close = FALSE;
/* If the file doesn't exist, create it */
{
/* The file already exists */
fd = handle_overwrite_open (filename, readable, etag,
- create_backup, &temp_file,
- flags, cancellable, error);
+ create_backup, &temp_file,
+ flags, reference_info,
+ cancellable, error);
if (fd == -1)
return NULL;
GFileOutputStream * _g_local_file_output_stream_create (const char *filename,
gboolean readable,
GFileCreateFlags flags,
+ GFileInfo *reference_info,
GCancellable *cancellable,
GError **error);
GFileOutputStream * _g_local_file_output_stream_append (const char *filename,
const char *etag,
gboolean create_backup,
GFileCreateFlags flags,
+ GFileInfo *reference_info,
GCancellable *cancellable,
GError **error);