mirror of
https://git.savannah.gnu.org/git/make.git
synced 2025-01-12 08:40:55 +00:00
[SV 66499] Detect jobserver values that are too large
Set the jobserver pipe to non-blocking before writing tokens; if a token write fails the user's jobserver value is too large so fail. Original implementation: Dmitry Goncharov <dgoncharov@users.sf.net> * src/posixos.c (set_blocking): Split into force_blocking() which always enables/disables blocking; set_blocking() may call it. (jobserver_setup): Set the write side of the pipe to non-blocking before writing tokens. If it fails with EAGAIN we know the pipe is full: create a fatal error. * tests/scripts/features/jobserver: Test a too-large jobserver.
This commit is contained in:
parent
f12a4fddce
commit
d523661ce2
2 changed files with 32 additions and 6 deletions
|
@ -122,10 +122,8 @@ make_job_rfd ()
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
set_blocking (int fd, int blocking)
|
force_blocking (int fd, int blocking)
|
||||||
{
|
{
|
||||||
/* If we're not using pselect() don't change the blocking. */
|
|
||||||
#ifdef HAVE_PSELECT
|
|
||||||
int flags;
|
int flags;
|
||||||
EINTRLOOP (flags, fcntl (fd, F_GETFL));
|
EINTRLOOP (flags, fcntl (fd, F_GETFL));
|
||||||
if (flags >= 0)
|
if (flags >= 0)
|
||||||
|
@ -136,6 +134,14 @@ set_blocking (int fd, int blocking)
|
||||||
if (r < 0)
|
if (r < 0)
|
||||||
pfatal_with_name ("fcntl(O_NONBLOCK)");
|
pfatal_with_name ("fcntl(O_NONBLOCK)");
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
set_blocking (int fd, int blocking)
|
||||||
|
{
|
||||||
|
/* If we're not using pselect() don't change the blocking. */
|
||||||
|
#ifdef HAVE_PSELECT
|
||||||
|
force_blocking (fd, blocking);
|
||||||
#else
|
#else
|
||||||
(void) fd;
|
(void) fd;
|
||||||
(void) blocking;
|
(void) blocking;
|
||||||
|
@ -145,7 +151,7 @@ set_blocking (int fd, int blocking)
|
||||||
unsigned int
|
unsigned int
|
||||||
jobserver_setup (int slots, const char *style)
|
jobserver_setup (int slots, const char *style)
|
||||||
{
|
{
|
||||||
int r;
|
int r, k;
|
||||||
|
|
||||||
/* This function sets up the root jobserver. */
|
/* This function sets up the root jobserver. */
|
||||||
job_root = 1;
|
job_root = 1;
|
||||||
|
@ -211,12 +217,21 @@ jobserver_setup (int slots, const char *style)
|
||||||
if (make_job_rfd () < 0)
|
if (make_job_rfd () < 0)
|
||||||
pfatal_with_name (_("duping jobs pipe"));
|
pfatal_with_name (_("duping jobs pipe"));
|
||||||
|
|
||||||
while (slots--)
|
/* Set the write side of the pipe to non blocking in case the number of
|
||||||
|
slots specified by the user exceeds pipe capacity. */
|
||||||
|
force_blocking (job_fds[1], 0);
|
||||||
|
for (k = 0; k < slots; ++k)
|
||||||
{
|
{
|
||||||
EINTRLOOP (r, write (job_fds[1], &token, 1));
|
EINTRLOOP (r, write (job_fds[1], &token, 1));
|
||||||
if (r != 1)
|
if (r != 1)
|
||||||
pfatal_with_name (_("init jobserver pipe"));
|
{
|
||||||
|
if (errno != EAGAIN)
|
||||||
|
pfatal_with_name (_("init jobserver pipe"));
|
||||||
|
|
||||||
|
ONN (fatal, NILF, _("requested job count (%d) is larger than system limit (%d)"), slots+1, k);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
force_blocking (job_fds[1], 1);
|
||||||
|
|
||||||
/* When using pselect() we want the read to be non-blocking. */
|
/* When using pselect() we want the read to be non-blocking. */
|
||||||
set_blocking (job_fds[0], 0);
|
set_blocking (job_fds[0], 0);
|
||||||
|
|
|
@ -211,4 +211,15 @@ all:;@echo "$$MAKEFLAGS"
|
||||||
run_make_test(q!all:;@echo hi!, "", "#MAKE#: cannot open jobserver nosuchfile: $ERR_no_such_file\n#MAKE#: $j1err\nhi\n");
|
run_make_test(q!all:;@echo hi!, "", "#MAKE#: cannot open jobserver nosuchfile: $ERR_no_such_file\n#MAKE#: $j1err\nhi\n");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if ($port_type eq 'UNIX') {
|
||||||
|
# sv 66499. The specified number of jobs exceeds pipe capacity.
|
||||||
|
run_make_test(q!
|
||||||
|
all:; $(info hello, world)
|
||||||
|
!, '-j688777', '/requested job count \(688777\) is larger than system limit/', 512);
|
||||||
|
|
||||||
|
run_make_test(q!
|
||||||
|
all:; $(info hello, world)
|
||||||
|
!, '-j688777 --jobserver-style=pipe', '/requested job count \(688777\) is larger than system limit/', 512);
|
||||||
|
}
|
||||||
|
|
||||||
1;
|
1;
|
||||||
|
|
Loading…
Reference in a new issue