mirror of
https://salsa.debian.org/srivasta/make-dfsg.git
synced 2024-12-30 16:49:35 +00:00
Ensure error messages are printed with sync'd output.
Enhance the child_error() function so that it will write error output to the child's sync output buffer, if it exists. If it doesn't the output goes to stdout/stderr.
This commit is contained in:
parent
441b643355
commit
f88eb23b02
6 changed files with 145 additions and 23 deletions
|
@ -1,5 +1,12 @@
|
||||||
2013-04-28 Paul Smith <psmith@gnu.org>
|
2013-04-28 Paul Smith <psmith@gnu.org>
|
||||||
|
|
||||||
|
* makeint.h (message_s, error_s): Functions that print to strings
|
||||||
|
rather than directly to files.
|
||||||
|
* misc.c (message_s, error_s): Create them.
|
||||||
|
* job.c (child_error): Print error messages to the output sync
|
||||||
|
logs, if one exists, rather then directly to the terminal.
|
||||||
|
(reap_children): Move the per-line sync after child_error().
|
||||||
|
|
||||||
* configure.ac: Remove support for pre-ANSI variadic function calls.
|
* configure.ac: Remove support for pre-ANSI variadic function calls.
|
||||||
* makeint.h: Ditto.
|
* makeint.h: Ditto.
|
||||||
* misc.c: Ditto.
|
* misc.c: Ditto.
|
||||||
|
|
75
job.c
75
job.c
|
@ -467,19 +467,46 @@ is_bourne_compatible_shell (const char *path)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* Write a message relating to a child. Write it to the child's output
|
||||||
|
sync file if present, otherwise to the terminal. */
|
||||||
|
|
||||||
|
static void
|
||||||
|
child_out (const struct child *child, const char *msg, int out)
|
||||||
|
{
|
||||||
|
int outfd = out ? child->outfd : child->errfd;
|
||||||
|
|
||||||
|
if (outfd >= 0)
|
||||||
|
{
|
||||||
|
lseek (outfd, 0, SEEK_END);
|
||||||
|
write (outfd, msg, strlen (msg));
|
||||||
|
write (outfd, "\n", 1);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
FILE *outf = out ? stdout : stderr;
|
||||||
|
|
||||||
|
fputs (msg, outf);
|
||||||
|
putc ('\n', outf);
|
||||||
|
fflush (outf);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/* Write an error message describing the exit status given in
|
/* Write an error message describing the exit status given in
|
||||||
EXIT_CODE, EXIT_SIG, and COREDUMP, for the target TARGET_NAME.
|
EXIT_CODE, EXIT_SIG, and COREDUMP, for the target TARGET_NAME.
|
||||||
Append "(ignored)" if IGNORED is nonzero. */
|
Append "(ignored)" if IGNORED is nonzero. */
|
||||||
|
|
||||||
static void
|
static void
|
||||||
child_error (const struct file *file,
|
child_error (const struct child *child,
|
||||||
int exit_code, int exit_sig, int coredump, int ignored)
|
int exit_code, int exit_sig, int coredump, int ignored)
|
||||||
{
|
{
|
||||||
const char *nm;
|
|
||||||
const char *pre = "*** ";
|
const char *pre = "*** ";
|
||||||
const char *post = "";
|
const char *post = "";
|
||||||
const char *dump = "";
|
const char *dump = "";
|
||||||
gmk_floc *flocp = &file->cmds->fileinfo;
|
const struct file *f = child->file;
|
||||||
|
gmk_floc *flocp = &f->cmds->fileinfo;
|
||||||
|
const char *msg;
|
||||||
|
const char *nm;
|
||||||
|
unsigned int l;
|
||||||
|
|
||||||
if (ignored && silent_flag)
|
if (ignored && silent_flag)
|
||||||
return;
|
return;
|
||||||
|
@ -501,18 +528,32 @@ child_error (const struct file *file,
|
||||||
sprintf (a, "%s:%lu", flocp->filenm, flocp->lineno);
|
sprintf (a, "%s:%lu", flocp->filenm, flocp->lineno);
|
||||||
nm = a;
|
nm = a;
|
||||||
}
|
}
|
||||||
message (0, _("%s: recipe for target '%s' failed"), nm, file->name);
|
|
||||||
|
msg = message_s (strlen (nm) + strlen (f->name),
|
||||||
|
0, _("%s: recipe for target '%s' failed"), nm, f->name);
|
||||||
|
child_out (child, msg, 1);
|
||||||
|
|
||||||
|
l = strlen (pre) + strlen (f->name) + strlen (post);
|
||||||
|
|
||||||
#ifdef VMS
|
#ifdef VMS
|
||||||
if (!(exit_code & 1))
|
if (exit_code & 1 != 0)
|
||||||
error (NILF, _("%s[%s] Error 0x%x%s"), pre, file->name, exit_code, post);
|
return;
|
||||||
|
|
||||||
|
msg = error_s (l + INTEGER_LENGTH, NILF, _("%s[%s] Error 0x%x%s"),
|
||||||
|
pre, f->name, exit_code, post);
|
||||||
#else
|
#else
|
||||||
if (exit_sig == 0)
|
if (exit_sig == 0)
|
||||||
error (NILF, _("%s[%s] Error %d%s"), pre, file->name, exit_code, post);
|
msg = error_s (l + INTEGER_LENGTH, NILF, _("%s[%s] Error %d%s"),
|
||||||
|
pre, f->name, exit_code, post);
|
||||||
else
|
else
|
||||||
error (NILF, _("%s[%s] %s%s%s"),
|
{
|
||||||
pre, file->name, strsignal (exit_sig), dump, post);
|
const char *s = strsignal (exit_sig);
|
||||||
|
msg = error_s (l + strlen (s) + strlen (dump),
|
||||||
|
NILF, _("%s[%s] %s%s%s"), pre, f->name, s, dump, post);
|
||||||
|
}
|
||||||
#endif /* VMS */
|
#endif /* VMS */
|
||||||
|
|
||||||
|
child_out (child, msg, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -1006,11 +1047,6 @@ reap_children (int block, int err)
|
||||||
c->sh_batch_file = NULL;
|
c->sh_batch_file = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef OUTPUT_SYNC
|
|
||||||
if (output_sync == OUTPUT_SYNC_JOB)
|
|
||||||
sync_output (c);
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/* If this child had the good stdin, say it is now free. */
|
/* If this child had the good stdin, say it is now free. */
|
||||||
if (c->good_stdin)
|
if (c->good_stdin)
|
||||||
good_stdin_used = 0;
|
good_stdin_used = 0;
|
||||||
|
@ -1024,7 +1060,7 @@ reap_children (int block, int err)
|
||||||
static int delete_on_error = -1;
|
static int delete_on_error = -1;
|
||||||
|
|
||||||
if (!dontcare)
|
if (!dontcare)
|
||||||
child_error (c->file, exit_code, exit_sig, coredump, 0);
|
child_error (c, exit_code, exit_sig, coredump, 0);
|
||||||
|
|
||||||
c->file->update_status = 2;
|
c->file->update_status = 2;
|
||||||
if (delete_on_error == -1)
|
if (delete_on_error == -1)
|
||||||
|
@ -1040,7 +1076,7 @@ reap_children (int block, int err)
|
||||||
if (child_failed)
|
if (child_failed)
|
||||||
{
|
{
|
||||||
/* The commands failed, but we don't care. */
|
/* The commands failed, but we don't care. */
|
||||||
child_error (c->file, exit_code, exit_sig, coredump, 1);
|
child_error (c, exit_code, exit_sig, coredump, 1);
|
||||||
child_failed = 0;
|
child_failed = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1057,6 +1093,11 @@ reap_children (int block, int err)
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
#ifdef OUTPUT_SYNC
|
||||||
|
/* If we're sync'ing per job, write it now. */
|
||||||
|
if (output_sync == OUTPUT_SYNC_JOB)
|
||||||
|
sync_output (c);
|
||||||
|
#endif
|
||||||
/* Check again whether to start remotely.
|
/* Check again whether to start remotely.
|
||||||
Whether or not we want to changes over time.
|
Whether or not we want to changes over time.
|
||||||
Also, start_remote_job may need state set up
|
Also, start_remote_job may need state set up
|
||||||
|
@ -1089,7 +1130,7 @@ reap_children (int block, int err)
|
||||||
|
|
||||||
#ifdef OUTPUT_SYNC
|
#ifdef OUTPUT_SYNC
|
||||||
/* Synchronize parallel output if requested */
|
/* Synchronize parallel output if requested */
|
||||||
if (output_sync > OUTPUT_SYNC_JOB)
|
if (output_sync)
|
||||||
sync_output (c);
|
sync_output (c);
|
||||||
#endif /* OUTPUT_SYNC */
|
#endif /* OUTPUT_SYNC */
|
||||||
|
|
||||||
|
|
|
@ -383,6 +383,10 @@ extern struct rlimit stack_limit;
|
||||||
|
|
||||||
|
|
||||||
const char *concat (unsigned int, ...);
|
const char *concat (unsigned int, ...);
|
||||||
|
const char *message_s (unsigned int length, int prefix, const char *fmt, ...)
|
||||||
|
__attribute__ ((__format__ (__printf__, 3, 4)));
|
||||||
|
const char *error_s (unsigned int length, const gmk_floc *flocp, const char *fmt, ...)
|
||||||
|
__attribute__ ((__format__ (__printf__, 3, 4)));
|
||||||
void message (int prefix, const char *fmt, ...)
|
void message (int prefix, const char *fmt, ...)
|
||||||
__attribute__ ((__format__ (__printf__, 2, 3)));
|
__attribute__ ((__format__ (__printf__, 2, 3)));
|
||||||
void error (const gmk_floc *flocp, const char *fmt, ...)
|
void error (const gmk_floc *flocp, const char *fmt, ...)
|
||||||
|
|
73
misc.c
73
misc.c
|
@ -179,6 +179,79 @@ concat (unsigned int num, ...)
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* If we had a standard-compliant vsnprintf() this would be a lot simpler.
|
||||||
|
Maybe in the future we'll include gnulib's version. */
|
||||||
|
|
||||||
|
/* Return a formatted string buffer. */
|
||||||
|
|
||||||
|
const char *
|
||||||
|
message_s (unsigned int length, int prefix, const char *fmt, ...)
|
||||||
|
{
|
||||||
|
static char *buffer = NULL;
|
||||||
|
static unsigned int bsize = 0;
|
||||||
|
char *bp;
|
||||||
|
va_list args;
|
||||||
|
|
||||||
|
/* Compute the maximum buffer size we'll need, and make sure we have it. */
|
||||||
|
length += strlen (fmt) + strlen (program) + 4 + INTEGER_LENGTH + 1;
|
||||||
|
if (length > bsize)
|
||||||
|
{
|
||||||
|
bsize = length * 2;
|
||||||
|
buffer = xrealloc (buffer, bsize);
|
||||||
|
}
|
||||||
|
|
||||||
|
bp = buffer;
|
||||||
|
if (prefix)
|
||||||
|
{
|
||||||
|
if (makelevel == 0)
|
||||||
|
sprintf (bp, "%s: ", program);
|
||||||
|
else
|
||||||
|
sprintf (bp, "%s[%u]: ", program, makelevel);
|
||||||
|
bp += strlen (buffer);
|
||||||
|
}
|
||||||
|
|
||||||
|
va_start (args, fmt);
|
||||||
|
vsprintf (bp, fmt, args);
|
||||||
|
va_end (args);
|
||||||
|
|
||||||
|
return buffer;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Return a formatted error message in a buffer. */
|
||||||
|
|
||||||
|
const char *
|
||||||
|
error_s (unsigned int length, const gmk_floc *flocp, const char *fmt, ...)
|
||||||
|
{
|
||||||
|
static char *buffer = NULL;
|
||||||
|
static unsigned int bsize = 0;
|
||||||
|
char *bp;
|
||||||
|
va_list args;
|
||||||
|
|
||||||
|
/* Compute the maximum buffer size we'll need, and make sure we have it. */
|
||||||
|
length += (strlen (fmt) + strlen (program) + 4 + INTEGER_LENGTH + 1
|
||||||
|
+ (flocp && flocp->filenm ? strlen (flocp->filenm) : 0));
|
||||||
|
if (length > bsize)
|
||||||
|
{
|
||||||
|
bsize = length * 2;
|
||||||
|
buffer = xrealloc (buffer, bsize);
|
||||||
|
}
|
||||||
|
|
||||||
|
bp = buffer;
|
||||||
|
if (flocp && flocp->filenm)
|
||||||
|
sprintf (bp, "%s:%lu: ", flocp->filenm, flocp->lineno);
|
||||||
|
else if (makelevel == 0)
|
||||||
|
sprintf (bp, "%s: ", program);
|
||||||
|
else
|
||||||
|
sprintf (bp, "%s[%u]: ", program, makelevel);
|
||||||
|
bp += strlen (bp);
|
||||||
|
|
||||||
|
va_start (args, fmt);
|
||||||
|
vsprintf (bp, fmt, args);
|
||||||
|
va_end (args);
|
||||||
|
|
||||||
|
return buffer;
|
||||||
|
}
|
||||||
|
|
||||||
/* Print a message on stdout. */
|
/* Print a message on stdout. */
|
||||||
|
|
||||||
void
|
void
|
||||||
|
|
|
@ -2,6 +2,7 @@
|
||||||
|
|
||||||
* scripts/features/output-sync (output_sync_set): Add tests for
|
* scripts/features/output-sync (output_sync_set): Add tests for
|
||||||
the per-job syntax mode.
|
the per-job syntax mode.
|
||||||
|
(output_sync_set): Test improved error message location.
|
||||||
|
|
||||||
2013-04-15 Paul Smith <psmith@gnu.org>
|
2013-04-15 Paul Smith <psmith@gnu.org>
|
||||||
|
|
||||||
|
|
|
@ -197,14 +197,10 @@ bar: end
|
||||||
#MAKE#[1]: Leaving directory '#PWD#/bar'
|
#MAKE#[1]: Leaving directory '#PWD#/bar'
|
||||||
#MAKE#[1]: Leaving directory '#PWD#/bar'
|
#MAKE#[1]: Leaving directory '#PWD#/bar'
|
||||||
#MAKE#[1]: Entering directory '#PWD#/foo'
|
#MAKE#[1]: Entering directory '#PWD#/foo'
|
||||||
Makefile:20: recipe for target 'foo-fail' failed
|
|
||||||
#MAKE#[1]: Leaving directory '/home/psmith/src/make/make/tests/foo'
|
|
||||||
#MAKE#[1]: Entering directory '/home/psmith/src/make/make/tests/foo'
|
|
||||||
#MAKE#[1]: *** [foo-fail] Error 1
|
|
||||||
#MAKE#[1]: Leaving directory '/home/psmith/src/make/make/tests/foo'
|
|
||||||
#MAKE#[1]: Entering directory '/home/psmith/src/make/make/tests/foo'
|
|
||||||
foo-fail: start
|
foo-fail: start
|
||||||
foo-fail: end
|
foo-fail: end
|
||||||
|
Makefile:20: recipe for target 'foo-fail' failed
|
||||||
|
#MAKE#[1]: *** [foo-fail] Error 1
|
||||||
#MAKE#[1]: Leaving directory '#PWD#/foo'
|
#MAKE#[1]: Leaving directory '#PWD#/foo'
|
||||||
#MAKE#[1]: Leaving directory '#PWD#/foo'
|
#MAKE#[1]: Leaving directory '#PWD#/foo'
|
||||||
#MAKEFILE#:4: recipe for target 'make-foo-fail' failed
|
#MAKEFILE#:4: recipe for target 'make-foo-fail' failed
|
||||||
|
|
Loading…
Reference in a new issue