mirror of
https://gitlab.gnome.org/GNOME/glib.git
synced 2025-04-02 13:53:06 +02:00
gspawn: Port to g_poll() from select()
This removes the limitation of select() that only FDs with values lower than FD_SETSIZE can be used. Previously, if the out/err pipe FDs had high values (which could happen if a large process, like Firefox, was spawning subprocesses while having a lot of FDs open), GLib would abort due to an assertion failure in libc. Signed-off-by: Philip Withnall <withnall@endlessm.com> Fixes: #954
This commit is contained in:
parent
5e17a98d19
commit
a7242d4a5e
@ -372,7 +372,6 @@ g_spawn_sync (const gchar *working_directory,
|
|||||||
gint outpipe = -1;
|
gint outpipe = -1;
|
||||||
gint errpipe = -1;
|
gint errpipe = -1;
|
||||||
GPid pid;
|
GPid pid;
|
||||||
fd_set fds;
|
|
||||||
gint ret;
|
gint ret;
|
||||||
GString *outstr = NULL;
|
GString *outstr = NULL;
|
||||||
GString *errstr = NULL;
|
GString *errstr = NULL;
|
||||||
@ -435,16 +434,16 @@ g_spawn_sync (const gchar *working_directory,
|
|||||||
(outpipe >= 0 ||
|
(outpipe >= 0 ||
|
||||||
errpipe >= 0))
|
errpipe >= 0))
|
||||||
{
|
{
|
||||||
FD_ZERO (&fds);
|
/* Any negative FD in the array is ignored, so we can use a fixed length.
|
||||||
if (outpipe >= 0)
|
* We can use UNIX FDs here without worrying about Windows HANDLEs because
|
||||||
FD_SET (outpipe, &fds);
|
* the Windows implementation is entirely in gspawn-win32.c. */
|
||||||
if (errpipe >= 0)
|
GPollFD fds[] =
|
||||||
FD_SET (errpipe, &fds);
|
{
|
||||||
|
{ outpipe, G_IO_IN | G_IO_HUP | G_IO_ERR, 0 },
|
||||||
ret = select (MAX (outpipe, errpipe) + 1,
|
{ errpipe, G_IO_IN | G_IO_HUP | G_IO_ERR, 0 },
|
||||||
&fds,
|
};
|
||||||
NULL, NULL,
|
|
||||||
NULL /* no timeout */);
|
ret = g_poll (fds, G_N_ELEMENTS (fds), -1 /* no timeout */);
|
||||||
|
|
||||||
if (ret < 0)
|
if (ret < 0)
|
||||||
{
|
{
|
||||||
@ -458,13 +457,13 @@ g_spawn_sync (const gchar *working_directory,
|
|||||||
g_set_error (error,
|
g_set_error (error,
|
||||||
G_SPAWN_ERROR,
|
G_SPAWN_ERROR,
|
||||||
G_SPAWN_ERROR_READ,
|
G_SPAWN_ERROR_READ,
|
||||||
_("Unexpected error in select() reading data from a child process (%s)"),
|
_("Unexpected error in reading data from a child process (%s)"),
|
||||||
g_strerror (errsv));
|
g_strerror (errsv));
|
||||||
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (outpipe >= 0 && FD_ISSET (outpipe, &fds))
|
if (outpipe >= 0 && fds[0].revents != 0)
|
||||||
{
|
{
|
||||||
switch (read_data (outstr, outpipe, error))
|
switch (read_data (outstr, outpipe, error))
|
||||||
{
|
{
|
||||||
@ -483,7 +482,7 @@ g_spawn_sync (const gchar *working_directory,
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (errpipe >= 0 && FD_ISSET (errpipe, &fds))
|
if (errpipe >= 0 && fds[1].revents != 0)
|
||||||
{
|
{
|
||||||
switch (read_data (errstr, errpipe, error))
|
switch (read_data (errstr, errpipe, error))
|
||||||
{
|
{
|
||||||
|
Loading…
x
Reference in New Issue
Block a user