Changeset 24 for branches/FREEBSD/src/kmk/main.c
- Timestamp:
- Nov 26, 2002, 10:24:54 PM (23 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
branches/FREEBSD/src/kmk/main.c
r10 r24 35 35 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 36 36 * SUCH DAMAGE. 37 * 38 * @(#)main.c 8.3 (Berkeley) 3/19/94 39 */ 37 */ 38 39 #ifndef lint 40 static const char copyright[] = 41 "@(#) Copyright (c) 1988, 1989, 1990, 1993\n\ 42 The Regents of the University of California. All rights reserved.\n"; 43 #endif /* not lint */ 40 44 41 45 #ifndef lint 42 46 #if 0 43 static char copyright[] = 44 "@(#) Copyright (c) 1988, 1989, 1990, 1993\n\ 45 The Regents of the University of California. All rights reserved.\n"; 47 static char sccsid[] = "@(#)main.c 8.3 (Berkeley) 3/19/94"; 48 #else 49 static const char rcsid[] = 50 "$FreeBSD: src/usr.bin/make/main.c,v 1.35.2.6 2002/07/24 16:50:18 ru Exp $"; 46 51 #endif 47 52 #endif /* not lint */ 48 #include <sys/cdefs.h>49 __FBSDID("$FreeBSD: src/usr.bin/make/main.c,v 1.79 2002/10/10 19:27:48 jmallett Exp $");50 53 51 54 /*- … … 59 62 * invoked. Used by the parse module to implement 60 63 * the .MFLAGS target. 64 * 65 * Error Print a tagged error message. The global 66 * MAKE variable must have been defined. This 67 * takes a format string and two optional 68 * arguments for it. 69 * 70 * Fatal Print an error message and exit. Also takes 71 * a format string and two arguments. 72 * 73 * Punt Aborts all jobs and exits with a message. Also 74 * takes a format string and two arguments. 75 * 76 * Finish Finish things up by printing the number of 77 * errors which occured, as passed to it, and 78 * exiting. 61 79 */ 62 80 … … 80 98 #include <stdio.h> 81 99 #include <sysexits.h> 100 #ifdef __STDC__ 82 101 #include <stdarg.h> 83 #include <unistd.h> 102 #else 103 #include <varargs.h> 104 #endif 84 105 #include "make.h" 85 106 #include "hash.h" … … 88 109 #include "pathnames.h" 89 110 90 #define WANT_ENV_MKLVL 191 92 111 #ifndef DEFMAXLOCAL 93 112 #define DEFMAXLOCAL DEFMAXJOBS … … 103 122 static Boolean noBuiltins; /* -r flag */ 104 123 static Lst makefiles; /* ordered list of makefiles to read */ 124 static Boolean printVars; /* print value of one or more vars */ 105 125 static Boolean expandVars; /* fully expand printed variables */ 106 126 static Lst variables; /* list of variables to print */ … … 121 141 Boolean checkEnvFirst; /* -e flag */ 122 142 Lst envFirstVars; /* (-E) vars to override from env */ 123 BooleanjobsRunning; /* TRUE if the jobs might be running */124 125 static void MainParseArgs (int, char **);126 char * chdir_verify_path (char *, char *);127 static int ReadMakefile (void *, void *);128 static void usage (void);143 static Boolean jobsRunning; /* TRUE if the jobs might be running */ 144 145 static void MainParseArgs __P((int, char **)); 146 char * chdir_verify_path __P((char *, char *)); 147 static int ReadMakefile __P((ClientData, ClientData)); 148 static void usage __P((void)); 129 149 130 150 static char *curdir; /* startup directory */ … … 146 166 */ 147 167 static void 148 MainParseArgs(int argc, char **argv) 149 { 168 MainParseArgs(argc, argv) 169 int argc; 170 char **argv; 171 { 172 extern int optind; 173 extern char *optarg; 150 174 char *p; 151 175 int c; … … 153 177 optind = 1; /* since we're called more than once */ 154 178 #ifdef REMOTE 155 # define OPTFLAGS "B C:D:E:I:L:PSV:Xd:ef:ij:km:nqrstv"179 # define OPTFLAGS "BD:E:I:L:PSV:Xd:ef:ij:km:nqrstv" 156 180 #else 157 # define OPTFLAGS "B C:D:E:I:PSV:Xd:ef:ij:km:nqrstv"181 # define OPTFLAGS "BD:E:I:PSV:Xd:ef:ij:km:nqrstv" 158 182 #endif 159 183 rearg: while((c = getopt(argc, argv, OPTFLAGS)) != -1) { 160 184 switch(c) { 161 case 'C':162 chdir(optarg);163 break;164 185 case 'D': 165 186 Var_Set(optarg, "1", VAR_GLOBAL); … … 173 194 break; 174 195 case 'V': 175 (void)Lst_AtEnd(variables, (void *)optarg); 196 printVars = TRUE; 197 (void)Lst_AtEnd(variables, (ClientData)optarg); 176 198 Var_Append(MAKEFLAGS, "-V", VAR_GLOBAL); 177 199 Var_Append(MAKEFLAGS, optarg, VAR_GLOBAL); … … 264 286 } 265 287 case 'E': 266 p = emalloc(strlen(optarg) + 1); 288 p = malloc(strlen(optarg) + 1); 289 if (!p) 290 Punt("make: cannot allocate memory."); 267 291 (void)strcpy(p, optarg); 268 (void)Lst_AtEnd(envFirstVars, ( void *)p);292 (void)Lst_AtEnd(envFirstVars, (ClientData)p); 269 293 Var_Append(MAKEFLAGS, "-E", VAR_GLOBAL); 270 294 Var_Append(MAKEFLAGS, optarg, VAR_GLOBAL); … … 275 299 break; 276 300 case 'f': 277 (void)Lst_AtEnd(makefiles, ( void *)optarg);301 (void)Lst_AtEnd(makefiles, (ClientData)optarg); 278 302 break; 279 303 case 'i': … … 358 382 goto rearg; 359 383 } 360 (void)Lst_AtEnd(create, ( void *)estrdup(*argv));384 (void)Lst_AtEnd(create, (ClientData)estrdup(*argv)); 361 385 } 362 386 } … … 378 402 */ 379 403 void 380 Main_ParseArgLine(char *line) 404 Main_ParseArgLine(line) 405 char *line; /* Line to fracture */ 381 406 { 382 407 char **argv; /* Manufactured argument vector */ … … 395 420 396 421 char * 397 chdir_verify_path(char *path, char *obpath) 422 chdir_verify_path(path, obpath) 423 char *path; 424 char *obpath; 398 425 { 399 426 struct stat sb; 400 427 401 428 if (stat(path, &sb) == 0 && S_ISDIR(sb.st_mode)) { 402 if (chdir(path) == -1 || getcwd(obpath, MAXPATHLEN) == NULL) {429 if (chdir(path)) { 403 430 warn("warning: %s", path); 404 431 return 0; 405 432 } 406 return obpath; 433 else { 434 if (path[0] != '/') { 435 (void) snprintf(obpath, MAXPATHLEN, "%s/%s", 436 curdir, path); 437 return obpath; 438 } 439 else 440 return path; 441 } 407 442 } 408 443 … … 429 464 */ 430 465 int 431 main(int argc, char **argv) 466 main(argc, argv) 467 int argc; 468 char **argv; 432 469 { 433 470 Lst targs; /* target nodes to create -- passed to Make_Init */ … … 435 472 struct stat sa; 436 473 char *p, *p1, *path, *pathp; 437 #ifdef WANT_ENV_MKLVL 438 #define MKLVL_MAXVAL 500 439 #define MKLVL_ENVVAR "__MKLVL__" 440 int iMkLvl = 0; 441 char *szMkLvl = getenv(MKLVL_ENVVAR); 442 #endif /* WANT_ENV_MKLVL */ 443 char mdpath[MAXPATHLEN]; 444 char obpath[MAXPATHLEN]; 445 char cdpath[MAXPATHLEN]; 474 #ifdef WANT_ENV_PWD 475 struct stat sb; 476 char *pwd; 477 #endif 478 char mdpath[MAXPATHLEN + 1]; 479 char obpath[MAXPATHLEN + 1]; 480 char cdpath[MAXPATHLEN + 1]; 446 481 char *machine = getenv("MACHINE"); 447 482 char *machine_arch = getenv("MACHINE_ARCH"); … … 452 487 static char syspath[] = _PATH_DEFSYSPATH; 453 488 454 #ifdef WANT_ENV_MKLVL455 if ((iMkLvl = szMkLvl ? atoi(szMkLvl) : 0) < 0) {456 iMkLvl = 0;457 }458 if (iMkLvl++ > MKLVL_MAXVAL) {459 errc(2, EAGAIN,460 "Max recursion level (%d) exceeded.", MKLVL_MAXVAL);461 }462 bzero(szMkLvl = emalloc(32), 32);463 sprintf(szMkLvl, "%d", iMkLvl);464 setenv(MKLVL_ENVVAR, szMkLvl, 1);465 #endif /* WANT_ENV_MKLVL */466 467 #if DEFSHELL == 2468 /*469 * Turn off ENV to make ksh happier.470 */471 unsetenv("ENV");472 #endif473 474 489 #ifdef RLIMIT_NOFILE 475 490 /* … … 486 501 #endif 487 502 /* 488 * Find where we are ...503 * Find where we are and take care of PWD for the automounter... 489 504 * All this code is so that we know where we are when we start up 490 505 * on a different machine with pmake. … … 496 511 if (stat(curdir, &sa) == -1) 497 512 err(2, "%s", curdir); 513 514 #ifdef WANT_ENV_PWD 515 if ((pwd = getenv("PWD")) != NULL) { 516 if (stat(pwd, &sb) == 0 && sa.st_ino == sb.st_ino && 517 sa.st_dev == sb.st_dev) 518 (void) strcpy(curdir, pwd); 519 } 520 #endif 498 521 499 522 #if defined(__i386__) && defined(__FreeBSD_version) && \ … … 532 555 struct utsname utsname; 533 556 534 if (uname(&utsname) == -1) 535 err(2, "uname"); 557 if (uname(&utsname) == -1) { 558 perror("make: uname"); 559 exit(2); 560 } 536 561 machine = utsname.machine; 537 562 #else … … 603 628 } 604 629 630 #ifdef WANT_ENV_PWD 631 setenv("PWD", objdir, 1); 632 #endif 633 605 634 create = Lst_Init(FALSE); 606 635 makefiles = Lst_Init(FALSE); 607 636 envFirstVars = Lst_Init(FALSE); 637 printVars = FALSE; 608 638 expandVars = TRUE; 609 639 variables = Lst_Init(FALSE); … … 659 689 Var_Set("MACHINE_ARCH", machine_arch, VAR_GLOBAL); 660 690 Var_Set("MACHINE_CPU", machine_cpu, VAR_GLOBAL); 661 #ifdef MAKE_VERSION662 Var_Set("MAKE_VERSION", MAKE_VERSION, VAR_GLOBAL);663 #endif664 691 665 692 /* … … 691 718 Suff_Init(); 692 719 693 DEFAULT = N ULL;720 DEFAULT = NILGNODE; 694 721 (void)time(&now); 695 722 … … 702 729 LstNode ln; 703 730 704 for (ln = Lst_First(create); ln != N ULL;731 for (ln = Lst_First(create); ln != NILLNODE; 705 732 ln = Lst_Succ(ln)) { 706 733 char *name = (char *)Lst_Datum(ln); … … 742 769 if (Lst_IsEmpty(sysMkPath)) 743 770 Fatal("make: no system rules (%s).", _PATH_DEFSYSMK); 744 ln = Lst_Find(sysMkPath, ( void *)NULL, ReadMakefile);745 if (ln != N ULL)771 ln = Lst_Find(sysMkPath, (ClientData)NULL, ReadMakefile); 772 if (ln != NILLNODE) 746 773 Fatal("make: cannot open %s.", (char *)Lst_Datum(ln)); 747 774 } … … 750 777 LstNode ln; 751 778 752 ln = Lst_Find(makefiles, ( void *)NULL, ReadMakefile);753 if (ln != N ULL)779 ln = Lst_Find(makefiles, (ClientData)NULL, ReadMakefile); 780 if (ln != NILLNODE) 754 781 Fatal("make: cannot open %s.", (char *)Lst_Datum(ln)); 755 } else if (!ReadMakefile("BSDmakefile", NULL)) 756 if (!ReadMakefile("makefile", NULL)) 782 } else if (!ReadMakefile("makefile", NULL)) 757 783 (void)ReadMakefile("Makefile", NULL); 758 784 … … 778 804 */ 779 805 if (Var_Exists("VPATH", VAR_CMD)) { 780 char *vpath, savec;806 char *vpath, *path, *cp, savec; 781 807 /* 782 808 * GCC stores string constants in read-only memory, but … … 800 826 path = cp + 1; 801 827 } while (savec == ':'); 802 (void)free( vpath);828 (void)free((Address)vpath); 803 829 } 804 830 … … 814 840 815 841 /* print the values of any variables requested by the user */ 816 if ( !Lst_IsEmpty(variables)) {842 if (printVars) { 817 843 LstNode ln; 818 844 819 for (ln = Lst_First(variables); ln != N ULL;845 for (ln = Lst_First(variables); ln != NILLNODE; 820 846 ln = Lst_Succ(ln)) { 821 847 char *value; 822 848 if (expandVars) { 823 p1 = emalloc(strlen((char *)Lst_Datum(ln)) + 1 + 3); 849 p1 = malloc(strlen((char *)Lst_Datum(ln)) + 1 + 3); 850 if (!p1) 851 Punt("make: cannot allocate memory."); 824 852 /* This sprintf is safe, because of the malloc above */ 825 853 (void)sprintf(p1, "${%s}", (char *)Lst_Datum(ln)); … … 833 861 free(p1); 834 862 } 835 } else { 836 863 } 864 865 /* 866 * Have now read the entire graph and need to make a list of targets 867 * to create. If none was given on the command line, we consult the 868 * parsing module to find the main target(s) to create. 869 */ 870 if (Lst_IsEmpty(create)) 871 targs = Parse_MainName(); 872 else 873 targs = Targ_FindList(create, TARG_CREATE); 874 875 if (!compatMake && !printVars) { 837 876 /* 838 * Have now read the entire graph and need to make a list of targets 839 * to create. If none was given on the command line, we consult the 840 * parsing module to find the main target(s) to create. 877 * Initialize job module before traversing the graph, now that 878 * any .BEGIN and .END targets have been read. This is done 879 * only if the -q flag wasn't given (to prevent the .BEGIN from 880 * being executed should it exist). 841 881 */ 842 if (Lst_IsEmpty(create)) 843 targs = Parse_MainName(); 844 else 845 targs = Targ_FindList(create, TARG_CREATE); 846 847 if (!compatMake) { 848 /* 849 * Initialize job module before traversing the graph, now that 850 * any .BEGIN and .END targets have been read. This is done 851 * only if the -q flag wasn't given (to prevent the .BEGIN from 852 * being executed should it exist). 853 */ 854 if (!queryFlag) { 855 if (maxLocal == -1) 856 maxLocal = maxJobs; 857 Job_Init(maxJobs, maxLocal); 858 jobsRunning = TRUE; 859 } 860 861 /* Traverse the graph, checking on all the targets */ 862 outOfDate = Make_Run(targs); 863 } else { 864 /* 865 * Compat_Init will take care of creating all the targets as 866 * well as initializing the module. 867 */ 868 Compat_Run(targs); 869 } 870 Lst_Destroy(targs, NOFREE); 871 } 872 882 if (!queryFlag) { 883 if (maxLocal == -1) 884 maxLocal = maxJobs; 885 Job_Init(maxJobs, maxLocal); 886 jobsRunning = TRUE; 887 } 888 889 /* Traverse the graph, checking on all the targets */ 890 outOfDate = Make_Run(targs); 891 } else if (!printVars) { 892 /* 893 * Compat_Init will take care of creating all the targets as 894 * well as initializing the module. 895 */ 896 Compat_Run(targs); 897 } 898 899 Lst_Destroy(targs, NOFREE); 873 900 Lst_Destroy(variables, NOFREE); 874 901 Lst_Destroy(makefiles, NOFREE); 875 Lst_Destroy(create, (void (*) (void *)) free);902 Lst_Destroy(create, (void (*) __P((ClientData))) free); 876 903 877 904 /* print the graph now it's been processed if the user requested it */ … … 904 931 */ 905 932 static Boolean 906 ReadMakefile(void *p, void *q __unused) 907 { 908 char *fname; /* makefile to read */ 933 ReadMakefile(p, q) 934 ClientData p, q; 935 { 936 char *fname = p; /* makefile to read */ 937 extern Lst parseIncPath; 909 938 FILE *stream; 910 char *name, path[MAXPATHLEN ];939 char *name, path[MAXPATHLEN + 1]; 911 940 char *MAKEFILE; 912 941 int setMAKEFILE; 913 914 fname = p;915 942 916 943 if (!strcmp(fname, "-")) { … … 923 950 if (curdir != objdir && *fname != '/') { 924 951 (void)snprintf(path, MAXPATHLEN, "%s/%s", curdir, fname); 925 /*926 * XXX The realpath stuff breaks relative includes927 * XXX in some cases. The problem likely is in928 * XXX parse.c where it does special things in929 * XXX ParseDoInclude if the file is relateive930 * XXX or absolute and not a system file. There931 * XXX it assumes that if the current file that's932 * XXX being included is absolute, that any files933 * XXX that it includes shouldn't do the -I path934 * XXX stuff, which is inconsistant with historical935 * XXX behavior. However, I can't pentrate the mists936 * XXX further, so I'm putting this workaround in937 * XXX here until such time as the underlying bug938 * XXX can be fixed.939 */940 #if THIS_BREAKS_THINGS941 952 if (realpath(path, path) != NULL && 942 953 (stream = fopen(path, "r")) != NULL) { … … 951 962 goto found; 952 963 } 953 #else954 if ((stream = fopen(path, "r")) != NULL) {955 MAKEFILE = fname;956 fname = path;957 goto found;958 }959 } else {960 MAKEFILE = fname;961 if ((stream = fopen(fname, "r")) != NULL)962 goto found;963 }964 #endif965 964 /* look in -I and system include directories. */ 966 965 name = Dir_FindFile(fname, parseIncPath); … … 991 990 * Results: 992 991 * A string containing the output of the command, or the empty string 993 * If err oris not NULL, it contains the reason for the command failure992 * If err is not NULL, it contains the reason for the command failure 994 993 * 995 994 * Side Effects: … … 997 996 */ 998 997 char * 999 Cmd_Exec(char *cmd, char **error) 998 Cmd_Exec(cmd, err) 999 char *cmd; 1000 char **err; 1000 1001 { 1001 1002 char *args[4]; /* Args for invoking the shell */ … … 1009 1010 int cc; 1010 1011 1011 *error = NULL; 1012 1013 *err = NULL; 1012 1014 1013 1015 /* … … 1023 1025 */ 1024 1026 if (pipe(fds) == -1) { 1025 *err or= "Couldn't create pipe for \"%s\"";1027 *err = "Couldn't create pipe for \"%s\""; 1026 1028 goto bad; 1027 1029 } … … 1045 1047 (void) close(fds[1]); 1046 1048 1047 #if defined(DEFSHELL) && DEFSHELL == 01048 (void) execv("/bin/csh", args);1049 #elif DEFSHELL == 11050 1049 (void) execv("/bin/sh", args); 1051 #elif DEFSHELL == 21052 (void) execv("/bin/ksh", args);1053 #else1054 #error "DEFSHELL must be 1 or 2."1055 #endif1056 1050 _exit(1); 1057 1051 /*NOTREACHED*/ 1058 1052 1059 1053 case -1: 1060 *err or= "Couldn't exec \"%s\"";1054 *err = "Couldn't exec \"%s\""; 1061 1055 goto bad; 1062 1056 … … 1089 1083 1090 1084 if (cc == -1) 1091 *err or= "Error reading shell's output for \"%s\"";1085 *err = "Error reading shell's output for \"%s\""; 1092 1086 1093 1087 res = (char *)Buf_GetAll (buf, &cc); … … 1095 1089 1096 1090 if (status) 1097 *err or= "\"%s\" returned non-zero status";1091 *err = "\"%s\" returned non-zero status"; 1098 1092 1099 1093 /* … … 1125 1119 } 1126 1120 1121 /*- 1122 * Error -- 1123 * Print an error message given its format. 1124 * 1125 * Results: 1126 * None. 1127 * 1128 * Side Effects: 1129 * The message is printed. 1130 */ 1131 /* VARARGS */ 1132 void 1133 #ifdef __STDC__ 1134 Error(char *fmt, ...) 1135 #else 1136 Error(va_alist) 1137 va_dcl 1138 #endif 1139 { 1140 va_list ap; 1141 #ifdef __STDC__ 1142 va_start(ap, fmt); 1143 #else 1144 char *fmt; 1145 1146 va_start(ap); 1147 fmt = va_arg(ap, char *); 1148 #endif 1149 (void)vfprintf(stderr, fmt, ap); 1150 va_end(ap); 1151 (void)fprintf(stderr, "\n"); 1152 (void)fflush(stderr); 1153 } 1154 1155 /*- 1156 * Fatal -- 1157 * Produce a Fatal error message. If jobs are running, waits for them 1158 * to finish. 1159 * 1160 * Results: 1161 * None 1162 * 1163 * Side Effects: 1164 * The program exits 1165 */ 1166 /* VARARGS */ 1167 void 1168 #ifdef __STDC__ 1169 Fatal(char *fmt, ...) 1170 #else 1171 Fatal(va_alist) 1172 va_dcl 1173 #endif 1174 { 1175 va_list ap; 1176 #ifdef __STDC__ 1177 va_start(ap, fmt); 1178 #else 1179 char *fmt; 1180 1181 va_start(ap); 1182 fmt = va_arg(ap, char *); 1183 #endif 1184 if (jobsRunning) 1185 Job_Wait(); 1186 1187 (void)vfprintf(stderr, fmt, ap); 1188 va_end(ap); 1189 (void)fprintf(stderr, "\n"); 1190 (void)fflush(stderr); 1191 1192 if (DEBUG(GRAPH2)) 1193 Targ_PrintGraph(2); 1194 exit(2); /* Not 1 so -q can distinguish error */ 1195 } 1196 1197 /* 1198 * Punt -- 1199 * Major exception once jobs are being created. Kills all jobs, prints 1200 * a message and exits. 1201 * 1202 * Results: 1203 * None 1204 * 1205 * Side Effects: 1206 * All children are killed indiscriminately and the program Lib_Exits 1207 */ 1208 /* VARARGS */ 1209 void 1210 #ifdef __STDC__ 1211 Punt(char *fmt, ...) 1212 #else 1213 Punt(va_alist) 1214 va_dcl 1215 #endif 1216 { 1217 va_list ap; 1218 #if __STDC__ 1219 va_start(ap, fmt); 1220 #else 1221 char *fmt; 1222 1223 va_start(ap); 1224 fmt = va_arg(ap, char *); 1225 #endif 1226 1227 (void)fprintf(stderr, "make: "); 1228 (void)vfprintf(stderr, fmt, ap); 1229 va_end(ap); 1230 (void)fprintf(stderr, "\n"); 1231 (void)fflush(stderr); 1232 1233 DieHorribly(); 1234 } 1235 1236 /*- 1237 * DieHorribly -- 1238 * Exit without giving a message. 1239 * 1240 * Results: 1241 * None 1242 * 1243 * Side Effects: 1244 * A big one... 1245 */ 1246 void 1247 DieHorribly() 1248 { 1249 if (jobsRunning) 1250 Job_AbortAll(); 1251 if (DEBUG(GRAPH2)) 1252 Targ_PrintGraph(2); 1253 exit(2); /* Not 1, so -q can distinguish error */ 1254 } 1255 1256 /* 1257 * Finish -- 1258 * Called when aborting due to errors in child shell to signal 1259 * abnormal exit. 1260 * 1261 * Results: 1262 * None 1263 * 1264 * Side Effects: 1265 * The program exits 1266 */ 1267 void 1268 Finish(errors) 1269 int errors; /* number of errors encountered in Make_Make */ 1270 { 1271 Fatal("%d error%s", errors, errors == 1 ? "" : "s"); 1272 } 1273 1274 /* 1275 * emalloc -- 1276 * malloc, but die on error. 1277 */ 1278 void * 1279 emalloc(len) 1280 size_t len; 1281 { 1282 void *p; 1283 1284 if ((p = malloc(len)) == NULL) 1285 enomem(); 1286 return(p); 1287 } 1288 1289 /* 1290 * estrdup -- 1291 * strdup, but die on error. 1292 */ 1293 char * 1294 estrdup(str) 1295 const char *str; 1296 { 1297 char *p; 1298 1299 if ((p = strdup(str)) == NULL) 1300 enomem(); 1301 return(p); 1302 } 1303 1304 /* 1305 * erealloc -- 1306 * realloc, but die on error. 1307 */ 1308 void * 1309 erealloc(ptr, size) 1310 void *ptr; 1311 size_t size; 1312 { 1313 if ((ptr = realloc(ptr, size)) == NULL) 1314 enomem(); 1315 return(ptr); 1316 } 1317 1318 /* 1319 * enomem -- 1320 * die when out of memory. 1321 */ 1322 void 1323 enomem() 1324 { 1325 err(2, NULL); 1326 } 1327 1328 /* 1329 * enunlink -- 1330 * Remove a file carefully, avoiding directories. 1331 */ 1332 int 1333 eunlink(file) 1334 const char *file; 1335 { 1336 struct stat st; 1337 1338 if (lstat(file, &st) == -1) 1339 return -1; 1340 1341 if (S_ISDIR(st.st_mode)) { 1342 errno = EISDIR; 1343 return -1; 1344 } 1345 return unlink(file); 1346 } 1347 1127 1348 /* 1128 1349 * usage -- … … 1130 1351 */ 1131 1352 static void 1132 usage( void)1353 usage() 1133 1354 { 1134 1355 (void)fprintf(stderr, "%s\n%s\n%s\n", … … 1138 1359 exit(2); 1139 1360 } 1361 1362 1363 int 1364 PrintAddr(a, b) 1365 ClientData a; 1366 ClientData b; 1367 { 1368 printf("%lx ", (unsigned long) a); 1369 return b ? 0 : 0; 1370 }
Note:
See TracChangeset
for help on using the changeset viewer.