1141104Sharti/*- 2104818Sjmallett * Copyright (c) 2002 Juli Mallett. All rights reserved. 3104818Sjmallett * Copyright (c) 1988, 1989, 1990, 1993 4104818Sjmallett * The Regents of the University of California. All rights reserved. 5104818Sjmallett * Copyright (c) 1989 by Berkeley Softworks 6104818Sjmallett * All rights reserved. 7104818Sjmallett * 8104818Sjmallett * This code is derived from software contributed to Berkeley by 9104818Sjmallett * Adam de Boor. 10104818Sjmallett * 11104818Sjmallett * Redistribution and use in source and binary forms, with or without 12104818Sjmallett * modification, are permitted provided that the following conditions 13104818Sjmallett * are met: 14104818Sjmallett * 1. Redistributions of source code must retain the above copyright 15104818Sjmallett * notice, this list of conditions and the following disclaimer. 16104818Sjmallett * 2. Redistributions in binary form must reproduce the above copyright 17104818Sjmallett * notice, this list of conditions and the following disclaimer in the 18104818Sjmallett * documentation and/or other materials provided with the distribution. 19104818Sjmallett * 3. All advertising materials mentioning features or use of this software 20104818Sjmallett * must display the following acknowledgement: 21104818Sjmallett * This product includes software developed by the University of 22104818Sjmallett * California, Berkeley and its contributors. 23104818Sjmallett * 4. Neither the name of the University nor the names of its contributors 24104818Sjmallett * may be used to endorse or promote products derived from this software 25104818Sjmallett * without specific prior written permission. 26104818Sjmallett * 27104818Sjmallett * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND 28104818Sjmallett * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 29104818Sjmallett * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 30104818Sjmallett * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE 31104818Sjmallett * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 32104818Sjmallett * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 33104818Sjmallett * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 34104818Sjmallett * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 35104818Sjmallett * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 36104818Sjmallett * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 37104818Sjmallett * SUCH DAMAGE. 38104818Sjmallett * 39104818Sjmallett * @(#)main.c 8.3 (Berkeley) 3/19/94 40104818Sjmallett */ 41104818Sjmallett 42104818Sjmallett#include <sys/cdefs.h> 43104818Sjmallett__FBSDID("$FreeBSD: releng/10.3/usr.bin/make/util.c 146184 2005-05-13 13:47:41Z harti $"); 44104818Sjmallett 45104818Sjmallett/*- 46104818Sjmallett * util.c -- 47104818Sjmallett * General utilitarian routines for make(1). 48104818Sjmallett */ 49104818Sjmallett 50104818Sjmallett#include <sys/types.h> 51104818Sjmallett#include <sys/stat.h> 52104818Sjmallett#include <err.h> 53104818Sjmallett#include <errno.h> 54104818Sjmallett#include <stdarg.h> 55141104Sharti#include <stdlib.h> 56141104Sharti#include <string.h> 57104818Sjmallett#include <unistd.h> 58104818Sjmallett 59141104Sharti#include "globals.h" 60104818Sjmallett#include "job.h" 61141104Sharti#include "targ.h" 62141104Sharti#include "util.h" 63104818Sjmallett 64141139Shartistatic void enomem(void) __dead2; 65141139Sharti 66104818Sjmallett/*- 67104818Sjmallett * Debug -- 68104818Sjmallett * Print a debugging message given its format. 69104818Sjmallett * 70104818Sjmallett * Results: 71104818Sjmallett * None. 72104818Sjmallett * 73104818Sjmallett * Side Effects: 74104818Sjmallett * The message is printed. 75104818Sjmallett */ 76104818Sjmallett/* VARARGS */ 77104818Sjmallettvoid 78104818SjmallettDebug(const char *fmt, ...) 79104818Sjmallett{ 80104818Sjmallett va_list ap; 81104818Sjmallett 82104818Sjmallett va_start(ap, fmt); 83138232Sharti vfprintf(stderr, fmt, ap); 84104818Sjmallett va_end(ap); 85138232Sharti fflush(stderr); 86104818Sjmallett} 87104818Sjmallett 88104818Sjmallett/*- 89143278Sharti * Print a debugging message given its format and append the current 90143278Sharti * errno description. Terminate with a newline. 91143278Sharti */ 92143278Sharti/* VARARGS */ 93143278Shartivoid 94143278ShartiDebugM(const char *fmt, ...) 95143278Sharti{ 96143278Sharti va_list ap; 97143278Sharti int e = errno; 98143278Sharti 99143278Sharti va_start(ap, fmt); 100143278Sharti vfprintf(stderr, fmt, ap); 101143278Sharti fprintf(stderr, ": %s\n", strerror(e)); 102143278Sharti va_end(ap); 103143278Sharti fflush(stderr); 104143278Sharti} 105143278Sharti 106143278Sharti/*- 107104818Sjmallett * Error -- 108104818Sjmallett * Print an error message given its format. 109104818Sjmallett * 110104818Sjmallett * Results: 111104818Sjmallett * None. 112104818Sjmallett * 113104818Sjmallett * Side Effects: 114104818Sjmallett * The message is printed. 115104818Sjmallett */ 116104818Sjmallett/* VARARGS */ 117104818Sjmallettvoid 118104818SjmallettError(const char *fmt, ...) 119104818Sjmallett{ 120104818Sjmallett va_list ap; 121104818Sjmallett 122104818Sjmallett va_start(ap, fmt); 123138232Sharti vfprintf(stderr, fmt, ap); 124104818Sjmallett va_end(ap); 125138232Sharti fprintf(stderr, "\n"); 126138232Sharti fflush(stderr); 127104818Sjmallett} 128104818Sjmallett 129104818Sjmallett/*- 130104818Sjmallett * Fatal -- 131104818Sjmallett * Produce a Fatal error message. If jobs are running, waits for them 132104818Sjmallett * to finish. 133104818Sjmallett * 134104818Sjmallett * Results: 135104818Sjmallett * None 136104818Sjmallett * 137104818Sjmallett * Side Effects: 138104818Sjmallett * The program exits 139104818Sjmallett */ 140104818Sjmallett/* VARARGS */ 141104818Sjmallettvoid 142104818SjmallettFatal(const char *fmt, ...) 143104818Sjmallett{ 144104818Sjmallett va_list ap; 145104818Sjmallett 146104818Sjmallett va_start(ap, fmt); 147104818Sjmallett if (jobsRunning) 148104818Sjmallett Job_Wait(); 149104818Sjmallett 150138232Sharti vfprintf(stderr, fmt, ap); 151104818Sjmallett va_end(ap); 152138232Sharti fprintf(stderr, "\n"); 153138232Sharti fflush(stderr); 154104818Sjmallett 155104818Sjmallett if (DEBUG(GRAPH2)) 156104818Sjmallett Targ_PrintGraph(2); 157104818Sjmallett exit(2); /* Not 1 so -q can distinguish error */ 158104818Sjmallett} 159104818Sjmallett 160104818Sjmallett/* 161104818Sjmallett * Punt -- 162104818Sjmallett * Major exception once jobs are being created. Kills all jobs, prints 163104818Sjmallett * a message and exits. 164104818Sjmallett * 165104818Sjmallett * Results: 166104818Sjmallett * None 167104818Sjmallett * 168104818Sjmallett * Side Effects: 169104818Sjmallett * All children are killed indiscriminately and the program Lib_Exits 170104818Sjmallett */ 171104818Sjmallett/* VARARGS */ 172104818Sjmallettvoid 173104818SjmallettPunt(const char *fmt, ...) 174104818Sjmallett{ 175104818Sjmallett va_list ap; 176104818Sjmallett 177104818Sjmallett va_start(ap, fmt); 178138232Sharti fprintf(stderr, "make: "); 179138232Sharti vfprintf(stderr, fmt, ap); 180104818Sjmallett va_end(ap); 181138232Sharti fprintf(stderr, "\n"); 182138232Sharti fflush(stderr); 183104818Sjmallett 184104818Sjmallett DieHorribly(); 185104818Sjmallett} 186104818Sjmallett 187104818Sjmallett/*- 188104818Sjmallett * DieHorribly -- 189104818Sjmallett * Exit without giving a message. 190104818Sjmallett * 191104818Sjmallett * Results: 192104818Sjmallett * None 193104818Sjmallett * 194104818Sjmallett * Side Effects: 195104818Sjmallett * A big one... 196104818Sjmallett */ 197104818Sjmallettvoid 198104818SjmallettDieHorribly(void) 199104818Sjmallett{ 200104818Sjmallett if (jobsRunning) 201104818Sjmallett Job_AbortAll(); 202104818Sjmallett if (DEBUG(GRAPH2)) 203104818Sjmallett Targ_PrintGraph(2); 204104818Sjmallett exit(2); /* Not 1, so -q can distinguish error */ 205104818Sjmallett} 206104818Sjmallett 207104818Sjmallett/* 208104818Sjmallett * Finish -- 209104818Sjmallett * Called when aborting due to errors in child shell to signal 210104818Sjmallett * abnormal exit, with the number of errors encountered in Make_Make. 211104818Sjmallett * 212104818Sjmallett * Results: 213104818Sjmallett * None 214104818Sjmallett * 215104818Sjmallett * Side Effects: 216104818Sjmallett * The program exits 217104818Sjmallett */ 218104818Sjmallettvoid 219104818SjmallettFinish(int errors) 220104818Sjmallett{ 221138232Sharti 222104818Sjmallett Fatal("%d error%s", errors, errors == 1 ? "" : "s"); 223104818Sjmallett} 224104818Sjmallett 225104818Sjmallett/* 226104818Sjmallett * emalloc -- 227104818Sjmallett * malloc, but die on error. 228104818Sjmallett */ 229104818Sjmallettvoid * 230104818Sjmallettemalloc(size_t len) 231104818Sjmallett{ 232104818Sjmallett void *p; 233104818Sjmallett 234104818Sjmallett if ((p = malloc(len)) == NULL) 235104818Sjmallett enomem(); 236138232Sharti return (p); 237104818Sjmallett} 238104818Sjmallett 239104818Sjmallett/* 240104818Sjmallett * estrdup -- 241104818Sjmallett * strdup, but die on error. 242104818Sjmallett */ 243104818Sjmallettchar * 244104818Sjmallettestrdup(const char *str) 245104818Sjmallett{ 246104818Sjmallett char *p; 247104818Sjmallett 248104818Sjmallett if ((p = strdup(str)) == NULL) 249104818Sjmallett enomem(); 250138232Sharti return (p); 251104818Sjmallett} 252104818Sjmallett 253104818Sjmallett/* 254104818Sjmallett * erealloc -- 255104818Sjmallett * realloc, but die on error. 256104818Sjmallett */ 257104818Sjmallettvoid * 258104818Sjmalletterealloc(void *ptr, size_t size) 259104818Sjmallett{ 260138232Sharti 261104818Sjmallett if ((ptr = realloc(ptr, size)) == NULL) 262104818Sjmallett enomem(); 263138232Sharti return (ptr); 264104818Sjmallett} 265104818Sjmallett 266104818Sjmallett/* 267104818Sjmallett * enomem -- 268104818Sjmallett * die when out of memory. 269104818Sjmallett */ 270141139Shartistatic void 271104818Sjmallettenomem(void) 272104818Sjmallett{ 273104818Sjmallett err(2, NULL); 274104818Sjmallett} 275104818Sjmallett 276104818Sjmallett/* 277104818Sjmallett * enunlink -- 278104818Sjmallett * Remove a file carefully, avoiding directories. 279104818Sjmallett */ 280104818Sjmallettint 281104818Sjmalletteunlink(const char *file) 282104818Sjmallett{ 283104818Sjmallett struct stat st; 284104818Sjmallett 285104818Sjmallett if (lstat(file, &st) == -1) 286138232Sharti return (-1); 287104818Sjmallett 288104818Sjmallett if (S_ISDIR(st.st_mode)) { 289104818Sjmallett errno = EISDIR; 290138232Sharti return (-1); 291104818Sjmallett } 292138232Sharti return (unlink(file)); 293104818Sjmallett} 294104818Sjmallett 295143414Sharti/* 296143414Sharti * Convert a flag word to a printable thing and print it 297143414Sharti */ 298143414Shartivoid 299146184Shartiprint_flags(FILE *fp, const struct flag2str *tab, u_int flags, int par) 300143414Sharti{ 301143414Sharti int first = 1; 302143414Sharti 303146184Sharti if (par) 304146184Sharti fprintf(fp, "("); 305143414Sharti while (tab->str != NULL) { 306143414Sharti if (flags & tab->flag) { 307143414Sharti if (!first) 308146184Sharti fprintf(fp, par ? "|" : " "); 309143414Sharti first = 0; 310143414Sharti fprintf(fp, "%s", tab->str); 311143414Sharti } 312143414Sharti tab++; 313143414Sharti } 314146184Sharti if (par) 315146184Sharti fprintf(fp, ")"); 316143414Sharti} 317