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 * @(#)main.c 8.3 (Berkeley) 3/19/94 40 */ 41 42#include <sys/cdefs.h> 43__FBSDID("$FreeBSD: releng/10.2/usr.bin/make/util.c 146184 2005-05-13 13:47:41Z harti $"); 44 45/*- 46 * util.c -- 47 * General utilitarian routines for make(1). 48 */ 49 50#include <sys/types.h> 51#include <sys/stat.h> 52#include <err.h> 53#include <errno.h> 54#include <stdarg.h> 55#include <stdlib.h> 56#include <string.h> 57#include <unistd.h> 58 59#include "globals.h" 60#include "job.h" 61#include "targ.h" 62#include "util.h" 63 64static void enomem(void) __dead2; 65 66/*- 67 * Debug -- 68 * Print a debugging message given its format. 69 * 70 * Results: 71 * None. 72 * 73 * Side Effects: 74 * The message is printed. 75 */ 76/* VARARGS */ 77void 78Debug(const char *fmt, ...) 79{ 80 va_list ap; 81 82 va_start(ap, fmt); 83 vfprintf(stderr, fmt, ap); 84 va_end(ap); 85 fflush(stderr); 86} 87 88/*- 89 * Print a debugging message given its format and append the current 90 * errno description. Terminate with a newline. 91 */ 92/* VARARGS */ 93void 94DebugM(const char *fmt, ...) 95{ 96 va_list ap; 97 int e = errno; 98 99 va_start(ap, fmt); 100 vfprintf(stderr, fmt, ap); 101 fprintf(stderr, ": %s\n", strerror(e)); 102 va_end(ap); 103 fflush(stderr); 104} 105 106/*- 107 * Error -- 108 * Print an error message given its format. 109 * 110 * Results: 111 * None. 112 * 113 * Side Effects: 114 * The message is printed. 115 */ 116/* VARARGS */ 117void 118Error(const char *fmt, ...) 119{ 120 va_list ap; 121 122 va_start(ap, fmt); 123 vfprintf(stderr, fmt, ap); 124 va_end(ap); 125 fprintf(stderr, "\n"); 126 fflush(stderr); 127} 128 129/*- 130 * Fatal -- 131 * Produce a Fatal error message. If jobs are running, waits for them 132 * to finish. 133 * 134 * Results: 135 * None 136 * 137 * Side Effects: 138 * The program exits 139 */ 140/* VARARGS */ 141void 142Fatal(const char *fmt, ...) 143{ 144 va_list ap; 145 146 va_start(ap, fmt); 147 if (jobsRunning) 148 Job_Wait(); 149 150 vfprintf(stderr, fmt, ap); 151 va_end(ap); 152 fprintf(stderr, "\n"); 153 fflush(stderr); 154 155 if (DEBUG(GRAPH2)) 156 Targ_PrintGraph(2); 157 exit(2); /* Not 1 so -q can distinguish error */ 158} 159 160/* 161 * Punt -- 162 * Major exception once jobs are being created. Kills all jobs, prints 163 * a message and exits. 164 * 165 * Results: 166 * None 167 * 168 * Side Effects: 169 * All children are killed indiscriminately and the program Lib_Exits 170 */ 171/* VARARGS */ 172void 173Punt(const char *fmt, ...) 174{ 175 va_list ap; 176 177 va_start(ap, fmt); 178 fprintf(stderr, "make: "); 179 vfprintf(stderr, fmt, ap); 180 va_end(ap); 181 fprintf(stderr, "\n"); 182 fflush(stderr); 183 184 DieHorribly(); 185} 186 187/*- 188 * DieHorribly -- 189 * Exit without giving a message. 190 * 191 * Results: 192 * None 193 * 194 * Side Effects: 195 * A big one... 196 */ 197void 198DieHorribly(void) 199{ 200 if (jobsRunning) 201 Job_AbortAll(); 202 if (DEBUG(GRAPH2)) 203 Targ_PrintGraph(2); 204 exit(2); /* Not 1, so -q can distinguish error */ 205} 206 207/* 208 * Finish -- 209 * Called when aborting due to errors in child shell to signal 210 * abnormal exit, with the number of errors encountered in Make_Make. 211 * 212 * Results: 213 * None 214 * 215 * Side Effects: 216 * The program exits 217 */ 218void 219Finish(int errors) 220{ 221 222 Fatal("%d error%s", errors, errors == 1 ? "" : "s"); 223} 224 225/* 226 * emalloc -- 227 * malloc, but die on error. 228 */ 229void * 230emalloc(size_t len) 231{ 232 void *p; 233 234 if ((p = malloc(len)) == NULL) 235 enomem(); 236 return (p); 237} 238 239/* 240 * estrdup -- 241 * strdup, but die on error. 242 */ 243char * 244estrdup(const char *str) 245{ 246 char *p; 247 248 if ((p = strdup(str)) == NULL) 249 enomem(); 250 return (p); 251} 252 253/* 254 * erealloc -- 255 * realloc, but die on error. 256 */ 257void * 258erealloc(void *ptr, size_t size) 259{ 260 261 if ((ptr = realloc(ptr, size)) == NULL) 262 enomem(); 263 return (ptr); 264} 265 266/* 267 * enomem -- 268 * die when out of memory. 269 */ 270static void 271enomem(void) 272{ 273 err(2, NULL); 274} 275 276/* 277 * enunlink -- 278 * Remove a file carefully, avoiding directories. 279 */ 280int 281eunlink(const char *file) 282{ 283 struct stat st; 284 285 if (lstat(file, &st) == -1) 286 return (-1); 287 288 if (S_ISDIR(st.st_mode)) { 289 errno = EISDIR; 290 return (-1); 291 } 292 return (unlink(file)); 293} 294 295/* 296 * Convert a flag word to a printable thing and print it 297 */ 298void 299print_flags(FILE *fp, const struct flag2str *tab, u_int flags, int par) 300{ 301 int first = 1; 302 303 if (par) 304 fprintf(fp, "("); 305 while (tab->str != NULL) { 306 if (flags & tab->flag) { 307 if (!first) 308 fprintf(fp, par ? "|" : " "); 309 first = 0; 310 fprintf(fp, "%s", tab->str); 311 } 312 tab++; 313 } 314 if (par) 315 fprintf(fp, ")"); 316} 317