mirror of
https://gitlab.gnome.org/GNOME/glib.git
synced 2025-04-20 14:19:16 +02:00
gspawn: avoid race due to retry with EINTR on close()
Retry on EINTR is wrong on many OS, including Linux. See the comment in g_close() why that is. As we cannot use g_close() after fork, we had safe_close(). This had the wrong retry loop on EINTR. Drop that. This was especially problematic since commit 6f46294227f8 ('gspawn: Don’t use g_close() in async-signal-safe context'). Before, safe_close() was only called after fork, where there is only one thread and there is no concern about a race. This patch only exists for easier backporting of the bugfix. The code will be reworked further next. Fixes: 6f46294227f8 ('gspawn: Don’t use g_close() in async-signal-safe context')
This commit is contained in:
parent
1936516268
commit
f0bcb7f79c
@ -162,7 +162,7 @@ extern char **environ;
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
|
|
||||||
static gint safe_close (gint fd);
|
static void safe_close (gint fd);
|
||||||
|
|
||||||
static gint g_execute (const gchar *file,
|
static gint g_execute (const gchar *file,
|
||||||
gchar **argv,
|
gchar **argv,
|
||||||
@ -1340,16 +1340,21 @@ dupfd_cloexec (int old_fd, int new_fd_min)
|
|||||||
|
|
||||||
/* This function is called between fork() and exec() and hence must be
|
/* This function is called between fork() and exec() and hence must be
|
||||||
* async-signal-safe (see signal-safety(7)). */
|
* async-signal-safe (see signal-safety(7)). */
|
||||||
static gint
|
static void
|
||||||
safe_close (gint fd)
|
safe_close (gint fd)
|
||||||
{
|
{
|
||||||
gint ret;
|
/* Note that this function is (also) called after fork(), so it cannot use
|
||||||
|
* g_close().
|
||||||
do
|
* Note that it is however called both from the parent and the child
|
||||||
ret = close (fd);
|
* process.
|
||||||
while (ret < 0 && errno == EINTR);
|
*
|
||||||
|
* This function returns no error, because there is nothing what the caller
|
||||||
return ret;
|
* could do with that information. That is even the case for EINTR. See
|
||||||
|
* g_close() about the specialty of EINTR and why that is correct.
|
||||||
|
* If g_close() ever gets extended to handle EINTR specially, then this place
|
||||||
|
* and all other direct calls to close() need updating.
|
||||||
|
*/
|
||||||
|
close (fd);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* This function is called between fork() and exec() and hence must be
|
/* This function is called between fork() and exec() and hence must be
|
||||||
@ -1358,7 +1363,7 @@ G_GNUC_UNUSED static int
|
|||||||
close_func (void *data, int fd)
|
close_func (void *data, int fd)
|
||||||
{
|
{
|
||||||
if (fd >= GPOINTER_TO_INT (data))
|
if (fd >= GPOINTER_TO_INT (data))
|
||||||
(void) safe_close (fd);
|
safe_close (fd);
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user