shell/util: Add spawn_app_info_with_fds() function

This wraps `g_desktop_app_info_launch_as_manager_with_fds()` as
used by Shell.App. Like the other spawn helpers, it takes care
of resetting the nofile rlimit of the spawned child, and therefore
avoids exposing the child-setup parameter to introspection, where
it is unsafe to use.
This commit is contained in:
Florian Müllner 2024-06-06 19:13:03 +02:00
parent 55027bb084
commit 2827a9f16d
No known key found for this signature in database
2 changed files with 62 additions and 0 deletions

View file

@ -824,6 +824,14 @@ spawn_child_setup (gpointer user_data)
meta_context_restore_rlimit_nofile (meta_context, NULL);
}
static void
wait_pid (GDesktopAppInfo *appinfo,
GPid pid,
gpointer user_data)
{
g_child_watch_add (pid, (GChildWatchFunc) g_spawn_close_pid, NULL);
}
/**
* shell_util_spawn_async_with_pipes_and_fds:
* @working_directory: (type filename) (nullable): child's current working
@ -985,3 +993,49 @@ shell_util_spawn_async (const char *working_directory,
return shell_util_spawn_async_with_pipes (working_directory, argv, envp,
flags, NULL, NULL, NULL, error);
}
/**
* shell_util_spawn_app_info_with_fds:
* @context: (nullable): a launch context
* @flags: flags from #GSpawnFlags
* @stdin_fd: File descriptor to use for childs stdin, or -1.
* @stdout_fd: File descriptor to use for childs stdout, or -1.
* @stderr_fd: File descriptor to use for childs stderr, or -1.
* @error: return location for error
*
* A wrapper around g_desktop_app_info_launch_uris_as_manager_with_fds()
* with async-signal-safe implementation of #GSpawnChildSetupFunc to
* launch a child program asynchronously resetting the rlimit nofile
* on child setup.
*
* Returns: TRUE on successful launch, FALSE otherwise.
**/
gboolean
shell_util_spawn_app_info_with_fds (GAppInfo *app_info,
GAppLaunchContext *context,
GSpawnFlags flags,
int stdin_fd,
int stdout_fd,
int stderr_fd,
GError **error)
{
MetaContext *meta_context;
/* Hack: Use GAppInfo in public API, so it works with infos created with
* g_app_info_create_from_commandline(), but assume GDesktopAppInfo
* internally (considering that it has been the only backend on
* Unix since GIO was created, the assumption should be fairly safe)
*/
g_return_val_if_fail (G_IS_DESKTOP_APP_INFO (app_info), FALSE);
meta_context = shell_global_get_context (shell_global_get ());
return g_desktop_app_info_launch_uris_as_manager_with_fds (G_DESKTOP_APP_INFO (app_info),
NULL, /* uris */
context,
flags,
spawn_child_setup, meta_context,
wait_pid, NULL,
stdin_fd, stdout_fd, stderr_fd,
error);
}

View file

@ -119,6 +119,14 @@ GPid shell_util_spawn_async (const char *working_directory,
GSpawnFlags flags,
GError **error);
gboolean shell_util_spawn_app_info_with_fds (GAppInfo *app_info,
GAppLaunchContext *context,
GSpawnFlags flags,
int stdin_fd,
int stdout_fd,
int stderr_fd,
GError **error);
G_END_DECLS
#endif /* __SHELL_UTIL_H__ */