summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorPaul Smith <psmith@gnu.org>2022-10-24 00:48:47 -0400
committerPaul Smith <psmith@gnu.org>2022-10-24 01:50:12 -0400
commitd18a87d0a40f326d219c7dbabc50e824956f4497 (patch)
tree164e3ea4712d603c569ba63278e80cce262076df
parent41c35f2ffe58a5b90b63256a199d674696f8a743 (diff)
downloadmake-git-d18a87d0a40f326d219c7dbabc50e824956f4497.tar.gz
[SV 63260] Don't recurse forever if setup_tmpfile() fails
If we fail during setup_tmpfile() we'll try to write an error, which will invoke setup_tmpfile() again, etc. Avoid infinite recursion. Original patch by Dmitry Goncharov <dgoncharov@users.sf.net> * src/output.c (setup_tmpfile): Remember we're in this function and return immediately if we enter it during recursion. (message): Remember the starting location and use that instead of fmtbuf.buffer. (error): Ditto. (fatal): Ditto.
-rw-r--r--src/output.c34
1 files changed, 24 insertions, 10 deletions
diff --git a/src/output.c b/src/output.c
index a88f537a..43eb2f06 100644
--- a/src/output.c
+++ b/src/output.c
@@ -202,7 +202,16 @@ output_tmpfd (void)
static void
setup_tmpfile (struct output *out)
{
- unsigned int io_state = check_io_state ();
+ static unsigned int in_setup = 0;
+ unsigned int io_state;
+
+ /* If something fails during setup we might recurse back into this function
+ while writing errors. Make sure we don't do so infinitely. */
+ if (in_setup)
+ return;
+ in_setup = 1;
+
+ io_state = check_io_state ();
if (NONE_SET (io_state, IO_STDOUT_OK|IO_STDERR_OK))
{
@@ -234,6 +243,7 @@ setup_tmpfile (struct output *out)
}
}
+ in_setup = 0;
return;
/* If we failed to create a temp file, disable output sync going forward. */
@@ -241,6 +251,7 @@ setup_tmpfile (struct output *out)
output_close (out);
output_sync = OUTPUT_SYNC_NONE;
osync_clear ();
+ in_setup = 0;
}
/* Synchronize the output of jobs in -j mode to keep the results of
@@ -398,10 +409,11 @@ void
message (int prefix, size_t len, const char *fmt, ...)
{
va_list args;
+ char *start;
char *p;
len += strlen (fmt) + strlen (program) + INTSTR_LENGTH + 4 + 1 + 1;
- p = get_buffer (len);
+ start = p = get_buffer (len);
if (prefix)
{
@@ -418,8 +430,8 @@ message (int prefix, size_t len, const char *fmt, ...)
strcat (p, "\n");
- assert (fmtbuf.buffer[len-1] == '\0');
- outputs (0, fmtbuf.buffer);
+ assert (start[len-1] == '\0');
+ outputs (0, start);
}
/* Print an error message. */
@@ -428,12 +440,13 @@ void
error (const floc *flocp, size_t len, const char *fmt, ...)
{
va_list args;
+ char *start;
char *p;
len += (strlen (fmt) + strlen (program)
+ (flocp && flocp->filenm ? strlen (flocp->filenm) : 0)
+ INTSTR_LENGTH + 4 + 1 + 1);
- p = get_buffer (len);
+ start = p = get_buffer (len);
if (flocp && flocp->filenm)
sprintf (p, "%s:%lu: ", flocp->filenm, flocp->lineno + flocp->offset);
@@ -449,8 +462,8 @@ error (const floc *flocp, size_t len, const char *fmt, ...)
strcat (p, "\n");
- assert (fmtbuf.buffer[len-1] == '\0');
- outputs (1, fmtbuf.buffer);
+ assert (start[len-1] == '\0');
+ outputs (1, start);
}
/* Print an error message and exit. */
@@ -460,12 +473,13 @@ fatal (const floc *flocp, size_t len, const char *fmt, ...)
{
va_list args;
const char *stop = _(". Stop.\n");
+ char *start;
char *p;
len += (strlen (fmt) + strlen (program)
+ (flocp && flocp->filenm ? strlen (flocp->filenm) : 0)
+ INTSTR_LENGTH + 8 + strlen (stop) + 1);
- p = get_buffer (len);
+ start = p = get_buffer (len);
if (flocp && flocp->filenm)
sprintf (p, "%s:%lu: *** ", flocp->filenm, flocp->lineno + flocp->offset);
@@ -481,8 +495,8 @@ fatal (const floc *flocp, size_t len, const char *fmt, ...)
strcat (p, stop);
- assert (fmtbuf.buffer[len-1] == '\0');
- outputs (1, fmtbuf.buffer);
+ assert (start[len-1] == '\0');
+ outputs (1, start);
die (MAKE_FAILURE);
}