glib/gio/gsubprocesslauncher.h
Sergio Costas c12762a091 GSubprocessLauncher: allow to close passed FDs
By default, when using g_subprocess_launcher_take_fd() to pass an
FD to a child, the GSubprocessLauncher object also takes ownership
of the FD in the parent, and closes it during finalize(). This is
a reasonable assumption in the majority of the cases, but sometimes
it isn't a good idea.

An example is when creating a GSubprocessLauncher in JavaScript:
here, the destruction process is managed by the Garbage Collector,
which means that those sockets will remain opened for some time
after all the references to the object has been droped. This means
that it could be not possible to detect when the child has closed
that same FD, because in order to make that work, both FDs
instances (the one in the parent and the one in the children) must
be closed. This can be a problem in, as an example, a process that
launches a child that communicates with Wayland using an specific
socket (like when using the new API MetaWaylandClient).

Of course, it isn't a valid solution to manually call close() in
the parent process just after the call to spawn(), because the FD
number could be reused in the time between it is manually closed,
and when the object is destroyed and closes again that FD. If that
happens, it will close an incorrect FD.

One solution could be to call run_dispose() from Javascript on the
GSubprocessLauncher object, to force freeing the resources.
Unfortunately, the current code frees them in the finalize()
method, not in dispose() (this is fixed in !1670 (merged) ) but it
isn't a very elegant solution.

This proposal adds a new method, g_subprocess_launcher_close(),
that allows to close the FDs passed to the child. To avoid problems,
after closing an FD with this method, no more spawns are allowed.

Fix: https://gitlab.gnome.org/GNOME/glib/-/merge_requests/1677
2020-10-12 20:29:48 +02:00

120 lines
6.4 KiB
C

/* GIO - GLib Input, Output and Streaming Library
*
* Copyright © 2012,2013 Colin Walters <walters@verbum.org>
* Copyright © 2012,2013 Canonical Limited
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General
* Public License along with this library; if not, see <http://www.gnu.org/licenses/>.
*
* Author: Ryan Lortie <desrt@desrt.ca>
* Author: Colin Walters <walters@verbum.org>
*/
#if !defined (__GIO_GIO_H_INSIDE__) && !defined (GIO_COMPILATION)
#error "Only <gio/gio.h> can be included directly."
#endif
#ifndef __G_SUBPROCESS_LAUNCHER_H__
#define __G_SUBPROCESS_LAUNCHER_H__
#include <gio/giotypes.h>
G_BEGIN_DECLS
#define G_TYPE_SUBPROCESS_LAUNCHER (g_subprocess_launcher_get_type ())
#define G_SUBPROCESS_LAUNCHER(o) (G_TYPE_CHECK_INSTANCE_CAST ((o), G_TYPE_SUBPROCESS_LAUNCHER, GSubprocessLauncher))
#define G_IS_SUBPROCESS_LAUNCHER(o) (G_TYPE_CHECK_INSTANCE_TYPE ((o), G_TYPE_SUBPROCESS_LAUNCHER))
GLIB_AVAILABLE_IN_2_40
GType g_subprocess_launcher_get_type (void) G_GNUC_CONST;
GLIB_AVAILABLE_IN_2_40
GSubprocessLauncher * g_subprocess_launcher_new (GSubprocessFlags flags);
GLIB_AVAILABLE_IN_2_40
GSubprocess * g_subprocess_launcher_spawn (GSubprocessLauncher *self,
GError **error,
const gchar *argv0,
...) G_GNUC_NULL_TERMINATED;
GLIB_AVAILABLE_IN_2_40
GSubprocess * g_subprocess_launcher_spawnv (GSubprocessLauncher *self,
const gchar * const *argv,
GError **error);
GLIB_AVAILABLE_IN_2_40
void g_subprocess_launcher_set_environ (GSubprocessLauncher *self,
gchar **env);
GLIB_AVAILABLE_IN_2_40
void g_subprocess_launcher_setenv (GSubprocessLauncher *self,
const gchar *variable,
const gchar *value,
gboolean overwrite);
GLIB_AVAILABLE_IN_2_40
void g_subprocess_launcher_unsetenv (GSubprocessLauncher *self,
const gchar *variable);
GLIB_AVAILABLE_IN_2_40
const gchar * g_subprocess_launcher_getenv (GSubprocessLauncher *self,
const gchar *variable);
GLIB_AVAILABLE_IN_2_40
void g_subprocess_launcher_set_cwd (GSubprocessLauncher *self,
const gchar *cwd);
GLIB_AVAILABLE_IN_2_40
void g_subprocess_launcher_set_flags (GSubprocessLauncher *self,
GSubprocessFlags flags);
/* Extended I/O control, only available on UNIX */
#ifdef G_OS_UNIX
GLIB_AVAILABLE_IN_2_40
void g_subprocess_launcher_set_stdin_file_path (GSubprocessLauncher *self,
const gchar *path);
GLIB_AVAILABLE_IN_2_40
void g_subprocess_launcher_take_stdin_fd (GSubprocessLauncher *self,
gint fd);
GLIB_AVAILABLE_IN_2_40
void g_subprocess_launcher_set_stdout_file_path (GSubprocessLauncher *self,
const gchar *path);
GLIB_AVAILABLE_IN_2_40
void g_subprocess_launcher_take_stdout_fd (GSubprocessLauncher *self,
gint fd);
GLIB_AVAILABLE_IN_2_40
void g_subprocess_launcher_set_stderr_file_path (GSubprocessLauncher *self,
const gchar *path);
GLIB_AVAILABLE_IN_2_40
void g_subprocess_launcher_take_stderr_fd (GSubprocessLauncher *self,
gint fd);
GLIB_AVAILABLE_IN_2_40
void g_subprocess_launcher_take_fd (GSubprocessLauncher *self,
gint source_fd,
gint target_fd);
GLIB_AVAILABLE_IN_2_68
void g_subprocess_launcher_close (GSubprocessLauncher *self);
/* Child setup, only available on UNIX */
GLIB_AVAILABLE_IN_2_40
void g_subprocess_launcher_set_child_setup (GSubprocessLauncher *self,
GSpawnChildSetupFunc child_setup,
gpointer user_data,
GDestroyNotify destroy_notify);
#endif
G_END_DECLS
#endif /* __G_SUBPROCESS_H__ */