- Add missing disclamer.
[dragonfly.git] / usr.bin / make / util.c
1 /*
2  * Copyright (c) 2002 Juli Mallett.  All rights reserved.
3  * Copyright (c) 1988, 1989, 1990, 1993
4  *      The Regents of the University of California.  All rights reserved.
5  * Copyright (c) 1989 by Berkeley Softworks
6  * All rights reserved.
7  *
8  * This code is derived from software contributed to Berkeley by
9  * Adam de Boor.
10  *
11  * Redistribution and use in source and binary forms, with or without
12  * modification, are permitted provided that the following conditions
13  * are met:
14  * 1. Redistributions of source code must retain the above copyright
15  *    notice, this list of conditions and the following disclaimer.
16  * 2. Redistributions in binary form must reproduce the above copyright
17  *    notice, this list of conditions and the following disclaimer in the
18  *    documentation and/or other materials provided with the distribution.
19  * 3. All advertising materials mentioning features or use of this software
20  *    must display the following acknowledgement:
21  *      This product includes software developed by the University of
22  *      California, Berkeley and its contributors.
23  * 4. Neither the name of the University nor the names of its contributors
24  *    may be used to endorse or promote products derived from this software
25  *    without specific prior written permission.
26  *
27  * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
28  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
29  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
30  * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
31  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
32  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
33  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
34  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
35  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
36  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
37  * SUCH DAMAGE.
38  *
39  * $FreeBSD: src/usr.bin/make/util.c,v 1.5.2.2 2001/02/13 03:13:58 will Exp $
40  * $DragonFly: src/usr.bin/make/util.c,v 1.14 2005/01/31 09:49:14 okumoto Exp $
41  */
42
43 /*-
44  * util.c --
45  *      General utilitarian routines for make(1).
46  */
47
48 #include <sys/stat.h>
49 #include <sys/types.h>
50 #include <err.h>
51 #include <errno.h>
52 #include <stdarg.h>
53 #include <stdlib.h>
54 #include <string.h>
55 #include <unistd.h>
56
57 #include "globals.h"
58 #include "job.h"
59 #include "targ.h"
60 #include "util.h"
61
62 static void enomem(void);
63
64 /*-
65  * Debug --
66  *      Print a debugging message given its format.
67  *
68  * Results:
69  *      None.
70  *
71  * Side Effects:
72  *      The message is printed.
73  */
74 /* VARARGS */
75 void
76 Debug(const char *fmt, ...)
77 {
78         va_list ap;
79
80         va_start(ap, fmt);
81         vfprintf(stderr, fmt, ap);
82         va_end(ap);
83         fflush(stderr);
84 }
85
86 /*-
87  * Error --
88  *      Print an error message given its format.
89  *
90  * Results:
91  *      None.
92  *
93  * Side Effects:
94  *      The message is printed.
95  */
96 /* VARARGS */
97 void
98 Error(const char *fmt, ...)
99 {
100         va_list ap;
101
102         va_start(ap, fmt);
103         vfprintf(stderr, fmt, ap);
104         va_end(ap);
105         fprintf(stderr, "\n");
106         fflush(stderr);
107 }
108
109 /*-
110  * Fatal --
111  *      Produce a Fatal error message. If jobs are running, waits for them
112  *      to finish.
113  *
114  * Results:
115  *      None
116  *
117  * Side Effects:
118  *      The program exits
119  */
120 /* VARARGS */
121 void
122 Fatal(const char *fmt, ...)
123 {
124         va_list ap;
125
126         va_start(ap, fmt);
127         if (jobsRunning)
128                 Job_Wait();
129
130         vfprintf(stderr, fmt, ap);
131         va_end(ap);
132         fprintf(stderr, "\n");
133         fflush(stderr);
134
135         if (DEBUG(GRAPH2))
136                 Targ_PrintGraph(2);
137         exit(2);                /* Not 1 so -q can distinguish error */
138 }
139
140 /*
141  * Punt --
142  *      Major exception once jobs are being created. Kills all jobs, prints
143  *      a message and exits.
144  *
145  * Results:
146  *      None
147  *
148  * Side Effects:
149  *      All children are killed indiscriminately and the program Lib_Exits
150  */
151 /* VARARGS */
152 void
153 Punt(const char *fmt, ...)
154 {
155         va_list ap;
156
157         va_start(ap, fmt);
158         fprintf(stderr, "make: ");
159         vfprintf(stderr, fmt, ap);
160         va_end(ap);
161         fprintf(stderr, "\n");
162         fflush(stderr);
163
164         DieHorribly();
165 }
166
167 /*-
168  * DieHorribly --
169  *      Exit without giving a message.
170  *
171  * Results:
172  *      None
173  *
174  * Side Effects:
175  *      A big one...
176  */
177 void
178 DieHorribly(void)
179 {
180         if (jobsRunning)
181                 Job_AbortAll();
182         if (DEBUG(GRAPH2))
183                 Targ_PrintGraph(2);
184         exit(2);                /* Not 1, so -q can distinguish error */
185 }
186
187 /*
188  * Finish --
189  *      Called when aborting due to errors in child shell to signal
190  *      abnormal exit, with the number of errors encountered in Make_Make.
191  *
192  * Results:
193  *      None
194  *
195  * Side Effects:
196  *      The program exits
197  */
198 void
199 Finish(int errors)
200 {
201
202         Fatal("%d error%s", errors, errors == 1 ? "" : "s");
203 }
204
205 /*
206  * emalloc --
207  *      malloc, but die on error.
208  */
209 void *
210 emalloc(size_t len)
211 {
212         void *p;
213
214         if ((p = malloc(len)) == NULL)
215                 enomem();
216         return (p);
217 }
218
219 /*
220  * estrdup --
221  *      strdup, but die on error.
222  */
223 char *
224 estrdup(const char *str)
225 {
226         char *p;
227
228         if ((p = strdup(str)) == NULL)
229                 enomem();
230         return (p);
231 }
232
233 /*
234  * erealloc --
235  *      realloc, but die on error.
236  */
237 void *
238 erealloc(void *ptr, size_t size)
239 {
240
241         if ((ptr = realloc(ptr, size)) == NULL)
242                 enomem();
243         return (ptr);
244 }
245
246 /*
247  * enomem --
248  *      die when out of memory.
249  */
250 static void
251 enomem(void)
252 {
253         err(2, NULL);
254 }
255
256 /*
257  * enunlink --
258  *      Remove a file carefully, avoiding directories.
259  */
260 int
261 eunlink(const char *file)
262 {
263         struct stat st;
264
265         if (lstat(file, &st) == -1)
266                 return (-1);
267
268         if (S_ISDIR(st.st_mode)) {
269                 errno = EISDIR;
270                 return (-1);
271         }
272         return (unlink(file));
273 }
274