diff options
author | Ross Lagerwall <rosslagerwall@gmail.com> | 2014-07-26 08:46:59 +0100 |
---|---|---|
committer | Ross Lagerwall <rosslagerwall@gmail.com> | 2014-10-26 15:58:56 +0000 |
commit | 548ba46c2ba51c4ec5b0dd8442b476f3a2a7000b (patch) | |
tree | 438c31559455b1a91e0f5df6d8b1e6a3606b3a6c /client/gvfsfusedaemon.c | |
parent | 8082321c9d2c8e1f8bb8a679219af1507f297b1a (diff) | |
download | gvfs-548ba46c2ba51c4ec5b0dd8442b476f3a2a7000b.tar.gz |
fuse: Don't g_file_append_to unless O_APPEND is given
Because g_file_append_to opens an output stream that can only append
regardless of the seek position, only use g_file_append_to when O_APPEND
is actually specified. This prevents file corruption when the mode is
O_WRONLY or O_RDWR without O_APPEND.
Note that this means opening a file with a bare O_WRONLY or O_RDWR
returns ENOTSUP since there is no equivalent in gvfs.
Furthermore, don't attempt to seek when the file mode is O_APPEND since
this is unnecessary.
https://bugzilla.gnome.org/show_bug.cgi?id=632296
Diffstat (limited to 'client/gvfsfusedaemon.c')
-rw-r--r-- | client/gvfsfusedaemon.c | 17 |
1 files changed, 12 insertions, 5 deletions
diff --git a/client/gvfsfusedaemon.c b/client/gvfsfusedaemon.c index 40cf52e2..d8440eb3 100644 --- a/client/gvfsfusedaemon.c +++ b/client/gvfsfusedaemon.c @@ -1027,8 +1027,10 @@ setup_output_stream (GFile *file, FileHandle *fh, int flags) { if (flags & O_TRUNC) fh->stream = g_file_replace (file, NULL, FALSE, 0, NULL, &error); - else + else if (flags & O_APPEND) fh->stream = g_file_append_to (file, 0, NULL, &error); + else + result = -ENOTSUP; if (fh->stream) fh->pos = g_seekable_tell (G_SEEKABLE (fh->stream)); } @@ -1383,7 +1385,11 @@ vfs_read (const gchar *path, gchar *buf, size_t size, } static gint -write_stream (FileHandle *fh, const gchar *input_buf, size_t input_buf_size, off_t offset) +write_stream (FileHandle *fh, + gboolean is_append, + const gchar *input_buf, + size_t input_buf_size, + off_t offset) { GOutputStream *output_stream; gint n_bytes_written = 0; @@ -1394,7 +1400,7 @@ write_stream (FileHandle *fh, const gchar *input_buf, size_t input_buf_size, off output_stream = fh->stream; - if (offset != fh->pos) + if (!is_append && offset != fh->pos) { if (g_seekable_can_seek (G_SEEKABLE (output_stream))) { @@ -1479,7 +1485,8 @@ vfs_write (const gchar *path, const gchar *buf, size_t len, off_t offset, result = setup_output_stream (file, fh, 0); if (result == 0) { - result = write_stream (fh, buf, len, offset); + result = write_stream (fh, fi->flags & O_APPEND, + buf, len, offset); } g_mutex_unlock (&fh->mutex); @@ -1914,7 +1921,7 @@ pad_file (FileHandle *fh, gsize num, goffset current_size) buf = g_malloc0 (PAD_BLOCK_SIZE); for (written = 0; written < num; written += PAD_BLOCK_SIZE) { - res = write_stream (fh, buf, MIN (num - written, PAD_BLOCK_SIZE), current_size + written); + res = write_stream (fh, FALSE, buf, MIN (num - written, PAD_BLOCK_SIZE), current_size + written); if (res < 0) break; } |