Home | History | Annotate | Download | only in make-3.81
      1 /* Miscellaneous generic support functions for GNU Make.
      2 Copyright (C) 1988, 1989, 1990, 1991, 1992, 1993, 1994, 1995, 1996, 1997,
      3 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006 Free Software
      4 Foundation, Inc.
      5 This file is part of GNU Make.
      6 
      7 GNU Make is free software; you can redistribute it and/or modify it under the
      8 terms of the GNU General Public License as published by the Free Software
      9 Foundation; either version 2, or (at your option) any later version.
     10 
     11 GNU Make is distributed in the hope that it will be useful, but WITHOUT ANY
     12 WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
     13 A PARTICULAR PURPOSE.  See the GNU General Public License for more details.
     14 
     15 You should have received a copy of the GNU General Public License along with
     16 GNU Make; see the file COPYING.  If not, write to the Free Software
     17 Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.  */
     18 
     19 #include "make.h"
     20 #include "dep.h"
     21 #include "debug.h"
     22 
     23 /* Variadic functions.  We go through contortions to allow proper function
     24    prototypes for both ANSI and pre-ANSI C compilers, and also for those
     25    which support stdarg.h vs. varargs.h, and finally those which have
     26    vfprintf(), etc. and those who have _doprnt... or nothing.
     27 
     28    This fancy stuff all came from GNU fileutils, except for the VA_PRINTF and
     29    VA_END macros used here since we have multiple print functions.  */
     30 
     31 #if USE_VARIADIC
     32 # if HAVE_STDARG_H
     33 #  include <stdarg.h>
     34 #  define VA_START(args, lastarg) va_start(args, lastarg)
     35 # else
     36 #  include <varargs.h>
     37 #  define VA_START(args, lastarg) va_start(args)
     38 # endif
     39 # if HAVE_VPRINTF
     40 #  define VA_PRINTF(fp, lastarg, args) vfprintf((fp), (lastarg), (args))
     41 # else
     42 #  define VA_PRINTF(fp, lastarg, args) _doprnt((lastarg), (args), (fp))
     43 # endif
     44 # define VA_END(args) va_end(args)
     45 #else
     46 /* We can't use any variadic interface! */
     47 # define va_alist a1, a2, a3, a4, a5, a6, a7, a8
     48 # define va_dcl char *a1, *a2, *a3, *a4, *a5, *a6, *a7, *a8;
     49 # define VA_START(args, lastarg)
     50 # define VA_PRINTF(fp, lastarg, args) fprintf((fp), (lastarg), va_alist)
     51 # define VA_END(args)
     52 #endif
     53 
     54 
     55 /* Compare strings *S1 and *S2.
     56    Return negative if the first is less, positive if it is greater,
     57    zero if they are equal.  */
     58 
     59 int
     60 alpha_compare (const void *v1, const void *v2)
     61 {
     62   const char *s1 = *((char **)v1);
     63   const char *s2 = *((char **)v2);
     64 
     65   if (*s1 != *s2)
     66     return *s1 - *s2;
     67   return strcmp (s1, s2);
     68 }
     69 
     70 /* Discard each backslash-newline combination from LINE.
     72    Backslash-backslash-newline combinations become backslash-newlines.
     73    This is done by copying the text at LINE into itself.  */
     74 
     75 void
     76 collapse_continuations (char *line)
     77 {
     78   register char *in, *out, *p;
     79   register int backslash;
     80   register unsigned int bs_write;
     81 
     82   in = strchr (line, '\n');
     83   if (in == 0)
     84     return;
     85 
     86   out = in;
     87   while (out > line && out[-1] == '\\')
     88     --out;
     89 
     90   while (*in != '\0')
     91     {
     92       /* BS_WRITE gets the number of quoted backslashes at
     93 	 the end just before IN, and BACKSLASH gets nonzero
     94 	 if the next character is quoted.  */
     95       backslash = 0;
     96       bs_write = 0;
     97       for (p = in - 1; p >= line && *p == '\\'; --p)
     98 	{
     99 	  if (backslash)
    100 	    ++bs_write;
    101 	  backslash = !backslash;
    102 
    103 	  /* It should be impossible to go back this far without exiting,
    104 	     but if we do, we can't get the right answer.  */
    105 	  if (in == out - 1)
    106 	    abort ();
    107 	}
    108 
    109       /* Output the appropriate number of backslashes.  */
    110       while (bs_write-- > 0)
    111 	*out++ = '\\';
    112 
    113       /* Skip the newline.  */
    114       ++in;
    115 
    116       /* If the newline is quoted, discard following whitespace
    117 	 and any preceding whitespace; leave just one space.  */
    118       if (backslash)
    119 	{
    120 	  in = next_token (in);
    121 	  while (out > line && isblank ((unsigned char)out[-1]))
    122 	    --out;
    123 	  *out++ = ' ';
    124 	}
    125       else
    126 	/* If the newline isn't quoted, put it in the output.  */
    127 	*out++ = '\n';
    128 
    129       /* Now copy the following line to the output.
    130 	 Stop when we find backslashes followed by a newline.  */
    131       while (*in != '\0')
    132 	if (*in == '\\')
    133 	  {
    134 	    p = in + 1;
    135 	    while (*p == '\\')
    136 	      ++p;
    137 	    if (*p == '\n')
    138 	      {
    139 		in = p;
    140 		break;
    141 	      }
    142 	    while (in < p)
    143 	      *out++ = *in++;
    144 	  }
    145 	else
    146 	  *out++ = *in++;
    147     }
    148 
    149   *out = '\0';
    150 }
    151 
    152 /* Print N spaces (used in debug for target-depth).  */
    154 
    155 void
    156 print_spaces (unsigned int n)
    157 {
    158   while (n-- > 0)
    159     putchar (' ');
    160 }
    161 
    162 
    163 /* Return a newly-allocated string whose contents
    165    concatenate those of s1, s2, s3.  */
    166 
    167 char *
    168 concat (const char *s1, const char *s2, const char *s3)
    169 {
    170   unsigned int len1, len2, len3;
    171   char *result;
    172 
    173   len1 = *s1 != '\0' ? strlen (s1) : 0;
    174   len2 = *s2 != '\0' ? strlen (s2) : 0;
    175   len3 = *s3 != '\0' ? strlen (s3) : 0;
    176 
    177   result = (char *) xmalloc (len1 + len2 + len3 + 1);
    178 
    179   if (*s1 != '\0')
    180     bcopy (s1, result, len1);
    181   if (*s2 != '\0')
    182     bcopy (s2, result + len1, len2);
    183   if (*s3 != '\0')
    184     bcopy (s3, result + len1 + len2, len3);
    185   *(result + len1 + len2 + len3) = '\0';
    186 
    187   return result;
    188 }
    189 
    190 /* Print a message on stdout.  */
    192 
    193 void
    194 #if HAVE_ANSI_COMPILER && USE_VARIADIC && HAVE_STDARG_H
    195 message (int prefix, const char *fmt, ...)
    196 #else
    197 message (prefix, fmt, va_alist)
    198      int prefix;
    199      const char *fmt;
    200      va_dcl
    201 #endif
    202 {
    203 #if USE_VARIADIC
    204   va_list args;
    205 #endif
    206 
    207   log_working_directory (1);
    208 
    209   if (fmt != 0)
    210     {
    211       if (prefix)
    212 	{
    213 	  if (makelevel == 0)
    214 	    printf ("%s: ", program);
    215 	  else
    216 	    printf ("%s[%u]: ", program, makelevel);
    217 	}
    218       VA_START (args, fmt);
    219       VA_PRINTF (stdout, fmt, args);
    220       VA_END (args);
    221       putchar ('\n');
    222     }
    223 
    224   fflush (stdout);
    225 }
    226 
    227 /* Print an error message.  */
    228 
    229 void
    230 #if HAVE_ANSI_COMPILER && USE_VARIADIC && HAVE_STDARG_H
    231 error (const struct floc *flocp, const char *fmt, ...)
    232 #else
    233 error (flocp, fmt, va_alist)
    234      const struct floc *flocp;
    235      const char *fmt;
    236      va_dcl
    237 #endif
    238 {
    239 #if USE_VARIADIC
    240   va_list args;
    241 #endif
    242 
    243   log_working_directory (1);
    244 
    245   if (flocp && flocp->filenm)
    246     fprintf (stderr, "%s:%lu: ", flocp->filenm, flocp->lineno);
    247   else if (makelevel == 0)
    248     fprintf (stderr, "%s: ", program);
    249   else
    250     fprintf (stderr, "%s[%u]: ", program, makelevel);
    251 
    252   VA_START(args, fmt);
    253   VA_PRINTF (stderr, fmt, args);
    254   VA_END (args);
    255 
    256   putc ('\n', stderr);
    257   fflush (stderr);
    258 }
    259 
    260 /* Print an error message and exit.  */
    261 
    262 void
    263 #if HAVE_ANSI_COMPILER && USE_VARIADIC && HAVE_STDARG_H
    264 fatal (const struct floc *flocp, const char *fmt, ...)
    265 #else
    266 fatal (flocp, fmt, va_alist)
    267      const struct floc *flocp;
    268      const char *fmt;
    269      va_dcl
    270 #endif
    271 {
    272 #if USE_VARIADIC
    273   va_list args;
    274 #endif
    275 
    276   log_working_directory (1);
    277 
    278   if (flocp && flocp->filenm)
    279     fprintf (stderr, "%s:%lu: *** ", flocp->filenm, flocp->lineno);
    280   else if (makelevel == 0)
    281     fprintf (stderr, "%s: *** ", program);
    282   else
    283     fprintf (stderr, "%s[%u]: *** ", program, makelevel);
    284 
    285   VA_START(args, fmt);
    286   VA_PRINTF (stderr, fmt, args);
    287   VA_END (args);
    288 
    289   fputs (_(".  Stop.\n"), stderr);
    290 
    291   die (2);
    292 }
    293 
    294 #ifndef HAVE_STRERROR
    295 
    296 #undef	strerror
    297 
    298 char *
    299 strerror (int errnum)
    300 {
    301   extern int errno, sys_nerr;
    302 #ifndef __DECC
    303   extern char *sys_errlist[];
    304 #endif
    305   static char buf[] = "Unknown error 12345678901234567890";
    306 
    307   if (errno < sys_nerr)
    308     return sys_errlist[errnum];
    309 
    310   sprintf (buf, _("Unknown error %d"), errnum);
    311   return buf;
    312 }
    313 #endif
    314 
    315 /* Print an error message from errno.  */
    316 
    317 void
    318 perror_with_name (const char *str, const char *name)
    319 {
    320   error (NILF, _("%s%s: %s"), str, name, strerror (errno));
    321 }
    322 
    323 /* Print an error message from errno and exit.  */
    324 
    325 void
    326 pfatal_with_name (const char *name)
    327 {
    328   fatal (NILF, _("%s: %s"), name, strerror (errno));
    329 
    330   /* NOTREACHED */
    331 }
    332 
    333 /* Like malloc but get fatal error if memory is exhausted.  */
    335 /* Don't bother if we're using dmalloc; it provides these for us.  */
    336 
    337 #ifndef HAVE_DMALLOC_H
    338 
    339 #undef xmalloc
    340 #undef xrealloc
    341 #undef xstrdup
    342 
    343 char *
    344 xmalloc (unsigned int size)
    345 {
    346   /* Make sure we don't allocate 0, for pre-ANSI libraries.  */
    347   char *result = (char *) malloc (size ? size : 1);
    348   if (result == 0)
    349     fatal (NILF, _("virtual memory exhausted"));
    350   return result;
    351 }
    352 
    353 
    354 char *
    355 xrealloc (char *ptr, unsigned int size)
    356 {
    357   char *result;
    358 
    359   /* Some older implementations of realloc() don't conform to ANSI.  */
    360   if (! size)
    361     size = 1;
    362   result = ptr ? realloc (ptr, size) : malloc (size);
    363   if (result == 0)
    364     fatal (NILF, _("virtual memory exhausted"));
    365   return result;
    366 }
    367 
    368 
    369 char *
    370 xstrdup (const char *ptr)
    371 {
    372   char *result;
    373 
    374 #ifdef HAVE_STRDUP
    375   result = strdup (ptr);
    376 #else
    377   result = (char *) malloc (strlen (ptr) + 1);
    378 #endif
    379 
    380   if (result == 0)
    381     fatal (NILF, _("virtual memory exhausted"));
    382 
    383 #ifdef HAVE_STRDUP
    384   return result;
    385 #else
    386   return strcpy(result, ptr);
    387 #endif
    388 }
    389 
    390 #endif  /* HAVE_DMALLOC_H */
    391 
    392 char *
    393 savestring (const char *str, unsigned int length)
    394 {
    395   register char *out = (char *) xmalloc (length + 1);
    396   if (length > 0)
    397     bcopy (str, out, length);
    398   out[length] = '\0';
    399   return out;
    400 }
    401 
    402 
    404 /* Limited INDEX:
    405    Search through the string STRING, which ends at LIMIT, for the character C.
    406    Returns a pointer to the first occurrence, or nil if none is found.
    407    Like INDEX except that the string searched ends where specified
    408    instead of at the first null.  */
    409 
    410 char *
    411 lindex (const char *s, const char *limit, int c)
    412 {
    413   while (s < limit)
    414     if (*s++ == c)
    415       return (char *)(s - 1);
    416 
    417   return 0;
    418 }
    419 
    420 /* Return the address of the first whitespace or null in the string S.  */
    422 
    423 char *
    424 end_of_token (const char *s)
    425 {
    426   while (*s != '\0' && !isblank ((unsigned char)*s))
    427     ++s;
    428   return (char *)s;
    429 }
    430 
    431 #ifdef WINDOWS32
    432 /*
    433  * Same as end_of_token, but take into account a stop character
    434  */
    435 char *
    436 end_of_token_w32 (char *s, char stopchar)
    437 {
    438   register char *p = s;
    439   register int backslash = 0;
    440 
    441   while (*p != '\0' && *p != stopchar
    442 	 && (backslash || !isblank ((unsigned char)*p)))
    443     {
    444       if (*p++ == '\\')
    445         {
    446           backslash = !backslash;
    447           while (*p == '\\')
    448             {
    449               backslash = !backslash;
    450               ++p;
    451             }
    452         }
    453       else
    454         backslash = 0;
    455     }
    456 
    457   return p;
    458 }
    459 #endif
    460 
    461 /* Return the address of the first nonwhitespace or null in the string S.  */
    462 
    463 char *
    464 next_token (const char *s)
    465 {
    466   while (isblank ((unsigned char)*s))
    467     ++s;
    468   return (char *)s;
    469 }
    470 
    471 /* Find the next token in PTR; return the address of it, and store the
    472    length of the token into *LENGTHPTR if LENGTHPTR is not nil.  */
    473 
    474 char *
    475 find_next_token (char **ptr, unsigned int *lengthptr)
    476 {
    477   char *p = next_token (*ptr);
    478   char *end;
    479 
    480   if (*p == '\0')
    481     return 0;
    482 
    483   *ptr = end = end_of_token (p);
    484   if (lengthptr != 0)
    485     *lengthptr = end - p;
    486   return p;
    487 }
    488 
    489 
    491 /* Allocate a new `struct dep' with all fields initialized to 0.   */
    492 
    493 struct dep *
    494 alloc_dep ()
    495 {
    496   struct dep *d = (struct dep *) xmalloc (sizeof (struct dep));
    497   bzero ((char *) d, sizeof (struct dep));
    498   return d;
    499 }
    500 
    501 
    502 /* Free `struct dep' along with `name' and `stem'.   */
    503 
    504 void
    505 free_dep (struct dep *d)
    506 {
    507   if (d->name != 0)
    508     free (d->name);
    509 
    510   if (d->stem != 0)
    511     free (d->stem);
    512 
    513   free ((char *)d);
    514 }
    515 
    516 /* Copy a chain of `struct dep', making a new chain
    517    with the same contents as the old one.  */
    518 
    519 struct dep *
    520 copy_dep_chain (const struct dep *d)
    521 {
    522   register struct dep *c;
    523   struct dep *firstnew = 0;
    524   struct dep *lastnew = 0;
    525 
    526   while (d != 0)
    527     {
    528       c = (struct dep *) xmalloc (sizeof (struct dep));
    529       bcopy ((char *) d, (char *) c, sizeof (struct dep));
    530 
    531       if (c->name != 0)
    532 	c->name = xstrdup (c->name);
    533       if (c->stem != 0)
    534 	c->stem = xstrdup (c->stem);
    535 
    536       c->next = 0;
    537       if (firstnew == 0)
    538 	firstnew = lastnew = c;
    539       else
    540 	lastnew = lastnew->next = c;
    541 
    542       d = d->next;
    543     }
    544 
    545   return firstnew;
    546 }
    547 
    548 /* Free a chain of 'struct dep'.  */
    549 
    550 void
    551 free_dep_chain (struct dep *d)
    552 {
    553   while (d != 0)
    554     {
    555       struct dep *df = d;
    556       d = d->next;
    557       free_dep (df);
    558     }
    559 }
    560 
    561 /* Free a chain of `struct nameseq'. Each nameseq->name is freed
    563    as well.  For `struct dep' chains use free_dep_chain.  */
    564 
    565 void
    566 free_ns_chain (struct nameseq *n)
    567 {
    568   register struct nameseq *tmp;
    569 
    570   while (n != 0)
    571   {
    572     if (n->name != 0)
    573       free (n->name);
    574 
    575     tmp = n;
    576 
    577     n = n->next;
    578 
    579     free (tmp);
    580   }
    581 
    582 }
    583 #ifdef	iAPX286
    585 /* The losing compiler on this machine can't handle this macro.  */
    586 
    587 char *
    588 dep_name (struct dep *dep)
    589 {
    590   return dep->name == 0 ? dep->file->name : dep->name;
    591 }
    592 #endif
    593 
    594 #ifdef	GETLOADAVG_PRIVILEGED
    596 
    597 #ifdef POSIX
    598 
    599 /* Hopefully if a system says it's POSIX.1 and has the setuid and setgid
    600    functions, they work as POSIX.1 says.  Some systems (Alpha OSF/1 1.2,
    601    for example) which claim to be POSIX.1 also have the BSD setreuid and
    602    setregid functions, but they don't work as in BSD and only the POSIX.1
    603    way works.  */
    604 
    605 #undef HAVE_SETREUID
    606 #undef HAVE_SETREGID
    607 
    608 #else	/* Not POSIX.  */
    609 
    610 /* Some POSIX.1 systems have the seteuid and setegid functions.  In a
    611    POSIX-like system, they are the best thing to use.  However, some
    612    non-POSIX systems have them too but they do not work in the POSIX style
    613    and we must use setreuid and setregid instead.  */
    614 
    615 #undef HAVE_SETEUID
    616 #undef HAVE_SETEGID
    617 
    618 #endif	/* POSIX.  */
    619 
    620 #ifndef	HAVE_UNISTD_H
    621 extern int getuid (), getgid (), geteuid (), getegid ();
    622 extern int setuid (), setgid ();
    623 #ifdef HAVE_SETEUID
    624 extern int seteuid ();
    625 #else
    626 #ifdef	HAVE_SETREUID
    627 extern int setreuid ();
    628 #endif	/* Have setreuid.  */
    629 #endif	/* Have seteuid.  */
    630 #ifdef HAVE_SETEGID
    631 extern int setegid ();
    632 #else
    633 #ifdef	HAVE_SETREGID
    634 extern int setregid ();
    635 #endif	/* Have setregid.  */
    636 #endif	/* Have setegid.  */
    637 #endif	/* No <unistd.h>.  */
    638 
    639 /* Keep track of the user and group IDs for user- and make- access.  */
    640 static int user_uid = -1, user_gid = -1, make_uid = -1, make_gid = -1;
    641 #define	access_inited	(user_uid != -1)
    642 static enum { make, user } current_access;
    643 
    644 
    645 /* Under -d, write a message describing the current IDs.  */
    646 
    647 static void
    648 log_access (const char *flavor)
    649 {
    650   if (! ISDB (DB_JOBS))
    651     return;
    652 
    653   /* All the other debugging messages go to stdout,
    654      but we write this one to stderr because it might be
    655      run in a child fork whose stdout is piped.  */
    656 
    657   fprintf (stderr, _("%s: user %lu (real %lu), group %lu (real %lu)\n"),
    658 	   flavor, (unsigned long) geteuid (), (unsigned long) getuid (),
    659            (unsigned long) getegid (), (unsigned long) getgid ());
    660   fflush (stderr);
    661 }
    662 
    663 
    664 static void
    665 init_access (void)
    666 {
    667 #ifndef VMS
    668   user_uid = getuid ();
    669   user_gid = getgid ();
    670 
    671   make_uid = geteuid ();
    672   make_gid = getegid ();
    673 
    674   /* Do these ever fail?  */
    675   if (user_uid == -1 || user_gid == -1 || make_uid == -1 || make_gid == -1)
    676     pfatal_with_name ("get{e}[gu]id");
    677 
    678   log_access (_("Initialized access"));
    679 
    680   current_access = make;
    681 #endif
    682 }
    683 
    684 #endif	/* GETLOADAVG_PRIVILEGED */
    685 
    686 /* Give the process appropriate permissions for access to
    687    user data (i.e., to stat files, or to spawn a child process).  */
    688 void
    689 user_access (void)
    690 {
    691 #ifdef	GETLOADAVG_PRIVILEGED
    692 
    693   if (!access_inited)
    694     init_access ();
    695 
    696   if (current_access == user)
    697     return;
    698 
    699   /* We are in "make access" mode.  This means that the effective user and
    700      group IDs are those of make (if it was installed setuid or setgid).
    701      We now want to set the effective user and group IDs to the real IDs,
    702      which are the IDs of the process that exec'd make.  */
    703 
    704 #ifdef	HAVE_SETEUID
    705 
    706   /* Modern systems have the seteuid/setegid calls which set only the
    707      effective IDs, which is ideal.  */
    708 
    709   if (seteuid (user_uid) < 0)
    710     pfatal_with_name ("user_access: seteuid");
    711 
    712 #else	/* Not HAVE_SETEUID.  */
    713 
    714 #ifndef	HAVE_SETREUID
    715 
    716   /* System V has only the setuid/setgid calls to set user/group IDs.
    717      There is an effective ID, which can be set by setuid/setgid.
    718      It can be set (unless you are root) only to either what it already is
    719      (returned by geteuid/getegid, now in make_uid/make_gid),
    720      the real ID (return by getuid/getgid, now in user_uid/user_gid),
    721      or the saved set ID (what the effective ID was before this set-ID
    722      executable (make) was exec'd).  */
    723 
    724   if (setuid (user_uid) < 0)
    725     pfatal_with_name ("user_access: setuid");
    726 
    727 #else	/* HAVE_SETREUID.  */
    728 
    729   /* In 4BSD, the setreuid/setregid calls set both the real and effective IDs.
    730      They may be set to themselves or each other.  So you have two alternatives
    731      at any one time.  If you use setuid/setgid, the effective will be set to
    732      the real, leaving only one alternative.  Using setreuid/setregid, however,
    733      you can toggle between your two alternatives by swapping the values in a
    734      single setreuid or setregid call.  */
    735 
    736   if (setreuid (make_uid, user_uid) < 0)
    737     pfatal_with_name ("user_access: setreuid");
    738 
    739 #endif	/* Not HAVE_SETREUID.  */
    740 #endif	/* HAVE_SETEUID.  */
    741 
    742 #ifdef	HAVE_SETEGID
    743   if (setegid (user_gid) < 0)
    744     pfatal_with_name ("user_access: setegid");
    745 #else
    746 #ifndef	HAVE_SETREGID
    747   if (setgid (user_gid) < 0)
    748     pfatal_with_name ("user_access: setgid");
    749 #else
    750   if (setregid (make_gid, user_gid) < 0)
    751     pfatal_with_name ("user_access: setregid");
    752 #endif
    753 #endif
    754 
    755   current_access = user;
    756 
    757   log_access (_("User access"));
    758 
    759 #endif	/* GETLOADAVG_PRIVILEGED */
    760 }
    761 
    762 /* Give the process appropriate permissions for access to
    763    make data (i.e., the load average).  */
    764 void
    765 make_access (void)
    766 {
    767 #ifdef	GETLOADAVG_PRIVILEGED
    768 
    769   if (!access_inited)
    770     init_access ();
    771 
    772   if (current_access == make)
    773     return;
    774 
    775   /* See comments in user_access, above.  */
    776 
    777 #ifdef	HAVE_SETEUID
    778   if (seteuid (make_uid) < 0)
    779     pfatal_with_name ("make_access: seteuid");
    780 #else
    781 #ifndef	HAVE_SETREUID
    782   if (setuid (make_uid) < 0)
    783     pfatal_with_name ("make_access: setuid");
    784 #else
    785   if (setreuid (user_uid, make_uid) < 0)
    786     pfatal_with_name ("make_access: setreuid");
    787 #endif
    788 #endif
    789 
    790 #ifdef	HAVE_SETEGID
    791   if (setegid (make_gid) < 0)
    792     pfatal_with_name ("make_access: setegid");
    793 #else
    794 #ifndef	HAVE_SETREGID
    795   if (setgid (make_gid) < 0)
    796     pfatal_with_name ("make_access: setgid");
    797 #else
    798   if (setregid (user_gid, make_gid) < 0)
    799     pfatal_with_name ("make_access: setregid");
    800 #endif
    801 #endif
    802 
    803   current_access = make;
    804 
    805   log_access (_("Make access"));
    806 
    807 #endif	/* GETLOADAVG_PRIVILEGED */
    808 }
    809 
    810 /* Give the process appropriate permissions for a child process.
    811    This is like user_access, but you can't get back to make_access.  */
    812 void
    813 child_access (void)
    814 {
    815 #ifdef	GETLOADAVG_PRIVILEGED
    816 
    817   if (!access_inited)
    818     abort ();
    819 
    820   /* Set both the real and effective UID and GID to the user's.
    821      They cannot be changed back to make's.  */
    822 
    823 #ifndef	HAVE_SETREUID
    824   if (setuid (user_uid) < 0)
    825     pfatal_with_name ("child_access: setuid");
    826 #else
    827   if (setreuid (user_uid, user_uid) < 0)
    828     pfatal_with_name ("child_access: setreuid");
    829 #endif
    830 
    831 #ifndef	HAVE_SETREGID
    832   if (setgid (user_gid) < 0)
    833     pfatal_with_name ("child_access: setgid");
    834 #else
    835   if (setregid (user_gid, user_gid) < 0)
    836     pfatal_with_name ("child_access: setregid");
    837 #endif
    838 
    839   log_access (_("Child access"));
    840 
    841 #endif	/* GETLOADAVG_PRIVILEGED */
    842 }
    843 
    844 #ifdef NEED_GET_PATH_MAX
    846 unsigned int
    847 get_path_max (void)
    848 {
    849   static unsigned int value;
    850 
    851   if (value == 0)
    852     {
    853       long int x = pathconf ("/", _PC_PATH_MAX);
    854       if (x > 0)
    855 	value = x;
    856       else
    857 	return MAXPATHLEN;
    858     }
    859 
    860   return value;
    861 }
    862 #endif
    863 
    864 
    866 /* This code is stolen from gnulib.
    867    If/when we abandon the requirement to work with K&R compilers, we can
    868    remove this (and perhaps other parts of GNU make!) and migrate to using
    869    gnulib directly.
    870 
    871    This is called only through atexit(), which means die() has already been
    872    invoked.  So, call exit() here directly.  Apparently that works...?
    873 */
    874 
    875 /* Close standard output, exiting with status 'exit_failure' on failure.
    876    If a program writes *anything* to stdout, that program should close
    877    stdout and make sure that it succeeds before exiting.  Otherwise,
    878    suppose that you go to the extreme of checking the return status
    879    of every function that does an explicit write to stdout.  The last
    880    printf can succeed in writing to the internal stream buffer, and yet
    881    the fclose(stdout) could still fail (due e.g., to a disk full error)
    882    when it tries to write out that buffered data.  Thus, you would be
    883    left with an incomplete output file and the offending program would
    884    exit successfully.  Even calling fflush is not always sufficient,
    885    since some file systems (NFS and CODA) buffer written/flushed data
    886    until an actual close call.
    887 
    888    Besides, it's wasteful to check the return value from every call
    889    that writes to stdout -- just let the internal stream state record
    890    the failure.  That's what the ferror test is checking below.
    891 
    892    It's important to detect such failures and exit nonzero because many
    893    tools (most notably `make' and other build-management systems) depend
    894    on being able to detect failure in other tools via their exit status.  */
    895 
    896 void
    897 close_stdout (void)
    898 {
    899   int prev_fail = ferror (stdout);
    900   int fclose_fail = fclose (stdout);
    901 
    902   if (prev_fail || fclose_fail)
    903     {
    904       if (fclose_fail)
    905         error (NILF, _("write error: %s"), strerror (errno));
    906       else
    907         error (NILF, _("write error"));
    908       exit (EXIT_FAILURE);
    909     }
    910 }
    911