diff -Naur make-3.81-old/main.c make-3.81-new/main.c
--- make-3.81-old/main.c	2006-03-19 18:36:37.000000000 -0800
+++ make-3.81-new/main.c	2010-10-16 08:28:29.000000000 -0700
@@ -229,6 +229,7 @@
 
 int job_fds[2] = { -1, -1 };
 int job_rfd = -1;
+static int jobserver_fds_invalid_flag = 0;
 
 /* Maximum load average at which multiple jobs will be run.
    Negative values mean unlimited, while zero means limit to
@@ -416,6 +417,8 @@
     { 'W', string, (char *) &new_files, 0, 0, 0, 0, 0, "what-if" },
     { CHAR_MAX+4, flag, (char *) &warn_undefined_variables_flag, 1, 1, 0, 0, 0,
       "warn-undefined-variables" },
+    { CHAR_MAX+5, flag, (char *) &jobserver_fds_invalid_flag, 1, 1, 0, 0, 0,
+      "jobserver-fds-invalid" },
     { 0, 0, 0, 0, 0, 0, 0, 0, 0 }
   };
 
@@ -1648,20 +1651,26 @@
 
   if (jobserver_fds)
   {
-    char *cp;
-    unsigned int ui;
-
-    for (ui=1; ui < jobserver_fds->idx; ++ui)
-      if (!streq (jobserver_fds->list[0], jobserver_fds->list[ui]))
-        fatal (NILF, _("internal error: multiple --jobserver-fds options"));
-
-    /* Now parse the fds string and make sure it has the proper format.  */
-
-    cp = jobserver_fds->list[0];
+    /* Skip if jobserver-fds isn't valid.  */
+    if (!jobserver_fds_invalid_flag)
+      {
+	char *cp;
+	unsigned int ui;
 
-    if (sscanf (cp, "%d,%d", &job_fds[0], &job_fds[1]) != 2)
-      fatal (NILF,
-             _("internal error: invalid --jobserver-fds string `%s'"), cp);
+	for (ui=1; ui < jobserver_fds->idx; ++ui)
+	  if (!streq (jobserver_fds->list[0], jobserver_fds->list[ui]))
+	    fatal (NILF, _("internal error: multiple --jobserver-fds options"));
+
+	/* Now parse the fds string and make sure it has the proper
+	   format.  */
+
+	cp = jobserver_fds->list[0];
+
+	if (sscanf (cp, "%d,%d", &job_fds[0], &job_fds[1]) != 2)
+	  fatal (NILF,
+		 _("internal error: invalid --jobserver-fds string `%s'"),
+		 cp); 
+      }
 
     /* The combination of a pipe + !job_slots means we're using the
        jobserver.  If !job_slots and we don't have a pipe, we can start
@@ -1676,11 +1685,15 @@
     /* Create a duplicate pipe, that will be closed in the SIGCHLD
        handler.  If this fails with EBADF, the parent has closed the pipe
        on us because it didn't think we were a submake.  If so, print a
-       warning then default to -j1.  */
+       warning then default to -j1.
 
-    else if ((job_rfd = dup (job_fds[0])) < 0)
+       If jobserver_fds isn't valid, also print a warning then default
+       to -j1.  */
+
+    else if (jobserver_fds_invalid_flag
+	     || (job_rfd = dup (job_fds[0])) < 0)
       {
-        if (errno != EBADF)
+        if (!jobserver_fds_invalid_flag && errno != EBADF)
           pfatal_with_name (_("dup jobserver"));
 
         error (NILF,
@@ -1690,8 +1703,13 @@
 
     if (job_slots > 0)
       {
-        close (job_fds[0]);
-        close (job_fds[1]);
+	/* Don't close job_fds if they aren't valid.  Otherwise, we may
+	   close the wrong files.  */
+	if (!jobserver_fds_invalid_flag)
+	  {
+	    close (job_fds[0]);
+	    close (job_fds[1]);
+	  }
         job_fds[0] = job_fds[1] = -1;
         free (jobserver_fds->list);
         free (jobserver_fds);
@@ -1988,13 +2006,20 @@
 		  }
 	    }
 
-          /* Add -o option for the stdin temporary file, if necessary.  */
-          if (stdin_nm)
+          /* Add --jobserver-fds-invalid and -o option for the stdin
+	     temporary file, if necessary.  */
+          if (stdin_nm || jobserver_fds_invalid_flag)
             {
-              nargv = (char **) xmalloc ((nargc + 2) * sizeof (char *));
+	      int count = 2;
+	      if (stdin_nm && jobserver_fds_invalid_flag)
+		count++;
+              nargv = (char **) xmalloc ((nargc + count) * sizeof (char *));
               bcopy ((char *) argv, (char *) nargv, argc * sizeof (char *));
-              nargv[nargc++] = concat ("-o", stdin_nm, "");
-              nargv[nargc] = 0;
+	      if (stdin_nm)
+		nargv[nargc++] = concat ("-o", stdin_nm, "");
+	      if (jobserver_fds_invalid_flag)
+		nargv[nargc++] = "--jobserver-fds-invalid";
+	      nargv[nargc] = 0;
             }
 
 	  if (directories != 0 && directories->idx > 0)
@@ -2988,7 +3013,7 @@
      have written all our tokens so do that now.  If tokens are left
      after any other error code, that's bad.  */
 
-  if (job_fds[0] != -1 && jobserver_tokens)
+  if (job_fds[0] >= 0 && jobserver_tokens)
     {
       if (status != 2)
         error (NILF,
@@ -3008,7 +3033,7 @@
 
   /* Sanity: If we're the master, were all the tokens written back?  */
 
-  if (master_job_slots)
+  if (job_fds[0] >= 0 && master_job_slots)
     {
       /* We didn't write one for ourself, so start at 1.  */
       unsigned int tcnt = 1;
@@ -3025,6 +3050,9 @@
                tcnt, master_job_slots);
 
       close (job_fds[0]);
+
+      /* job_fds aren't valid now.  */
+      jobserver_fds_invalid_flag = 1;
     }
 }
 
