From 2905402c0b856eaf86e497c41bbe0d630647c6f6 Mon Sep 17 00:00:00 2001 From: raveit Date: Tue, 5 Feb 2013 10:54:42 +0100 Subject: Avoid-double-forking-when-launching-apps-it-breaks --- mate-panel/libpanel-util/panel-launch.c | 40 ++++++++++++++++++++++++++------- mate-panel/panel-run-dialog.c | 18 +++++++++++++-- 2 files changed, 48 insertions(+), 10 deletions(-) (limited to 'mate-panel') diff --git a/mate-panel/libpanel-util/panel-launch.c b/mate-panel/libpanel-util/panel-launch.c index 5b2517d9..90ba58dd 100644 --- a/mate-panel/libpanel-util/panel-launch.c +++ b/mate-panel/libpanel-util/panel-launch.c @@ -75,6 +75,25 @@ _panel_launch_handle_error (const gchar *name, return FALSE; } +static void +dummy_child_watch (GPid pid, + gint status, + gpointer user_data) +{ + /* Nothing, this is just to ensure we don't double fork + * and break pkexec: + * https://bugzilla.gnome.org/show_bug.cgi?id=675789 + */ +} + +static void +gather_pid_callback (GDesktopAppInfo *gapp, + GPid pid, + gpointer data) +{ + g_child_watch_add (pid, dummy_child_watch, NULL); +} + gboolean panel_app_info_launch_uris (GAppInfo *appinfo, GList *uris, @@ -86,7 +105,7 @@ panel_app_info_launch_uris (GAppInfo *appinfo, GError *local_error; gboolean retval; - g_return_val_if_fail (G_IS_APP_INFO (appinfo), FALSE); + g_return_val_if_fail (G_IS_DESKTOP_APP_INFO (appinfo), FALSE); g_return_val_if_fail (GDK_IS_SCREEN (screen), FALSE); g_return_val_if_fail (error == NULL || *error == NULL, FALSE); @@ -95,16 +114,18 @@ panel_app_info_launch_uris (GAppInfo *appinfo, gdk_app_launch_context_set_timestamp (context, timestamp); local_error = NULL; - retval = g_app_info_launch_uris (appinfo, uris, - (GAppLaunchContext *) context, - &local_error); + retval = g_desktop_app_info_launch_uris_as_manager ((GDesktopAppInfo*)appinfo, uris, + (GAppLaunchContext *) context, + G_SPAWN_SEARCH_PATH | G_SPAWN_DO_NOT_REAP_CHILD, + NULL, NULL, gather_pid_callback, appinfo, + &local_error); g_object_unref (context); if ((local_error == NULL) && (retval == TRUE)) return TRUE; - return _panel_launch_handle_error (g_app_info_get_name (appinfo), + return _panel_launch_handle_error (g_app_info_get_name ((GAppInfo*) appinfo), screen, local_error, error); } @@ -209,6 +230,7 @@ panel_launch_desktop_file_with_fallback (const char *desktop_file, char *argv[2] = { (char *) fallback_exec, NULL }; GError *local_error; gboolean retval; + GPid pid; g_return_val_if_fail (desktop_file != NULL, FALSE); g_return_val_if_fail (fallback_exec != NULL, FALSE); @@ -226,10 +248,12 @@ panel_launch_desktop_file_with_fallback (const char *desktop_file, } retval = gdk_spawn_on_screen (screen, NULL, argv, NULL, - G_SPAWN_SEARCH_PATH, - NULL, NULL, NULL, &local_error); + G_SPAWN_SEARCH_PATH | G_SPAWN_DO_NOT_REAP_CHILD, + NULL, NULL, &pid, &local_error); - if (local_error == NULL && retval == TRUE) + if (local_error == NULL && retval == TRUE) { + g_child_watch_add (pid, dummy_child_watch, NULL); + } return TRUE; return _panel_launch_handle_error (fallback_exec, diff --git a/mate-panel/panel-run-dialog.c b/mate-panel/panel-run-dialog.c index f476b5de..339240d2 100644 --- a/mate-panel/panel-run-dialog.c +++ b/mate-panel/panel-run-dialog.c @@ -349,6 +349,17 @@ command_is_executable (const char *command, return TRUE; } +static void +dummy_child_watch (GPid pid, + gint status, + gpointer user_data) +{ + /* Nothing, this is just to ensure we don't double fork + * and break pkexec: + * https://bugzilla.gnome.org/show_bug.cgi?id=675789 + */ +} + static gboolean panel_run_dialog_launch_command (PanelRunDialog *dialog, const char *command, @@ -359,6 +370,7 @@ panel_run_dialog_launch_command (PanelRunDialog *dialog, GError *error = NULL; char **argv; int argc; + GPid pid; if (!command_is_executable (locale_command, &argc, &argv)) return FALSE; @@ -372,10 +384,10 @@ panel_run_dialog_launch_command (PanelRunDialog *dialog, NULL, /* working directory */ argv, NULL, /* envp */ - G_SPAWN_SEARCH_PATH, + G_SPAWN_SEARCH_PATH | G_SPAWN_DO_NOT_REAP_CHILD, NULL, /* child setup func */ NULL, /* user data */ - NULL, /* child pid */ + &pid, /* child pid */ &error); if (!result) { @@ -389,6 +401,8 @@ panel_run_dialog_launch_command (PanelRunDialog *dialog, g_free (primary); g_error_free (error); + } else { + g_child_watch_add (pid, dummy_child_watch, NULL); } g_strfreev (argv); -- cgit v1.2.1