summaryrefslogtreecommitdiff
path: root/misc.c
diff options
context:
space:
mode:
Diffstat (limited to 'misc.c')
-rw-r--r--misc.c435
1 files changed, 101 insertions, 334 deletions
diff --git a/misc.c b/misc.c
index 7a6f773..bc54ce6 100644
--- a/misc.c
+++ b/misc.c
@@ -1,7 +1,5 @@
/* Miscellaneous generic support functions for GNU Make.
-Copyright (C) 1988, 1989, 1990, 1991, 1992, 1993, 1994, 1995, 1996, 1997,
-1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009,
-2010 Free Software Foundation, Inc.
+Copyright (C) 1988-2013 Free Software Foundation, Inc.
This file is part of GNU Make.
GNU Make is free software; you can redistribute it and/or modify it under the
@@ -16,42 +14,21 @@ A PARTICULAR PURPOSE. See the GNU General Public License for more details.
You should have received a copy of the GNU General Public License along with
this program. If not, see <http://www.gnu.org/licenses/>. */
-#include "make.h"
+#include "makeint.h"
+#include "filedef.h"
#include "dep.h"
#include "debug.h"
-/* Variadic functions. We go through contortions to allow proper function
- prototypes for both ANSI and pre-ANSI C compilers, and also for those
- which support stdarg.h vs. varargs.h, and finally those which have
- vfprintf(), etc. and those who have _doprnt... or nothing.
-
- This fancy stuff all came from GNU fileutils, except for the VA_PRINTF and
- VA_END macros used here since we have multiple print functions. */
-
-#if USE_VARIADIC
-# if HAVE_STDARG_H
-# include <stdarg.h>
-# define VA_START(args, lastarg) va_start(args, lastarg)
-# else
-# include <varargs.h>
-# define VA_START(args, lastarg) va_start(args)
-# endif
-# if HAVE_VPRINTF
-# define VA_PRINTF(fp, lastarg, args) vfprintf((fp), (lastarg), (args))
-# else
-# define VA_PRINTF(fp, lastarg, args) _doprnt((lastarg), (args), (fp))
-# endif
-# define VA_END(args) va_end(args)
+/* GNU make no longer supports pre-ANSI89 environments. */
+
+#include <stdarg.h>
+
+#ifdef HAVE_FCNTL_H
+# include <fcntl.h>
#else
-/* We can't use any variadic interface! */
-# define va_alist a1, a2, a3, a4, a5, a6, a7, a8
-# define va_dcl char *a1, *a2, *a3, *a4, *a5, *a6, *a7, *a8;
-# define VA_START(args, lastarg)
-# define VA_PRINTF(fp, lastarg, args) fprintf((fp), (lastarg), va_alist)
-# define VA_END(args)
+# include <sys/file.h>
#endif
-
/* Compare strings *S1 and *S2.
Return negative if the first is less, positive if it is greater,
zero if they are equal. */
@@ -74,9 +51,7 @@ alpha_compare (const void *v1, const void *v2)
void
collapse_continuations (char *line)
{
- register char *in, *out, *p;
- register int backslash;
- register unsigned int bs_write;
+ char *in, *out, *p;
in = strchr (line, '\n');
if (in == 0)
@@ -89,62 +64,64 @@ collapse_continuations (char *line)
while (*in != '\0')
{
/* BS_WRITE gets the number of quoted backslashes at
- the end just before IN, and BACKSLASH gets nonzero
- if the next character is quoted. */
- backslash = 0;
- bs_write = 0;
+ the end just before IN, and BACKSLASH gets nonzero
+ if the next character is quoted. */
+ unsigned int backslash = 0;
+ unsigned int bs_write = 0;
for (p = in - 1; p >= line && *p == '\\'; --p)
- {
- if (backslash)
- ++bs_write;
- backslash = !backslash;
+ {
+ if (backslash)
+ ++bs_write;
+ backslash = !backslash;
- /* It should be impossible to go back this far without exiting,
- but if we do, we can't get the right answer. */
- if (in == out - 1)
- abort ();
- }
+ /* It should be impossible to go back this far without exiting,
+ but if we do, we can't get the right answer. */
+ if (in == out - 1)
+ abort ();
+ }
/* Output the appropriate number of backslashes. */
while (bs_write-- > 0)
- *out++ = '\\';
+ *out++ = '\\';
/* Skip the newline. */
++in;
- /* If the newline is escaped, discard following whitespace leaving just
- one space. POSIX requires that each backslash/newline/following
- whitespace sequence be reduced to a single space. */
if (backslash)
- {
- in = next_token (in);
- /* Removing this loop will fix Savannah bug #16670: do we want to? */
- while (out > line && isblank ((unsigned char)out[-1]))
- --out;
- *out++ = ' ';
- }
+ {
+ /* Backslash/newline handling:
+ In traditional GNU make all trailing whitespace, consecutive
+ backslash/newlines, and any leading whitespace on the next line
+ is reduced to a single space.
+ In POSIX, each backslash/newline and is replaced by a space. */
+ in = next_token (in);
+ if (! posix_pedantic)
+ while (out > line && isblank ((unsigned char)out[-1]))
+ --out;
+ *out++ = ' ';
+ }
else
- /* If the newline isn't quoted, put it in the output. */
- *out++ = '\n';
+ /* If the newline isn't quoted, put it in the output. */
+ *out++ = '\n';
/* Now copy the following line to the output.
- Stop when we find backslashes followed by a newline. */
+ Stop when we find backslashes followed by a newline. */
while (*in != '\0')
- if (*in == '\\')
- {
- p = in + 1;
- while (*p == '\\')
- ++p;
- if (*p == '\n')
- {
- in = p;
- break;
- }
- while (in < p)
- *out++ = *in++;
- }
- else
- *out++ = *in++;
+ if (*in == '\\')
+ {
+ p = in + 1;
+ while (*p == '\\')
+ ++p;
+ if (*p == '\n')
+ {
+ in = p;
+ break;
+ }
+ while (in < p)
+ *out++ = *in++;
+ }
+ else
+ *out++ = *in++;
}
*out = '\0';
@@ -164,28 +141,19 @@ print_spaces (unsigned int n)
This string lives in static, re-used memory. */
const char *
-#if HAVE_ANSI_COMPILER && USE_VARIADIC && HAVE_STDARG_H
concat (unsigned int num, ...)
-#else
-concat (num, va_alist)
- unsigned int num;
- va_dcl
-#endif
{
static unsigned int rlen = 0;
static char *result = NULL;
- int ri = 0;
-
-#if USE_VARIADIC
+ unsigned int ri = 0;
va_list args;
-#endif
- VA_START (args, num);
+ va_start (args, num);
while (num-- > 0)
{
const char *s = va_arg (args, const char *);
- unsigned int l = s ? strlen (s) : 0;
+ unsigned int l = xstrlen (s);
if (l == 0)
continue;
@@ -200,7 +168,7 @@ concat (num, va_alist)
ri += l;
}
- VA_END (args);
+ va_end (args);
/* Get some more memory if we don't have enough space for the
terminating '\0'. */
@@ -215,113 +183,9 @@ concat (num, va_alist)
return result;
}
-/* Print a message on stdout. */
-
-void
-#if HAVE_ANSI_COMPILER && USE_VARIADIC && HAVE_STDARG_H
-message (int prefix, const char *fmt, ...)
-#else
-message (prefix, fmt, va_alist)
- int prefix;
- const char *fmt;
- va_dcl
-#endif
-{
-#if USE_VARIADIC
- va_list args;
-#endif
-
- log_working_directory (1);
-
- if (fmt != 0)
- {
- if (prefix)
- {
- if (makelevel == 0)
- printf ("%s: ", program);
- else
- printf ("%s[%u]: ", program, makelevel);
- }
- VA_START (args, fmt);
- VA_PRINTF (stdout, fmt, args);
- VA_END (args);
- putchar ('\n');
- }
-
- fflush (stdout);
-}
-
-/* Print an error message. */
-
-void
-#if HAVE_ANSI_COMPILER && USE_VARIADIC && HAVE_STDARG_H
-error (const struct floc *flocp, const char *fmt, ...)
-#else
-error (flocp, fmt, va_alist)
- const struct floc *flocp;
- const char *fmt;
- va_dcl
-#endif
-{
-#if USE_VARIADIC
- va_list args;
-#endif
-
- log_working_directory (1);
-
- if (flocp && flocp->filenm)
- fprintf (stderr, "%s:%lu: ", flocp->filenm, flocp->lineno);
- else if (makelevel == 0)
- fprintf (stderr, "%s: ", program);
- else
- fprintf (stderr, "%s[%u]: ", program, makelevel);
-
- VA_START(args, fmt);
- VA_PRINTF (stderr, fmt, args);
- VA_END (args);
-
- putc ('\n', stderr);
- fflush (stderr);
-}
-
-/* Print an error message and exit. */
-
-void
-#if HAVE_ANSI_COMPILER && USE_VARIADIC && HAVE_STDARG_H
-fatal (const struct floc *flocp, const char *fmt, ...)
-#else
-fatal (flocp, fmt, va_alist)
- const struct floc *flocp;
- const char *fmt;
- va_dcl
-#endif
-{
-#if USE_VARIADIC
- va_list args;
-#endif
-
- log_working_directory (1);
-
- if (flocp && flocp->filenm)
- fprintf (stderr, "%s:%lu: *** ", flocp->filenm, flocp->lineno);
- else if (makelevel == 0)
- fprintf (stderr, "%s: *** ", program);
- else
- fprintf (stderr, "%s[%u]: *** ", program, makelevel);
-
- VA_START(args, fmt);
- VA_PRINTF (stderr, fmt, args);
- VA_END (args);
-
- fputs (_(". Stop.\n"), stderr);
-
- die (2);
-}
#ifndef HAVE_STRERROR
-
-#undef strerror
-
+#undef strerror
char *
strerror (int errnum)
{
@@ -338,24 +202,6 @@ strerror (int errnum)
return buf;
}
#endif
-
-/* Print an error message from errno. */
-
-void
-perror_with_name (const char *str, const char *name)
-{
- error (NILF, _("%s%s: %s"), str, name, strerror (errno));
-}
-
-/* Print an error message from errno and exit. */
-
-void
-pfatal_with_name (const char *name)
-{
- fatal (NILF, _("%s: %s"), name, strerror (errno));
-
- /* NOTREACHED */
-}
/* Like malloc but get fatal error if memory is exhausted. */
/* Don't bother if we're using dmalloc; it provides these for us. */
@@ -468,41 +314,11 @@ lindex (const char *s, const char *limit, int c)
char *
end_of_token (const char *s)
{
- while (*s != '\0' && !isblank ((unsigned char)*s))
+ while (! STOP_SET (*s, MAP_BLANK|MAP_NUL))
++s;
return (char *)s;
}
-#ifdef WINDOWS32
-/*
- * Same as end_of_token, but take into account a stop character
- */
-char *
-end_of_token_w32 (const char *s, char stopchar)
-{
- const char *p = s;
- int backslash = 0;
-
- while (*p != '\0' && *p != stopchar
- && (backslash || !isblank ((unsigned char)*p)))
- {
- if (*p++ == '\\')
- {
- backslash = !backslash;
- while (*p == '\\')
- {
- backslash = !backslash;
- ++p;
- }
- }
- else
- backslash = 0;
- }
-
- return (char *)p;
-}
-#endif
-
/* Return the address of the first nonwhitespace or null in the string S. */
char *
@@ -533,7 +349,7 @@ find_next_token (const char **ptr, unsigned int *lengthptr)
}
-/* Copy a chain of `struct dep'. For 2nd expansion deps, dup the name. */
+/* Copy a chain of 'struct dep'. For 2nd expansion deps, dup the name. */
struct dep *
copy_dep_chain (const struct dep *d)
@@ -551,9 +367,9 @@ copy_dep_chain (const struct dep *d)
c->next = 0;
if (firstnew == 0)
- firstnew = lastnew = c;
+ firstnew = lastnew = c;
else
- lastnew = lastnew->next = c;
+ lastnew = lastnew->next = c;
d = d->next;
}
@@ -590,7 +406,6 @@ free_ns_chain (struct nameseq *ns)
#if !HAVE_STRCASECMP && !HAVE_STRICMP && !HAVE_STRCMPI
-
/* If we don't have strcasecmp() (from POSIX), or anything that can substitute
for it, define our own version. */
@@ -616,7 +431,6 @@ strcasecmp (const char *s1, const char *s2)
#endif
#if !HAVE_STRNCASECMP && !HAVE_STRNICMP && !HAVE_STRNCMPI
-
/* If we don't have strncasecmp() (from POSIX), or anything that can
substitute for it, define our own version. */
@@ -643,7 +457,7 @@ strncasecmp (const char *s1, const char *s2, int n)
}
#endif
-#ifdef GETLOADAVG_PRIVILEGED
+#ifdef GETLOADAVG_PRIVILEGED
#ifdef POSIX
@@ -656,7 +470,7 @@ strncasecmp (const char *s1, const char *s2, int n)
#undef HAVE_SETREUID
#undef HAVE_SETREGID
-#else /* Not POSIX. */
+#else /* Not POSIX. */
/* Some POSIX.1 systems have the seteuid and setegid functions. In a
POSIX-like system, they are the best thing to use. However, some
@@ -666,30 +480,30 @@ strncasecmp (const char *s1, const char *s2, int n)
#undef HAVE_SETEUID
#undef HAVE_SETEGID
-#endif /* POSIX. */
+#endif /* POSIX. */
-#ifndef HAVE_UNISTD_H
+#ifndef HAVE_UNISTD_H
extern int getuid (), getgid (), geteuid (), getegid ();
extern int setuid (), setgid ();
#ifdef HAVE_SETEUID
extern int seteuid ();
#else
-#ifdef HAVE_SETREUID
+#ifdef HAVE_SETREUID
extern int setreuid ();
-#endif /* Have setreuid. */
-#endif /* Have seteuid. */
+#endif /* Have setreuid. */
+#endif /* Have seteuid. */
#ifdef HAVE_SETEGID
extern int setegid ();
#else
-#ifdef HAVE_SETREGID
+#ifdef HAVE_SETREGID
extern int setregid ();
-#endif /* Have setregid. */
-#endif /* Have setegid. */
-#endif /* No <unistd.h>. */
+#endif /* Have setregid. */
+#endif /* Have setegid. */
+#endif /* No <unistd.h>. */
/* Keep track of the user and group IDs for user- and make- access. */
static int user_uid = -1, user_gid = -1, make_uid = -1, make_gid = -1;
-#define access_inited (user_uid != -1)
+#define access_inited (user_uid != -1)
static enum { make, user } current_access;
@@ -706,7 +520,7 @@ log_access (const char *flavor)
run in a child fork whose stdout is piped. */
fprintf (stderr, _("%s: user %lu (real %lu), group %lu (real %lu)\n"),
- flavor, (unsigned long) geteuid (), (unsigned long) getuid (),
+ flavor, (unsigned long) geteuid (), (unsigned long) getuid (),
(unsigned long) getegid (), (unsigned long) getgid ());
fflush (stderr);
}
@@ -732,14 +546,14 @@ init_access (void)
#endif
}
-#endif /* GETLOADAVG_PRIVILEGED */
+#endif /* GETLOADAVG_PRIVILEGED */
/* Give the process appropriate permissions for access to
user data (i.e., to stat files, or to spawn a child process). */
void
user_access (void)
{
-#ifdef GETLOADAVG_PRIVILEGED
+#ifdef GETLOADAVG_PRIVILEGED
if (!access_inited)
init_access ();
@@ -752,7 +566,7 @@ user_access (void)
We now want to set the effective user and group IDs to the real IDs,
which are the IDs of the process that exec'd make. */
-#ifdef HAVE_SETEUID
+#ifdef HAVE_SETEUID
/* Modern systems have the seteuid/setegid calls which set only the
effective IDs, which is ideal. */
@@ -760,9 +574,9 @@ user_access (void)
if (seteuid (user_uid) < 0)
pfatal_with_name ("user_access: seteuid");
-#else /* Not HAVE_SETEUID. */
+#else /* Not HAVE_SETEUID. */
-#ifndef HAVE_SETREUID
+#ifndef HAVE_SETREUID
/* System V has only the setuid/setgid calls to set user/group IDs.
There is an effective ID, which can be set by setuid/setgid.
@@ -775,7 +589,7 @@ user_access (void)
if (setuid (user_uid) < 0)
pfatal_with_name ("user_access: setuid");
-#else /* HAVE_SETREUID. */
+#else /* HAVE_SETREUID. */
/* In 4BSD, the setreuid/setregid calls set both the real and effective IDs.
They may be set to themselves or each other. So you have two alternatives
@@ -787,14 +601,14 @@ user_access (void)
if (setreuid (make_uid, user_uid) < 0)
pfatal_with_name ("user_access: setreuid");
-#endif /* Not HAVE_SETREUID. */
-#endif /* HAVE_SETEUID. */
+#endif /* Not HAVE_SETREUID. */
+#endif /* HAVE_SETEUID. */
-#ifdef HAVE_SETEGID
+#ifdef HAVE_SETEGID
if (setegid (user_gid) < 0)
pfatal_with_name ("user_access: setegid");
#else
-#ifndef HAVE_SETREGID
+#ifndef HAVE_SETREGID
if (setgid (user_gid) < 0)
pfatal_with_name ("user_access: setgid");
#else
@@ -807,7 +621,7 @@ user_access (void)
log_access (_("User access"));
-#endif /* GETLOADAVG_PRIVILEGED */
+#endif /* GETLOADAVG_PRIVILEGED */
}
/* Give the process appropriate permissions for access to
@@ -815,7 +629,7 @@ user_access (void)
void
make_access (void)
{
-#ifdef GETLOADAVG_PRIVILEGED
+#ifdef GETLOADAVG_PRIVILEGED
if (!access_inited)
init_access ();
@@ -825,11 +639,11 @@ make_access (void)
/* See comments in user_access, above. */
-#ifdef HAVE_SETEUID
+#ifdef HAVE_SETEUID
if (seteuid (make_uid) < 0)
pfatal_with_name ("make_access: seteuid");
#else
-#ifndef HAVE_SETREUID
+#ifndef HAVE_SETREUID
if (setuid (make_uid) < 0)
pfatal_with_name ("make_access: setuid");
#else
@@ -838,11 +652,11 @@ make_access (void)
#endif
#endif
-#ifdef HAVE_SETEGID
+#ifdef HAVE_SETEGID
if (setegid (make_gid) < 0)
pfatal_with_name ("make_access: setegid");
#else
-#ifndef HAVE_SETREGID
+#ifndef HAVE_SETREGID
if (setgid (make_gid) < 0)
pfatal_with_name ("make_access: setgid");
#else
@@ -855,7 +669,7 @@ make_access (void)
log_access (_("Make access"));
-#endif /* GETLOADAVG_PRIVILEGED */
+#endif /* GETLOADAVG_PRIVILEGED */
}
/* Give the process appropriate permissions for a child process.
@@ -863,7 +677,7 @@ make_access (void)
void
child_access (void)
{
-#ifdef GETLOADAVG_PRIVILEGED
+#ifdef GETLOADAVG_PRIVILEGED
if (!access_inited)
abort ();
@@ -871,7 +685,7 @@ child_access (void)
/* Set both the real and effective UID and GID to the user's.
They cannot be changed back to make's. */
-#ifndef HAVE_SETREUID
+#ifndef HAVE_SETREUID
if (setuid (user_uid) < 0)
pfatal_with_name ("child_access: setuid");
#else
@@ -879,7 +693,7 @@ child_access (void)
pfatal_with_name ("child_access: setreuid");
#endif
-#ifndef HAVE_SETREGID
+#ifndef HAVE_SETREGID
if (setgid (user_gid) < 0)
pfatal_with_name ("child_access: setgid");
#else
@@ -889,9 +703,9 @@ child_access (void)
log_access (_("Child access"));
-#endif /* GETLOADAVG_PRIVILEGED */
+#endif /* GETLOADAVG_PRIVILEGED */
}
-
+
#ifdef NEED_GET_PATH_MAX
unsigned int
get_path_max (void)
@@ -902,58 +716,11 @@ get_path_max (void)
{
long int x = pathconf ("/", _PC_PATH_MAX);
if (x > 0)
- value = x;
+ value = x;
else
- return MAXPATHLEN;
+ return MAXPATHLEN;
}
return value;
}
#endif
-
-
-/* This code is stolen from gnulib.
- If/when we abandon the requirement to work with K&R compilers, we can
- remove this (and perhaps other parts of GNU make!) and migrate to using
- gnulib directly.
-
- This is called only through atexit(), which means die() has already been
- invoked. So, call exit() here directly. Apparently that works...?
-*/
-
-/* Close standard output, exiting with status 'exit_failure' on failure.
- If a program writes *anything* to stdout, that program should close
- stdout and make sure that it succeeds before exiting. Otherwise,
- suppose that you go to the extreme of checking the return status
- of every function that does an explicit write to stdout. The last
- printf can succeed in writing to the internal stream buffer, and yet
- the fclose(stdout) could still fail (due e.g., to a disk full error)
- when it tries to write out that buffered data. Thus, you would be
- left with an incomplete output file and the offending program would
- exit successfully. Even calling fflush is not always sufficient,
- since some file systems (NFS and CODA) buffer written/flushed data
- until an actual close call.
-
- Besides, it's wasteful to check the return value from every call
- that writes to stdout -- just let the internal stream state record
- the failure. That's what the ferror test is checking below.
-
- It's important to detect such failures and exit nonzero because many
- tools (most notably `make' and other build-management systems) depend
- on being able to detect failure in other tools via their exit status. */
-
-void
-close_stdout (void)
-{
- int prev_fail = ferror (stdout);
- int fclose_fail = fclose (stdout);
-
- if (prev_fail || fclose_fail)
- {
- if (fclose_fail)
- error (NILF, _("write error: %s"), strerror (errno));
- else
- error (NILF, _("write error"));
- exit (EXIT_FAILURE);
- }
-}