Skip to content
Snippets Groups Projects
Commit 5bf032a5 authored by Simon McVittie's avatar Simon McVittie
Browse files

all: Consistently work around glib!490


As noted in Flatpak and in GNOME/glib!490, there is a bug in GLib < 2.60
where g_spawn_* can sometimes deadlock while closing fds in a
multi-threaded application.

Work around this by making the affected fds close-on-execute ourselves,
much like Flatpak does.

Signed-off-by: default avatarSimon McVittie <smcv@collabora.com>
parent 0d66ee9a
No related branches found
No related tags found
No related merge requests found
...@@ -39,6 +39,7 @@ ...@@ -39,6 +39,7 @@
#include "libglnx/libglnx.h" #include "libglnx/libglnx.h"
#include "bwrap-lock.h" #include "bwrap-lock.h"
#include "flatpak-utils-base-private.h"
#include "utils.h" #include "utils.h"
#ifndef PR_SET_CHILD_SUBREAPER #ifndef PR_SET_CHILD_SUBREAPER
...@@ -54,6 +55,12 @@ static gboolean opt_version = FALSE; ...@@ -54,6 +55,12 @@ static gboolean opt_version = FALSE;
static gboolean opt_wait = FALSE; static gboolean opt_wait = FALSE;
static gboolean opt_write = FALSE; static gboolean opt_write = FALSE;
static void
child_setup_cb (gpointer user_data)
{
flatpak_close_fds_workaround (3);
}
static gboolean static gboolean
opt_fd_cb (const char *name, opt_fd_cb (const char *name,
const char *value, const char *value,
...@@ -166,11 +173,13 @@ generate_locales (gchar **locpath_out, ...@@ -166,11 +173,13 @@ generate_locales (gchar **locpath_out,
NULL NULL
}; };
/* We use LEAVE_DESCRIPTORS_OPEN to work around a deadlock in older GLib,
* see flatpak_close_fds_workaround */
if (!g_spawn_sync (NULL, /* cwd */ if (!g_spawn_sync (NULL, /* cwd */
(gchar **) locale_gen_argv, (gchar **) locale_gen_argv,
NULL, /* environ */ NULL, /* environ */
G_SPAWN_DEFAULT, G_SPAWN_LEAVE_DESCRIPTORS_OPEN,
NULL, NULL, /* child setup */ child_setup_cb, NULL,
&child_stdout, &child_stdout,
&child_stderr, &child_stderr,
&wait_status, &wait_status,
...@@ -421,11 +430,14 @@ main (int argc, ...@@ -421,11 +430,14 @@ main (int argc,
g_debug ("Launching child process..."); g_debug ("Launching child process...");
/* We use LEAVE_DESCRIPTORS_OPEN to work around a deadlock in older GLib,
* see flatpak_close_fds_workaround */
if (!g_spawn_async (NULL, /* working directory */ if (!g_spawn_async (NULL, /* working directory */
command_and_args, command_and_args,
my_environ, my_environ,
G_SPAWN_SEARCH_PATH | G_SPAWN_DO_NOT_REAP_CHILD, (G_SPAWN_SEARCH_PATH | G_SPAWN_DO_NOT_REAP_CHILD |
NULL, NULL, /* child setup + user_data */ G_SPAWN_LEAVE_DESCRIPTORS_OPEN),
child_setup_cb, NULL,
&child_pid, &child_pid,
&local_error)) &local_error))
{ {
......
...@@ -45,8 +45,7 @@ pv_bwrap_run_sync (FlatpakBwrap *bwrap, ...@@ -45,8 +45,7 @@ pv_bwrap_run_sync (FlatpakBwrap *bwrap,
g_autofree gchar *errors = NULL; g_autofree gchar *errors = NULL;
guint i; guint i;
g_autoptr(GString) command = g_string_new (""); g_autoptr(GString) command = g_string_new ("");
void (*child_setup) (gpointer) = NULL; GArray *child_setup_data = NULL;
gpointer child_setup_data = NULL;
g_return_val_if_fail (bwrap != NULL, FALSE); g_return_val_if_fail (bwrap != NULL, FALSE);
g_return_val_if_fail (bwrap->argv->len >= 2, FALSE); g_return_val_if_fail (bwrap->argv->len >= 2, FALSE);
...@@ -69,18 +68,19 @@ pv_bwrap_run_sync (FlatpakBwrap *bwrap, ...@@ -69,18 +68,19 @@ pv_bwrap_run_sync (FlatpakBwrap *bwrap,
} }
if (bwrap->fds != NULL && bwrap->fds->len > 0) if (bwrap->fds != NULL && bwrap->fds->len > 0)
{ child_setup_data = bwrap->fds;
child_setup = flatpak_bwrap_child_setup_cb;
child_setup_data = bwrap->fds;
}
g_debug ("run:%s", command->str); g_debug ("run:%s", command->str);
/* We use LEAVE_DESCRIPTORS_OPEN to work around a deadlock in older GLib,
* see flatpak_close_fds_workaround */
if (!g_spawn_sync (NULL, /* cwd */ if (!g_spawn_sync (NULL, /* cwd */
(char **) bwrap->argv->pdata, (char **) bwrap->argv->pdata,
bwrap->envp, bwrap->envp,
G_SPAWN_SEARCH_PATH, (G_SPAWN_SEARCH_PATH |
child_setup, child_setup_data, G_SPAWN_LEAVE_DESCRIPTORS_OPEN),
flatpak_bwrap_child_setup_cb,
child_setup_data,
&output, &output,
&errors, &errors,
&exit_status, &exit_status,
......
...@@ -35,6 +35,12 @@ ...@@ -35,6 +35,12 @@
#include "flatpak-utils-base-private.h" #include "flatpak-utils-base-private.h"
#include "flatpak-utils-private.h" #include "flatpak-utils-private.h"
static void
child_setup_cb (gpointer user_data)
{
flatpak_close_fds_workaround (3);
}
/** /**
* pv_avoid_gvfs: * pv_avoid_gvfs:
* *
...@@ -228,11 +234,14 @@ pv_capture_output (const char * const * argv, ...@@ -228,11 +234,14 @@ pv_capture_output (const char * const * argv,
g_debug ("run:%s", command->str); g_debug ("run:%s", command->str);
/* We use LEAVE_DESCRIPTORS_OPEN to work around a deadlock in older GLib,
* see flatpak_close_fds_workaround */
if (!g_spawn_sync (NULL, /* cwd */ if (!g_spawn_sync (NULL, /* cwd */
(char **) argv, (char **) argv,
NULL, /* env */ NULL, /* env */
G_SPAWN_SEARCH_PATH, (G_SPAWN_SEARCH_PATH |
NULL, NULL, /* child setup */ G_SPAWN_LEAVE_DESCRIPTORS_OPEN),
child_setup_cb, NULL,
&output, &output,
&errors, &errors,
&wait_status, &wait_status,
......
...@@ -136,11 +136,13 @@ check_bwrap (const char *tools_dir, ...@@ -136,11 +136,13 @@ check_bwrap (const char *tools_dir,
bwrap_test_argv[0] = bwrap_executable; bwrap_test_argv[0] = bwrap_executable;
/* We use LEAVE_DESCRIPTORS_OPEN to work around a deadlock in older GLib,
* see flatpak_close_fds_workaround */
if (!g_spawn_sync (NULL, /* cwd */ if (!g_spawn_sync (NULL, /* cwd */
(gchar **) bwrap_test_argv, (gchar **) bwrap_test_argv,
NULL, /* environ */ NULL, /* environ */
G_SPAWN_DEFAULT, G_SPAWN_LEAVE_DESCRIPTORS_OPEN,
NULL, NULL, /* child setup */ flatpak_bwrap_child_setup_cb, NULL,
&child_stdout, &child_stdout,
&child_stderr, &child_stderr,
&wait_status, &wait_status,
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment