summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDavid Zeuthen <davidz@redhat.com>2011-12-22 14:42:54 -0500
committerDavid Zeuthen <davidz@redhat.com>2011-12-22 14:42:54 -0500
commitb6f13596478ddf234ae814cd007ab806a80cb5c1 (patch)
tree4aeeeac5aeeb9f3166900aef64c7fc1850b73d79
parentb9ccc6617f230a96938642ecb0aa65da3530e5d8 (diff)
downloadgvfs-b6f13596478ddf234ae814cd007ab806a80cb5c1.tar.gz
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 <davidz@redhat.com>
-rw-r--r--monitor/udisks2/gvfsudisks2mount.c6
-rw-r--r--monitor/udisks2/gvfsudisks2utils.c48
-rw-r--r--monitor/udisks2/gvfsudisks2utils.h3
-rw-r--r--monitor/udisks2/gvfsudisks2volume.c3
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\"",