diff options
author | Ondrej Holy <oholy@redhat.com> | 2018-02-15 09:25:36 +0100 |
---|---|---|
committer | Ondrej Holy <oholy@redhat.com> | 2018-02-16 16:39:58 +0100 |
commit | cb1c755a4a91e3e4e738adb1fb0dd7b4eaee130b (patch) | |
tree | e942e4d488ab32c3ca4befa559af424fe2babc3d | |
parent | 2502641f953266e17794249650c025b3abce057f (diff) | |
download | gvfs-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.c | 34 |
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); |