[glib: 4/7] gdesktopappinfo: add g_desktop_app_info_launch_uris_as_manager_with_fds variant



commit 156d009696e9873b9298774a11537966da15a26b
Author: Daniel Drake <drake endlessm com>
Date:   Wed Jun 6 06:59:59 2018 -0600

    gdesktopappinfo: add g_desktop_app_info_launch_uris_as_manager_with_fds variant
    
    Add an app-launching function which allows standard file descriptors
    to be passed to the child process.
    
    This will be used by gnome-shell to pass systemd journal descriptors
    as stdout/stderr. gnome-shell's child_setup function can then be
    eliminated, which will enable use of the posix_spawn optimized
    gspawn codepath for desktop app launching.

 docs/reference/gio/gio-sections.txt |   1 +
 gio/gdesktopappinfo.c               | 106 +++++++++++++++++++++++++++++-------
 gio/gdesktopappinfo.h               |  14 +++++
 gio/tests/desktop-app-info.c        |  41 ++++++++++++++
 4 files changed, 143 insertions(+), 19 deletions(-)
---
diff --git a/docs/reference/gio/gio-sections.txt b/docs/reference/gio/gio-sections.txt
index 9ae6d85c5..6861c90f5 100644
--- a/docs/reference/gio/gio-sections.txt
+++ b/docs/reference/gio/gio-sections.txt
@@ -1618,6 +1618,7 @@ g_desktop_app_info_get_boolean
 g_desktop_app_info_has_key
 GDesktopAppLaunchCallback
 g_desktop_app_info_launch_uris_as_manager
+g_desktop_app_info_launch_uris_as_manager_with_fds
 <SUBSECTION>
 g_desktop_app_info_list_actions
 g_desktop_app_info_get_action_name
