diff -Nrup a/job.c b/job.c --- a/job.c 2015-10-29 17:19:17.209430335 -0400 +++ b/job.c 2015-10-29 18:24:04.452169281 -0400 @@ -1033,7 +1033,7 @@ free_child (struct child *child) EINTRLOOP (r, write (job_fds[1], &token, 1)); if (r != 1) - pfatal_with_name (_("write jobserver")); + pfatal_with_name_err (_("write jobserver"), errno); DB (DB_JOBS, (_("Released token for child %p (%s).\n"), child, child->file->name)); @@ -2008,6 +2008,7 @@ new_job (struct file *file) #else /* Set interruptible system calls, and read() for a job token. */ set_child_handler_action_flags (1, waiting_jobs != NULL); + errno = 0; got_token = read (job_rfd, &token, 1); saved_errno = errno; set_child_handler_action_flags (0, waiting_jobs != NULL); @@ -2024,10 +2025,14 @@ new_job (struct file *file) #ifndef WINDOWS32 /* If the error _wasn't_ expected (EINTR or EBADF), punt. Otherwise, go back and reap_children(), and try again. */ - errno = saved_errno; - if (errno != EINTR && errno != EBADF) - pfatal_with_name (_("read jobs pipe")); - if (errno == EBADF) + if (saved_errno != EINTR && saved_errno != EBADF) + { + if (got_token == 0) + O (fatal, NILF, _("read jobs pipe EOF")); + else + pfatal_with_name_err (_("read jobs pipe"), saved_errno); + } + if (saved_errno == EBADF) DB (DB_JOBS, ("Read returned EBADF.\n")); #endif } @@ -2170,7 +2175,9 @@ load_too_high (void) O (error, NILF, _("cannot enforce load limits on this operating system")); else - perror_with_name (_("cannot enforce load limit: "), "getloadavg"); + perror_with_name_err (_("cannot enforce load limit: "), + "getloadavg", errno); + } lossage = errno; load = 0; diff -Nrup a/main.c b/main.c --- a/main.c 2015-10-29 17:19:17.198430225 -0400 +++ b/main.c 2015-10-29 19:12:15.599567039 -0400 @@ -1564,7 +1564,7 @@ main (int argc, char **argv, char **envp || (job_rfd = dup (job_fds[0])) < 0) { if (errno != EBADF) - pfatal_with_name (_("dup jobserver")); + pfatal_with_name_err (_("dup jobserver"), errno); O (error, NILF, _("warning: jobserver unavailable: using -j1. Add '+' to parent make rule.")); @@ -1777,13 +1777,13 @@ main (int argc, char **argv, char **envp strcat (template, DEFAULT_TMPFILE); outfile = output_tmpfile (&stdin_nm, template); if (outfile == 0) - pfatal_with_name (_("fopen (temporary file)")); + pfatal_with_name_err (_("fopen (temporary file)"), errno); while (!feof (stdin) && ! ferror (stdin)) { char buf[2048]; unsigned int n = fread (buf, 1, sizeof (buf), stdin); if (n > 0 && fwrite (buf, 1, n, outfile) != n) - pfatal_with_name (_("fwrite (temporary file)")); + pfatal_with_name_err (_("fwrite (temporary file)"), errno); } fclose (outfile); @@ -2019,7 +2019,8 @@ main (int argc, char **argv, char **envp char c = '+'; if (pipe (job_fds) < 0 || (job_rfd = dup (job_fds[0])) < 0) - pfatal_with_name (_("creating jobs pipe")); + pfatal_with_name_err (_("creating jobs pipe"), errno); + #endif /* Every make assumes that it always has one job it can run. For the @@ -2039,7 +2040,7 @@ main (int argc, char **argv, char **envp EINTRLOOP (r, write (job_fds[1], &c, 1)); if (r != 1) - pfatal_with_name (_("init jobserver pipe")); + pfatal_with_name_err (_("init jobserver pipe"), errno); } #endif @@ -2464,7 +2465,7 @@ main (int argc, char **argv, char **envp /* If there is a temp file from reading a makefile from stdin, get rid of it now. */ if (stdin_nm && unlink (stdin_nm) < 0 && errno != ENOENT) - perror_with_name (_("unlink (temporary file): "), stdin_nm); + perror_with_name_err (_("unlink (temporary file): "), stdin_nm, errno); /* If there were no command-line goals, use the default. */ if (goals == 0) diff -Nrup a/makeint.h b/makeint.h --- a/makeint.h 2015-10-29 17:19:17.168429926 -0400 +++ b/makeint.h 2015-10-29 18:30:44.364147393 -0400 @@ -458,6 +458,8 @@ void fatal (const gmk_floc *flocp, size_ void die (int) __attribute__ ((noreturn)); void pfatal_with_name (const char *) __attribute__ ((noreturn)); void perror_with_name (const char *, const char *); +void pfatal_with_name_err (const char *, int errnum) __attribute__ ((noreturn)); +void perror_with_name_err (const char *, const char *, int errnum); #define xstrlen(_s) ((_s)==NULL ? 0 : strlen (_s)) void *xmalloc (unsigned int); void *xcalloc (unsigned int); diff -Nrup a/output.c b/output.c --- a/output.c 2014-10-05 12:24:51.000000000 -0400 +++ b/output.c 2015-10-29 19:04:05.332692965 -0400 @@ -705,6 +705,13 @@ fatal (const gmk_floc *flocp, size_t len /* Print an error message from errno. */ void +perror_with_name_err (const char *str, const char *name, int errnum) +{ + const char *err = strerror (errnum); + OSSS (error, NILF, _("%s%s: %s"), str, name, err); +} + +void perror_with_name (const char *str, const char *name) { const char *err = strerror (errno); @@ -714,6 +721,15 @@ perror_with_name (const char *str, const /* Print an error message from errno and exit. */ void +pfatal_with_name_err (const char *name, int errnum) +{ + const char *err = strerror (errnum); + OSS (fatal, NILF, _("%s: %s"), name, err); + + /* NOTREACHED */ +} + +void pfatal_with_name (const char *name) { const char *err = strerror (errno);