[gnome-user-share] obex: Fix race condition when moving to Downloads dir
- From: Bastien Nocera <hadess src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [gnome-user-share] obex: Fix race condition when moving to Downloads dir
- Date: Thu, 14 Nov 2013 21:14:26 +0000 (UTC)
commit fb75cc08adfc73791373b7f46ad415494080597e
Author: Bastien Nocera <hadess hadess net>
Date: Wed Nov 13 20:49:25 2013 +0100
obex: Fix race condition when moving to Downloads dir
Rather than doing g_file_test()s then moving the file.
src/obexpush.c | 104 ++++++++++++++++++++++++++++----------------------------
1 files changed, 52 insertions(+), 52 deletions(-)
---
diff --git a/src/obexpush.c b/src/obexpush.c
index e042ccf..0fa4084 100644
--- a/src/obexpush.c
+++ b/src/obexpush.c
@@ -480,78 +480,78 @@ parse_extension (const char *filename)
return strrchr ((last_separator) ? last_separator : filename, '.');
}
-static char *
-get_destination_path (const char *filename)
-{
- char *dest_dir;
- char *destination_filename;
-
- dest_dir = lookup_download_dir ();
- destination_filename = g_build_filename (dest_dir, filename, NULL);
- g_free (dest_dir);
-
- /* Append (n) as needed. */
- if (g_file_test (destination_filename, G_FILE_TEST_EXISTS)) {
- int i = 1;
- const char *dot_pos;
- gssize position;
- char *serial = NULL;
- GString *tmp_filename;
-
- dot_pos = parse_extension (destination_filename);
- if (dot_pos)
- position = dot_pos - destination_filename;
- else
- position = strlen (destination_filename);
-
- tmp_filename = g_string_new (NULL);
-
- do {
- serial = g_strdup_printf ("(%d)", i++);
-
- g_string_assign (tmp_filename, destination_filename);
- g_string_insert (tmp_filename, position, serial);
-
- g_free (serial);
- } while (g_file_test (tmp_filename->str, G_FILE_TEST_EXISTS));
-
- destination_filename = g_strdup (tmp_filename->str);
- g_string_free (tmp_filename, TRUE);
- }
-
- return destination_filename;
-}
-
static void
move_temp_filename (GObject *object)
{
const char *orig_filename;
- char *dest_filename;
+ char *dest_filename, *dest_dir;
GFile *src, *dest;
GError *error = NULL;
gboolean res;
orig_filename = g_object_get_data (object, "temp-filename");
- /* FIXME move to the destination directly, rather than
- * getting the name separately */
- dest_filename = get_destination_path (g_object_get_data (object, "filename"));
-
src = g_file_new_for_path (orig_filename);
+
+ dest_dir = lookup_download_dir ();
+ dest_filename = g_build_filename (dest_dir, g_object_get_data (object, "filename"), NULL);
+ g_free (dest_dir);
dest = g_file_new_for_path (dest_filename);
- /* This is sync, but the files will be on the same partition already
- * (~/.cache/obexd to ~/Downloads) */
res = g_file_move (src, dest,
G_FILE_COPY_NONE, NULL,
NULL, NULL, &error);
- g_debug ("Moving %s (orig name %s) to %s",
- orig_filename, (char *) g_object_get_data (object, "filename"), dest_filename);
- if (res == FALSE) {
+ /* This is sync, but the files will be on the same partition already
+ * (~/.cache/obexd to ~/Downloads) */
+ if (!res && g_error_matches (error, G_IO_ERROR, G_IO_ERROR_EXISTS)) {
+ guint i = 1;
+ const char *dot_pos;
+ gssize position;
+ char *serial = NULL;
+ GString *tmp_filename;
+
+ dot_pos = parse_extension (dest_filename);
+ if (dot_pos)
+ position = dot_pos - dest_filename;
+ else
+ position = strlen (dest_filename);
+
+ tmp_filename = g_string_new (NULL);
+ g_string_assign (tmp_filename, dest_filename);
+
+ while (!res && g_error_matches (error, G_IO_ERROR, G_IO_ERROR_EXISTS)) {
+ g_debug ("Couldn't move file to %s", tmp_filename->str);
+
+ g_clear_error (&error);
+ g_object_unref (dest);
+
+ serial = g_strdup_printf ("(%d)", i++);
+
+ g_string_assign (tmp_filename, dest_filename);
+ g_string_insert (tmp_filename, position, serial);
+
+ g_free (serial);
+
+ dest = g_file_new_for_path (tmp_filename->str);
+ res = g_file_move (src, dest,
+ G_FILE_COPY_NONE, NULL,
+ NULL, NULL, &error);
+ }
+
+ g_free (dest_filename);
+ dest_filename = g_strdup (tmp_filename->str);
+ g_string_free (tmp_filename, TRUE);
+ }
+
+ if (!res) {
g_warning ("Failed to move %s to %s: '%s'",
orig_filename, dest_filename, error->message);
g_error_free (error);
+ } else {
+ g_debug ("Moved %s (orig name %s) to %s",
+ orig_filename, (char *) g_object_get_data (object, "filename"), dest_filename);
}
+
g_object_unref (src);
g_object_unref (dest);
g_free (dest_filename);
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]