summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorOndrej Holy <oholy@redhat.com>2018-02-15 09:25:36 +0100
committerOndrej Holy <oholy@redhat.com>2018-02-16 16:39:58 +0100
commitcb1c755a4a91e3e4e738adb1fb0dd7b4eaee130b (patch)
treee942e4d488ab32c3ca4befa559af424fe2babc3d
parent2502641f953266e17794249650c025b3abce057f (diff)
downloadgvfs-cb1c755a4a91e3e4e738adb1fb0dd7b4eaee130b.tar.gz
daemon: Fix admin backend spawning
pkexec fails on some systems with "Refusing to render service to dead parents.", which is caused by double forking when spawning the process. Let's prevent this by G_SPAWN_DO_NOT_REAP_CHILD flag and clean up manually using g_child_watch_add. https://bugzilla.gnome.org/show_bug.cgi?id=793445
-rw-r--r--daemon/mount.c34
1 files changed, 28 insertions, 6 deletions
diff --git a/daemon/mount.c b/daemon/mount.c
index 192923ef..e242666d 100644
--- a/daemon/mount.c
+++ b/daemon/mount.c
@@ -398,12 +398,22 @@ spawn_mount_handle_spawned (GVfsDBusSpawner *object,
}
static void
+child_watch_cb (GPid pid,
+ gint status,
+ gpointer user_data)
+{
+ g_spawn_close_pid (pid);
+}
+
+static void
spawn_mount (MountData *data)
{
char *exec;
GError *error;
GDBusConnection *connection;
static int mount_id = 0;
+ gchar **argv = NULL;
+ GPid pid;
data->spawned = TRUE;
@@ -448,13 +458,25 @@ spawn_mount (MountData *data)
" ",
data->obj_path,
NULL);
- if (!g_spawn_command_line_async (exec, &error))
- {
+
+ /* G_SPAWN_DO_NOT_REAP_CHILD is necessary for admin backend to prevent
+ * double forking causing pkexec failures, see:
+ * https://bugzilla.gnome.org/show_bug.cgi?id=793445
+ */
+ if (!g_shell_parse_argv (exec, NULL, &argv, &error) ||
+ !g_spawn_async (NULL, argv, NULL, G_SPAWN_DO_NOT_REAP_CHILD, NULL, NULL, &pid, &error))
+ {
g_dbus_interface_skeleton_unexport (G_DBUS_INTERFACE_SKELETON (data->spawner));
- mount_finish (data, error);
- g_error_free (error);
- }
-
+ mount_finish (data, error);
+ g_error_free (error);
+ }
+ else
+ {
+ g_child_watch_add (pid, child_watch_cb, NULL);
+ }
+
+ g_strfreev (argv);
+
/* TODO: Add a timeout here to detect spawned app crashing */
g_object_unref (connection);