diff --git a/gio/gdesktopappinfo.c b/gio/gdesktopappinfo.c
index 4eac5ada2..617a096fb 100644
--- a/gio/gdesktopappinfo.c
+++ b/gio/gdesktopappinfo.c
@@ -2641,6 +2641,9 @@ g_desktop_app_info_launch_uris_with_spawn (GDesktopAppInfo            *info,
                                            gpointer                    user_setup_data,
                                            GDesktopAppLaunchCallback   pid_callback,
                                            gpointer                    pid_callback_data,
+                                           gint                        stdin_fd,
+                                           gint                        stdout_fd,
+                                           gint                        stderr_fd,
                                            GError                    **error)
 {
   gboolean completed = FALSE;
@@ -2736,14 +2739,17 @@ g_desktop_app_info_launch_uris_with_spawn (GDesktopAppInfo            *info,
       g_free (argv);
       argv = NULL;
 
-      if (!g_spawn_async (info->path,
-                          wrapped_argv,
-                          envp,
-                          spawn_flags,
-                          user_setup,
-                          user_setup_data,
-                          &pid,
-                          error))
+      if (!g_spawn_async_with_fds (info->path,
+                                   wrapped_argv,
+                                   envp,
+                                   spawn_flags,
+                                   user_setup,
+                                   user_setup_data,
+                                   &pid,
+                                   stdin_fd,
+                                   stdout_fd,
+                                   stderr_fd,
+                                   error))
         {
           if (sn_id)
             g_app_launch_context_launch_failed (launch_context, sn_id);
@@ -2916,6 +2922,9 @@ g_desktop_app_info_launch_uris_internal (GAppInfo                   *appinfo,
                                          gpointer                    user_setup_data,
                                          GDesktopAppLaunchCallback   pid_callback,
                                          gpointer                    pid_callback_data,
+                                         gint                        stdin_fd,
+                                         gint                        stdout_fd,
+                                         gint                        stderr_fd,
                                          GError                     **error)
 {
   GDesktopAppInfo *info = G_DESKTOP_APP_INFO (appinfo);
@@ -2929,7 +2938,8 @@ g_desktop_app_info_launch_uris_internal (GAppInfo                   *appinfo,
   else
     success = g_desktop_app_info_launch_uris_with_spawn (info, session_bus, info->exec, uris, launch_context,
                                                          spawn_flags, user_setup, user_setup_data,
-                                                         pid_callback, pid_callback_data, error);
+                                                         pid_callback, pid_callback_data,
+                                                         stdin_fd, stdout_fd, stderr_fd, error);
 
   if (session_bus != NULL)
     {
@@ -2954,6 +2964,7 @@ g_desktop_app_info_launch_uris (GAppInfo           *appinfo,
                                                   launch_context,
                                                   _SPAWN_FLAGS_DEFAULT,
                                                   NULL, NULL, NULL, NULL,
+                                                  -1, -1, -1,
                                                   error);
 }
 
@@ -3004,6 +3015,61 @@ g_desktop_app_info_launch (GAppInfo           *appinfo,
   return res;
 }
 
+/**
+ * g_desktop_app_info_launch_uris_as_manager_with_fds:
+ * @appinfo: a #GDesktopAppInfo
+ * @uris: (element-type utf8): List of URIs
+ * @launch_context: (nullable): a #GAppLaunchContext
+ * @spawn_flags: #GSpawnFlags, used for each process
+ * @user_setup: (scope async) (nullable): a #GSpawnChildSetupFunc, used once
+ *     for each process.
+ * @user_setup_data: (closure user_setup) (nullable): User data for @user_setup
+ * @pid_callback: (scope call) (nullable): Callback for child processes
+ * @pid_callback_data: (closure pid_callback) (nullable): User data for @callback
+ * @stdin_fd: file descriptor to use for child's stdin, or -1
+ * @stdout_fd: file descriptor to use for child's stdout, or -1
+ * @stderr_fd: file descriptor to use for child's stderr, or -1
+ * @error: return location for a #GError, or %NULL
+ *
+ * Equivalent to g_desktop_app_info_launch_uris_as_manager() but allows
+ * you to pass in file descriptors for the stdin, stdout and stderr streams
+ * of the launched process.
+ *
+ * If application launching occurs via some non-spawn mechanism (e.g. D-Bus
+ * activation) then @stdin_fd, @stdout_fd and @stderr_fd are ignored.
+ *
+ * Returns: %TRUE on successful launch, %FALSE otherwise.
+ *
+ * Since: 2.58
+ */
+gboolean
+g_desktop_app_info_launch_uris_as_manager_with_fds (GDesktopAppInfo            *appinfo,
+                                                    GList                      *uris,
+                                                    GAppLaunchContext          *launch_context,
+                                                    GSpawnFlags                 spawn_flags,
+                                                    GSpawnChildSetupFunc        user_setup,
+                                                    gpointer                    user_setup_data,
+                                                    GDesktopAppLaunchCallback   pid_callback,
+                                                    gpointer                    pid_callback_data,
+                                                    gint                        stdin_fd,
+                                                    gint                        stdout_fd,
+                                                    gint                        stderr_fd,
+                                                    GError                    **error)
+{
+  return g_desktop_app_info_launch_uris_internal ((GAppInfo*)appinfo,
+                                                  uris,
+                                                  launch_context,
+                                                  spawn_flags,
+                                                  user_setup,
+                                                  user_setup_data,
+                                                  pid_callback,
+                                                  pid_callback_data,
+                                                  stdin_fd,
+                                                  stdout_fd,
+                                                  stderr_fd,
+                                                  error);
+}
+
 /**
  * g_desktop_app_info_launch_uris_as_manager:
  * @appinfo: a #GDesktopAppInfo
@@ -3046,15 +3112,16 @@ g_desktop_app_info_launch_uris_as_manager (GDesktopAppInfo            *appinfo,
                                            gpointer                    pid_callback_data,
                                            GError                    **error)
 {
-  return g_desktop_app_info_launch_uris_internal ((GAppInfo*)appinfo,
-                                                  uris,
-                                                  launch_context,
-                                                  spawn_flags,
-                                                  user_setup,
-                                                  user_setup_data,
-                                                  pid_callback,
-                                                  pid_callback_data,
-                                                  error);
+  return g_desktop_app_info_launch_uris_as_manager_with_fds (appinfo,
+                                                             uris,
+                                                             launch_context,
+                                                             spawn_flags,
+                                                             user_setup,
+                                                             user_setup_data,
+                                                             pid_callback,
+                                                             pid_callback_data,
+                                                             -1, -1, -1,
+                                                             error);
 }
 
 /* OnlyShowIn API support {{{2 */
@@ -4629,7 +4696,8 @@ g_desktop_app_info_launch_action (GDesktopAppInfo   *info,
 
       if (exec_line)
         g_desktop_app_info_launch_uris_with_spawn (info, session_bus, exec_line, NULL, launch_context,
-                                                   _SPAWN_FLAGS_DEFAULT, NULL, NULL, NULL, NULL, NULL);
+                                                   _SPAWN_FLAGS_DEFAULT, NULL, NULL, NULL, NULL,
+                                                   -1, -1, -1, NULL);
     }
 
   if (session_bus != NULL)
diff --git a/gio/gdesktopappinfo.h b/gio/gdesktopappinfo.h
index a2df3dd51..86a3caa30 100644
--- a/gio/gdesktopappinfo.h
+++ b/gio/gdesktopappinfo.h
@@ -169,6 +169,20 @@ gboolean    g_desktop_app_info_launch_uris_as_manager (GDesktopAppInfo
                                                       gpointer                    pid_callback_data,
                                                       GError                    **error);
 
+GLIB_AVAILABLE_IN_2_58
+gboolean    g_desktop_app_info_launch_uris_as_manager_with_fds (GDesktopAppInfo            *appinfo,
+                                                               GList                      *uris,
+                                                               GAppLaunchContext          *launch_context,
+                                                               GSpawnFlags                 spawn_flags,
+                                                               GSpawnChildSetupFunc        user_setup,
+                                                               gpointer                    user_setup_data,
+                                                               GDesktopAppLaunchCallback   pid_callback,
+                                                               gpointer                    pid_callback_data,
+                                                               gint                        stdin_fd,
+                                                               gint                        stdout_fd,
+                                                               gint                        stderr_fd,
+                                                               GError                    **error);
+
 GLIB_AVAILABLE_IN_2_40
 gchar *** g_desktop_app_info_search (const gchar *search_string);
 
diff --git a/gio/tests/desktop-app-info.c b/gio/tests/desktop-app-info.c
index 669db5769..639b27e18 100644
--- a/gio/tests/desktop-app-info.c
+++ b/gio/tests/desktop-app-info.c
@@ -788,6 +788,46 @@ test_show_in (void)
   assert_shown ("gcr-prompter.desktop", TRUE, "KDE:GNOME-Classic");
 }
 
+/* Test g_desktop_app_info_launch_uris_as_manager() and
+ * g_desktop_app_info_launch_uris_as_manager_with_fds()
+ */
+static void
+test_launch_as_manager (void)
+{
+  GDesktopAppInfo *appinfo;
+  GError *error = NULL;
+  gboolean retval;
+  const gchar *path;
+
+  if (g_getenv ("DISPLAY") == NULL || g_getenv ("DISPLAY")[0] == '\0')
+    {
+      g_test_skip ("No DISPLAY.  Skipping test.");
+      return;
+    }
+
+  path = g_test_get_filename (G_TEST_DIST, "appinfo-test.desktop", NULL);
+  appinfo = g_desktop_app_info_new_from_filename (path);
+  g_assert_nonnull (appinfo);
+
+  retval = g_desktop_app_info_launch_uris_as_manager (appinfo, NULL, NULL, 0,
+                                                      NULL, NULL,
+                                                      NULL, NULL,
+                                                      &error);
+  g_assert_no_error (error);
+  g_assert_true (retval);
+
+  retval = g_desktop_app_info_launch_uris_as_manager_with_fds (appinfo,
+                                                               NULL, NULL, 0,
+                                                               NULL, NULL,
+                                                               NULL, NULL,
+                                                               -1, -1, -1,
+                                                               &error);
+  g_assert_no_error (error);
+  g_assert_true (retval);
+
+  g_object_unref (appinfo);
+}
+
 int
 main (int   argc,
       char *argv[])
@@ -816,6 +856,7 @@ main (int   argc,
   g_test_add_func ("/desktop-app-info/search", test_search);
   g_test_add_func ("/desktop-app-info/implements", test_implements);
   g_test_add_func ("/desktop-app-info/show-in", test_show_in);
+  g_test_add_func ("/desktop-app-info/launch-as-manager", test_launch_as_manager);
 
   result = g_test_run ();
 


[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]