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