From b6f13596478ddf234ae814cd007ab806a80cb5c1 Mon Sep 17 00:00:00 2001 From: David Zeuthen Date: Thu, 22 Dec 2011 14:42:54 -0500 Subject: Use a timeout of ten seconds when spawning commands This is helpful in the presence of e.g. unreachable NFS servers etc. Signed-off-by: David Zeuthen --- monitor/udisks2/gvfsudisks2mount.c | 6 +++-- monitor/udisks2/gvfsudisks2utils.c | 48 ++++++++++++++++++++++++++++++++++++- monitor/udisks2/gvfsudisks2utils.h | 3 ++- monitor/udisks2/gvfsudisks2volume.c | 3 ++- 4 files changed, 55 insertions(+), 5 deletions(-) diff --git a/monitor/udisks2/gvfsudisks2mount.c b/monitor/udisks2/gvfsudisks2mount.c index ca1a0759..418bd8c6 100644 --- a/monitor/udisks2/gvfsudisks2mount.c +++ b/monitor/udisks2/gvfsudisks2mount.c @@ -736,7 +736,8 @@ unmount_show_busy (UnmountData *data, { gchar *escaped_mount_point; escaped_mount_point = g_strescape (mount_point, NULL); - gvfs_udisks2_utils_spawn (data->cancellable, + gvfs_udisks2_utils_spawn (10, /* timeout in seconds */ + data->cancellable, lsof_command_cb, unmount_data_ref (data), "lsof -t \"%s\"", @@ -874,7 +875,8 @@ unmount_do (UnmountData *data, { gchar *escaped_mount_path; escaped_mount_path = g_strescape (data->mount->mount_path, NULL); - gvfs_udisks2_utils_spawn (data->cancellable, + gvfs_udisks2_utils_spawn (10, /* timeout in seconds */ + data->cancellable, umount_command_cb, data, "umount %s \"%s\"", diff --git a/monitor/udisks2/gvfsudisks2utils.c b/monitor/udisks2/gvfsudisks2utils.c index 213c2e77..207777a0 100644 --- a/monitor/udisks2/gvfsudisks2utils.c +++ b/monitor/udisks2/gvfsudisks2utils.c @@ -129,6 +129,9 @@ typedef struct GSource *child_stdout_source; GSource *child_stderr_source; + gboolean timed_out; + GSource *timeout_source; + GString *child_stdout; GString *child_stderr; @@ -145,6 +148,12 @@ child_watch_from_release_cb (GPid pid, static void spawn_data_free (SpawnData *data) { + if (data->timeout_source != NULL) + { + g_source_destroy (data->timeout_source); + data->timeout_source = NULL; + } + /* Nuke the child, if necessary */ if (data->child_watch_source != NULL) { @@ -312,8 +321,26 @@ child_watch_cb (GPid pid, g_object_unref (data->simple); } +static gboolean +timeout_cb (gpointer user_data) +{ + SpawnData *data = user_data; + + data->timed_out = TRUE; + + /* ok, timeout is history, make sure we don't free it in spawn_data_free() */ + data->timeout_source = NULL; + + /* we're done */ + g_simple_async_result_complete_in_idle (data->simple); + g_object_unref (data->simple); + + return FALSE; /* remove source */ +} + void -gvfs_udisks2_utils_spawn (GCancellable *cancellable, +gvfs_udisks2_utils_spawn (guint timeout_seconds, + GCancellable *cancellable, GAsyncReadyCallback callback, gpointer user_data, const gchar *command_line_format, @@ -404,6 +431,15 @@ gvfs_udisks2_utils_spawn (GCancellable *cancellable, goto out; } + if (timeout_seconds > 0) + { + data->timeout_source = g_timeout_source_new_seconds (timeout_seconds); + g_source_set_priority (data->timeout_source, G_PRIORITY_DEFAULT); + g_source_set_callback (data->timeout_source, timeout_cb, data, NULL); + g_source_attach (data->timeout_source, data->main_context); + g_source_unref (data->timeout_source); + } + data->child_watch_source = g_child_watch_source_new (data->child_pid); g_source_set_callback (data->child_watch_source, (GSourceFunc) child_watch_cb, data, NULL); g_source_attach (data->child_watch_source, data->main_context); @@ -448,6 +484,16 @@ gvfs_udisks2_utils_spawn_finish (GAsyncResult *res, data = g_simple_async_result_get_op_res_gpointer (simple); + if (data->timed_out) + { + g_set_error (error, + G_IO_ERROR, + G_IO_ERROR_TIMED_OUT, + _("Timed out running command-line `%s'"), + data->command_line); + goto out; + } + if (out_exit_status != NULL) *out_exit_status = data->exit_status; diff --git a/monitor/udisks2/gvfsudisks2utils.h b/monitor/udisks2/gvfsudisks2utils.h index 7a6abe79..80cf43d5 100644 --- a/monitor/udisks2/gvfsudisks2utils.h +++ b/monitor/udisks2/gvfsudisks2utils.h @@ -37,7 +37,8 @@ GIcon *gvfs_udisks2_utils_icon_from_fs_type (const gchar *fs_type); gchar *gvfs_udisks2_utils_lookup_fstab_options_value (const gchar *fstab_options, const gchar *key); -void gvfs_udisks2_utils_spawn (GCancellable *cancellable, +void gvfs_udisks2_utils_spawn (guint timeout_seconds, + GCancellable *cancellable, GAsyncReadyCallback callback, gpointer user_data, const gchar *command_line_format, diff --git a/monitor/udisks2/gvfsudisks2volume.c b/monitor/udisks2/gvfsudisks2volume.c index 8914b026..bc11868c 100644 --- a/monitor/udisks2/gvfsudisks2volume.c +++ b/monitor/udisks2/gvfsudisks2volume.c @@ -1055,7 +1055,8 @@ gvfs_udisks2_volume_mount (GVolume *_volume, { gchar *escaped_mount_path; escaped_mount_path = g_strescape (g_unix_mount_point_get_mount_path (data->volume->mount_point), NULL); - gvfs_udisks2_utils_spawn (data->cancellable, + gvfs_udisks2_utils_spawn (10, /* timeout in seconds */ + data->cancellable, mount_command_cb, data, "mount \"%s\"", -- cgit v1.2.1