Clean up chdir_verify_path() and add comments.
[dragonfly.git] / usr.bin / make / main.c
1 /*-
2  * Copyright (c) 1988, 1989, 1990, 1993
3  *      The Regents of the University of California.  All rights reserved.
4  * Copyright (c) 1989 by Berkeley Softworks
5  * All rights reserved.
6  *
7  * This code is derived from software contributed to Berkeley by
8  * Adam de Boor.
9  *
10  * Redistribution and use in source and binary forms, with or without
11  * modification, are permitted provided that the following conditions
12  * are met:
13  * 1. Redistributions of source code must retain the above copyright
14  *    notice, this list of conditions and the following disclaimer.
15  * 2. Redistributions in binary form must reproduce the above copyright
16  *    notice, this list of conditions and the following disclaimer in the
17  *    documentation and/or other materials provided with the distribution.
18  * 3. All advertising materials mentioning features or use of this software
19  *    must display the following acknowledgement:
20  *      This product includes software developed by the University of
21  *      California, Berkeley and its contributors.
22  * 4. Neither the name of the University nor the names of its contributors
23  *    may be used to endorse or promote products derived from this software
24  *    without specific prior written permission.
25  *
26  * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
27  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
28  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
29  * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
30  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
31  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
32  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
33  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
34  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
35  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
36  * SUCH DAMAGE.
37  *
38  * @(#) Copyright (c) 1988, 1989, 1990, 1993 The Regents of the University of California.  All rights reserved.
39  * @(#)main.c   8.3 (Berkeley) 3/19/94
40  * $FreeBSD: src/usr.bin/make/main.c,v 1.118 2005/02/13 13:33:56 harti Exp $
41  * $DragonFly: src/usr.bin/make/main.c,v 1.94 2005/05/16 17:32:15 okumoto Exp $
42  */
43
44 /*
45  * main.c
46  *      The main file for this entire program. Exit routines etc
47  *      reside here.
48  *
49  * Utility functions defined in this file:
50  *      Main_ParseArgLine
51  *                      Takes a line of arguments, breaks them and
52  *                      treats them as if they were given when first
53  *                      invoked. Used by the parse module to implement
54  *                      the .MFLAGS target.
55  */
56
57 #ifndef MACHINE
58 #include <sys/utsname.h>
59 #endif
60 #include <sys/param.h>
61 #include <sys/stat.h>
62 #include <sys/time.h>
63 #include <sys/queue.h>
64 #include <sys/resource.h>
65 #include <sys/wait.h>
66 #include <err.h>
67 #include <errno.h>
68 #include <stdlib.h>
69 #include <string.h>
70 #include <unistd.h>
71
72 #include "arch.h"
73 #include "buf.h"
74 #include "config.h"
75 #include "dir.h"
76 #include "globals.h"
77 #include "job.h"
78 #include "make.h"
79 #include "parse.h"
80 #include "pathnames.h"
81 #include "str.h"
82 #include "suff.h"
83 #include "targ.h"
84 #include "util.h"
85 #include "var.h"
86
87 extern char **environ;  /* XXX what header declares this variable? */
88
89 #define WANT_ENV_MKLVL  1
90 #define MKLVL_MAXVAL    500
91 #define MKLVL_ENVVAR    "__MKLVL__"
92
93 /*
94  * DEFMAXJOBS
95  *      This control the default concurrency. On no occasion will more
96  *      than DEFMAXJOBS targets be created at once.
97  */
98 #define DEFMAXJOBS      1
99
100 /* ordered list of makefiles to read */
101 static Lst makefiles = Lst_Initializer(makefiles);
102
103 /* list of variables to print */
104 static Lst variables = Lst_Initializer(variables);
105
106 static Boolean  expandVars;     /* fully expand printed variables */
107 static Boolean  noBuiltins;     /* -r flag */
108 static Boolean  forceJobs;      /* -j argument given */
109 static char     *curdir;        /* startup directory */
110 static char     *objdir;        /* where we chdir'ed to */
111
112 /* (-E) vars to override from env */
113 Lst envFirstVars = Lst_Initializer(envFirstVars);
114
115 /* Targets to be made */
116 Lst create = Lst_Initializer(create);
117
118 Boolean         allPrecious;    /* .PRECIOUS given on line by itself */
119 Boolean         beSilent;       /* -s flag */
120 Boolean         beVerbose;      /* -v flag */
121 Boolean         compatMake;     /* -B argument */
122 Boolean         debug;          /* -d flag */
123 Boolean         ignoreErrors;   /* -i flag */
124 int             jobLimit;       /* -j argument */
125 Boolean         jobsRunning;    /* TRUE if the jobs might be running */
126 Boolean         keepgoing;      /* -k flag */
127 Boolean         noExecute;      /* -n flag */
128 Boolean         queryFlag;      /* -q flag */
129 Boolean         touchFlag;      /* -t flag */
130 Boolean         usePipes;       /* !-P flag */
131 uint32_t        warn_cmd;       /* command line warning flags */
132 uint32_t        warn_flags;     /* actual warning flags */
133 uint32_t        warn_nocmd;     /* command line no-warning flags */
134
135 time_t          now;            /* Time at start of make */
136 struct GNode    *DEFAULT;       /* .DEFAULT node */
137
138 /**
139  * Exit with usage message.
140  */
141 static void
142 usage(void)
143 {
144         fprintf(stderr,
145             "usage: make [-BPSXeiknqrstv] [-C directory] [-D variable]\n"
146             "\t[-d flags] [-E variable] [-f makefile] [-I directory]\n"
147             "\t[-j max_jobs] [-m directory] [-V variable]\n"
148             "\t[variable=value] [target ...]\n");
149         exit(2);
150 }
151
152 /**
153  * MFLAGS_append
154  *      Append a flag with an optional argument to MAKEFLAGS and MFLAGS
155  */
156 static void
157 MFLAGS_append(const char *flag, char *arg)
158 {
159         char *str;
160
161         Var_Append(".MAKEFLAGS", flag, VAR_GLOBAL);
162         if (arg != NULL) {
163                 str = MAKEFLAGS_quote(arg);
164                 Var_Append(".MAKEFLAGS", str, VAR_GLOBAL);
165                 free(str);
166         }
167
168         Var_Append("MFLAGS", flag, VAR_GLOBAL);
169         if (arg != NULL) {
170                 str = MAKEFLAGS_quote(arg);
171                 Var_Append("MFLAGS", str, VAR_GLOBAL);
172                 free(str);
173         }
174 }
175
176 /**
177  * Open and parse the given makefile.
178  *
179  * Results:
180  *      TRUE if ok. FALSE if couldn't open file.
181  */
182 static Boolean
183 ReadMakefile(const char p[])
184 {
185         char *fname;                    /* makefile to read */
186         FILE *stream;
187         char *name, path[MAXPATHLEN];
188         char *MAKEFILE;
189         int setMAKEFILE;
190
191         /* XXX - remove this once constification is done */
192         fname = estrdup(p);
193
194         if (!strcmp(fname, "-")) {
195                 Parse_File("(stdin)", stdin);
196                 Var_SetGlobal("MAKEFILE", "");
197         } else {
198                 setMAKEFILE = strcmp(fname, ".depend");
199
200                 /* if we've chdir'd, rebuild the path name */
201                 if (curdir != objdir && *fname != '/') {
202                         snprintf(path, MAXPATHLEN, "%s/%s", curdir, fname);
203                         /*
204                          * XXX The realpath stuff breaks relative includes
205                          * XXX in some cases.   The problem likely is in
206                          * XXX parse.c where it does special things in
207                          * XXX ParseDoInclude if the file is relateive
208                          * XXX or absolute and not a system file.  There
209                          * XXX it assumes that if the current file that's
210                          * XXX being included is absolute, that any files
211                          * XXX that it includes shouldn't do the -I path
212                          * XXX stuff, which is inconsistant with historical
213                          * XXX behavior.  However, I can't pentrate the mists
214                          * XXX further, so I'm putting this workaround in
215                          * XXX here until such time as the underlying bug
216                          * XXX can be fixed.
217                          */
218 #if THIS_BREAKS_THINGS
219                         if (realpath(path, path) != NULL &&
220                             (stream = fopen(path, "r")) != NULL) {
221                                 MAKEFILE = fname;
222                                 fname = path;
223                                 goto found;
224                         }
225                 } else if (realpath(fname, path) != NULL) {
226                         MAKEFILE = fname;
227                         fname = path;
228                         if ((stream = fopen(fname, "r")) != NULL)
229                                 goto found;
230                 }
231 #else
232                         if ((stream = fopen(path, "r")) != NULL) {
233                                 MAKEFILE = fname;
234                                 fname = path;
235                                 goto found;
236                         }
237                 } else {
238                         MAKEFILE = fname;
239                         if ((stream = fopen(fname, "r")) != NULL)
240                                 goto found;
241                 }
242 #endif
243                 /* look in -I and system include directories. */
244                 name = Path_FindFile(fname, &parseIncPath);
245                 if (!name)
246                         name = Path_FindFile(fname, &sysIncPath);
247                 if (!name || !(stream = fopen(name, "r")))
248                         return (FALSE);
249                 MAKEFILE = fname = name;
250                 /*
251                  * set the MAKEFILE variable desired by System V fans -- the
252                  * placement of the setting here means it gets set to the last
253                  * makefile specified, as it is set by SysV make.
254                  */
255 found:
256                 if (setMAKEFILE)
257                         Var_SetGlobal("MAKEFILE", MAKEFILE);
258                 Parse_File(fname, stream);
259                 fclose(stream);
260         }
261         return (TRUE);
262 }
263
264 /**
265  * Main_ParseWarn
266  *
267  *      Handle argument to warning option.
268  */
269 int
270 Main_ParseWarn(const char *arg, int iscmd)
271 {
272         int i, neg;
273
274         static const struct {
275                 const char      *option;
276                 uint32_t        flag;
277         } options[] = {
278                 { "dirsyntax",  WARN_DIRSYNTAX },
279                 { NULL,         0 }
280         };
281
282         neg = 0;
283         if (arg[0] == 'n' && arg[1] == 'o') {
284                 neg = 1;
285                 arg += 2;
286         }
287
288         for (i = 0; options[i].option != NULL; i++)
289                 if (strcmp(arg, options[i].option) == 0)
290                         break;
291
292         if (options[i].option == NULL)
293                 /* unknown option */
294                 return (-1);
295
296         if (iscmd) {
297                 if (!neg) {
298                         warn_cmd |= options[i].flag;
299                         warn_nocmd &= ~options[i].flag;
300                         warn_flags |= options[i].flag;
301                 } else {
302                         warn_nocmd |= options[i].flag;
303                         warn_cmd &= ~options[i].flag;
304                         warn_flags &= ~options[i].flag;
305                 }
306         } else {
307                 if (!neg) {
308                         warn_flags |= (options[i].flag & ~warn_nocmd);
309                 } else {
310                         warn_flags &= ~(options[i].flag | warn_cmd);
311                 }
312         }
313         return (0);
314 }
315
316 /**
317  * MainParseArgs
318  *      Parse a given argument vector. Called from main() and from
319  *      Main_ParseArgLine() when the .MAKEFLAGS target is used.
320  *
321  *      XXX: Deal with command line overriding .MAKEFLAGS in makefile
322  *
323  * Side Effects:
324  *      Various global and local flags will be set depending on the flags
325  *      given
326  */
327 static void
328 MainParseArgs(int argc, char **argv)
329 {
330         int c;
331         Boolean found_dd = FALSE;
332
333 rearg:
334         optind = 1;     /* since we're called more than once */
335         optreset = 1;
336 #define OPTFLAGS "ABC:D:E:I:PSV:Xd:ef:ij:km:nqrstvx:"
337         for (;;) {
338                 if ((optind < argc) && strcmp(argv[optind], "--") == 0) {
339                         found_dd = TRUE;
340                 }
341                 if ((c = getopt(argc, argv, OPTFLAGS)) == -1) {
342                         break;
343                 }
344                 switch(c) {
345
346                 case 'A':
347                         arch_fatal = FALSE;
348                         MFLAGS_append("-A", NULL);
349                         break;
350                 case 'C':
351                         if (chdir(optarg) == -1)
352                                 err(1, "chdir %s", optarg);
353                         break;
354                 case 'D':
355                         Var_SetGlobal(optarg, "1");
356                         MFLAGS_append("-D", optarg);
357                         break;
358                 case 'I':
359                         Parse_AddIncludeDir(optarg);
360                         MFLAGS_append("-I", optarg);
361                         break;
362                 case 'V':
363                         Lst_AtEnd(&variables, estrdup(optarg));
364                         MFLAGS_append("-V", optarg);
365                         break;
366                 case 'X':
367                         expandVars = FALSE;
368                         break;
369                 case 'B':
370                         compatMake = TRUE;
371                         MFLAGS_append("-B", NULL);
372                         unsetenv("MAKE_JOBS_FIFO");
373                         break;
374                 case 'P':
375                         usePipes = FALSE;
376                         MFLAGS_append("-P", NULL);
377                         break;
378                 case 'S':
379                         keepgoing = FALSE;
380                         MFLAGS_append("-S", NULL);
381                         break;
382                 case 'd': {
383                         char *modules = optarg;
384
385                         for (; *modules; ++modules)
386                                 switch (*modules) {
387                                 case 'A':
388                                         debug = ~0;
389                                         break;
390                                 case 'a':
391                                         debug |= DEBUG_ARCH;
392                                         break;
393                                 case 'c':
394                                         debug |= DEBUG_COND;
395                                         break;
396                                 case 'd':
397                                         debug |= DEBUG_DIR;
398                                         break;
399                                 case 'f':
400                                         debug |= DEBUG_FOR;
401                                         break;
402                                 case 'g':
403                                         if (modules[1] == '1') {
404                                                 debug |= DEBUG_GRAPH1;
405                                                 ++modules;
406                                         }
407                                         else if (modules[1] == '2') {
408                                                 debug |= DEBUG_GRAPH2;
409                                                 ++modules;
410                                         }
411                                         break;
412                                 case 'j':
413                                         debug |= DEBUG_JOB;
414                                         break;
415                                 case 'l':
416                                         debug |= DEBUG_LOUD;
417                                         break;
418                                 case 'm':
419                                         debug |= DEBUG_MAKE;
420                                         break;
421                                 case 's':
422                                         debug |= DEBUG_SUFF;
423                                         break;
424                                 case 't':
425                                         debug |= DEBUG_TARG;
426                                         break;
427                                 case 'v':
428                                         debug |= DEBUG_VAR;
429                                         break;
430                                 default:
431                                         warnx("illegal argument to d option "
432                                             "-- %c", *modules);
433                                         usage();
434                                 }
435                         MFLAGS_append("-d", optarg);
436                         break;
437                 }
438                 case 'E':
439                         Lst_AtEnd(&envFirstVars, estrdup(optarg));
440                         MFLAGS_append("-E", optarg);
441                         break;
442                 case 'e':
443                         checkEnvFirst = TRUE;
444                         MFLAGS_append("-e", NULL);
445                         break;
446                 case 'f':
447                         Lst_AtEnd(&makefiles, estrdup(optarg));
448                         break;
449                 case 'i':
450                         ignoreErrors = TRUE;
451                         MFLAGS_append("-i", NULL);
452                         break;
453                 case 'j': {
454                         char *endptr;
455
456                         forceJobs = TRUE;
457                         jobLimit = strtol(optarg, &endptr, 10);
458                         if (jobLimit <= 0 || *endptr != '\0') {
459                                 warnx("illegal number, -j argument -- %s",
460                                     optarg);
461                                 usage();
462                         }
463                         MFLAGS_append("-j", optarg);
464                         break;
465                 }
466                 case 'k':
467                         keepgoing = TRUE;
468                         MFLAGS_append("-k", NULL);
469                         break;
470                 case 'm':
471                         Path_AddDir(&sysIncPath, optarg);
472                         MFLAGS_append("-m", optarg);
473                         break;
474                 case 'n':
475                         noExecute = TRUE;
476                         MFLAGS_append("-n", NULL);
477                         break;
478                 case 'q':
479                         queryFlag = TRUE;
480                         /* Kind of nonsensical, wot? */
481                         MFLAGS_append("-q", NULL);
482                         break;
483                 case 'r':
484                         noBuiltins = TRUE;
485                         MFLAGS_append("-r", NULL);
486                         break;
487                 case 's':
488                         beSilent = TRUE;
489                         MFLAGS_append("-s", NULL);
490                         break;
491                 case 't':
492                         touchFlag = TRUE;
493                         MFLAGS_append("-t", NULL);
494                         break;
495                 case 'v':
496                         beVerbose = TRUE;
497                         MFLAGS_append("-v", NULL);
498                         break;
499                 case 'x':
500                         if (Main_ParseWarn(optarg, 1) != -1)
501                                 MFLAGS_append("-x", optarg);
502                         break;
503                                 
504                 default:
505                 case '?':
506                         usage();
507                 }
508         }
509         argv += optind;
510         argc -= optind;
511
512         oldVars = TRUE;
513
514         /*
515          * Parse the rest of the arguments.
516          *      o Check for variable assignments and perform them if so.
517          *      o Check for more flags and restart getopt if so.
518          *      o Anything else is taken to be a target and added
519          *        to the end of the "create" list.
520          */
521         for (; *argv != NULL; ++argv, --argc) {
522                 if (Parse_IsVar(*argv)) {
523                         char *ptr = MAKEFLAGS_quote(*argv);
524
525                         Var_Append(".MAKEFLAGS", ptr, VAR_GLOBAL);
526                         Parse_DoVar(*argv, VAR_CMD);
527                         free(ptr);
528
529                 } else if ((*argv)[0] == '-') {
530                         if ((*argv)[1] == '\0') {
531                                 /*
532                                  * (*argv) is a single dash, so we
533                                  * just ignore it.
534                                  */
535                         } else if (found_dd) {
536                                 /*
537                                  * Double dash has been found, ignore
538                                  * any more options.  But what do we do
539                                  * with it?  For now treat it like a target.
540                                  */
541                                 Lst_AtEnd(&create, estrdup(*argv));
542                         } else {
543                                 /*
544                                  * (*argv) is a -flag, so backup argv and
545                                  * argc.  getopt() expects options to start
546                                  * in the 2nd position.
547                                  */
548                                 argc++;
549                                 argv--;
550                                 goto rearg;
551                         }
552
553                 } else if ((*argv)[0] == '\0') {
554                         Punt("illegal (null) argument.");
555
556                 } else {
557                         Lst_AtEnd(&create, estrdup(*argv));
558                 }
559         }
560 }
561
562 /**
563  * Main_ParseArgLine
564  *      Used by the parse module when a .MFLAGS or .MAKEFLAGS target
565  *      is encountered and by main() when reading the .MAKEFLAGS envariable.
566  *      Takes a line of arguments and breaks it into its
567  *      component words and passes those words and the number of them to the
568  *      MainParseArgs function.
569  *      The line should have all its leading whitespace removed.
570  *
571  * Side Effects:
572  *      Only those that come from the various arguments.
573  */
574 void
575 Main_ParseArgLine(char *line, int mflags)
576 {
577         ArgArray        aa;
578
579         if (line == NULL)
580                 return;
581         for (; *line == ' '; ++line)
582                 continue;
583         if (!*line)
584                 return;
585
586         if (mflags) {
587                 MAKEFLAGS_break(&aa, line);
588         } else {
589                 brk_string(&aa, line, TRUE);
590         }
591         MainParseArgs(aa.argc, aa.argv);
592         ArgArray_Done(&aa);
593 }
594
595 /**
596  * Try to change the current working directory into path.
597  */
598 static char *
599 chdir_verify_path(const char path[], char newpath[])
600 {
601         struct stat sb;
602
603         /*
604          * Check if the path is a directory.  If not fail without reporting
605          * an error.
606          */
607         if (stat(path, &sb) < 0) {
608                 return (NULL);  /* fail but no report */
609         }
610         if (S_ISDIR(sb.st_mode) == 0) {
611                 return (NULL);
612         }
613
614         /*
615          * The path refers to a directory, so we try to change into it. If we
616          * fail, or we fail to obtain the path from root to the directory,
617          * then report an error and fail.
618          */
619         if (chdir(path) < 0) {
620                 warn("warning: %s", path);
621                 return (NULL);
622         }
623         if (getcwd(newpath, MAXPATHLEN) == NULL) {
624                 warn("warning: %s", path);
625                 return (NULL);
626         }
627         return (newpath);
628 }
629
630 /**
631  * In lieu of a good way to prevent every possible looping in make(1), stop
632  * there from being more than MKLVL_MAXVAL processes forked by make(1), to
633  * prevent a forkbomb from happening, in a dumb and mechanical way.
634  *
635  * Side Effects:
636  *      Creates or modifies enviornment variable MKLVL_ENVVAR via setenv().
637  */
638 static void
639 check_make_level(void)
640 {
641 #ifdef WANT_ENV_MKLVL
642         char    *value = getenv(MKLVL_ENVVAR);
643         int     level = (value == NULL) ? 0 : atoi(value);
644
645         if (level < 0) {
646                 errc(2, EAGAIN, "Invalid value for recursion level (%d).",
647                     level);
648         } else if (level > MKLVL_MAXVAL) {
649                 errc(2, EAGAIN, "Max recursion level (%d) exceeded.",
650                     MKLVL_MAXVAL);
651         } else {
652                 char new_value[32];
653                 sprintf(new_value, "%d", level + 1);
654                 setenv(MKLVL_ENVVAR, new_value, 1);
655         }
656 #endif /* WANT_ENV_MKLVL */
657 }
658
659 /**
660  * main
661  *      The main function, for obvious reasons. Initializes variables
662  *      and a few modules, then parses the arguments give it in the
663  *      environment and on the command line. Reads the system makefile
664  *      followed by either Makefile, makefile or the file given by the
665  *      -f argument. Sets the .MAKEFLAGS PMake variable based on all the
666  *      flags it has received by then uses either the Make or the Compat
667  *      module to create the initial list of targets.
668  *
669  * Results:
670  *      If -q was given, exits -1 if anything was out-of-date. Else it exits
671  *      0.
672  *
673  * Side Effects:
674  *      The program exits when done. Targets are created. etc. etc. etc.
675  */
676 int
677 main(int argc, char **argv)
678 {
679         const char *machine;
680         const char *machine_arch;
681         const char *machine_cpu;
682         Boolean outOfDate = TRUE;       /* FALSE if all targets up to date */
683         const char *pathp;
684         const char *path;
685         char mdpath[MAXPATHLEN];
686         char obpath[MAXPATHLEN];
687         char cdpath[MAXPATHLEN];
688         char *cp = NULL, *start;
689
690         /*
691          * Initialize file global variables.
692          */
693         expandVars = TRUE;
694         noBuiltins = FALSE;             /* Read the built-in rules */
695         forceJobs = FALSE;              /* No -j flag */
696         curdir = cdpath;
697
698         /*
699          * Initialize program global variables.
700          */
701         beSilent = FALSE;               /* Print commands as executed */
702         ignoreErrors = FALSE;           /* Pay attention to non-zero returns */
703         noExecute = FALSE;              /* Execute all commands */
704         keepgoing = FALSE;              /* Stop on error */
705         allPrecious = FALSE;            /* Remove targets when interrupted */
706         queryFlag = FALSE;              /* This is not just a check-run */
707         touchFlag = FALSE;              /* Actually update targets */
708         usePipes = TRUE;                /* Catch child output in pipes */
709         debug = 0;                      /* No debug verbosity, please. */
710         jobsRunning = FALSE;
711
712         jobLimit = DEFMAXJOBS;
713         compatMake = FALSE;             /* No compat mode */
714
715         check_make_level();
716
717 #ifdef RLIMIT_NOFILE
718         /*
719          * get rid of resource limit on file descriptors
720          */
721         {
722                 struct rlimit rl;
723                 if (getrlimit(RLIMIT_NOFILE, &rl) == -1) {
724                         err(2, "getrlimit");
725                 }
726                 rl.rlim_cur = rl.rlim_max;
727                 if (setrlimit(RLIMIT_NOFILE, &rl) == -1) {
728                         err(2, "setrlimit");
729                 }
730         }
731 #endif
732         /*
733          * Get the name of this type of MACHINE from utsname
734          * so we can share an executable for similar machines.
735          * (i.e. m68k: amiga hp300, mac68k, sun3, ...)
736          *
737          * Note that while MACHINE is decided at run-time,
738          * MACHINE_ARCH is always known at compile time.
739          */
740         if ((machine = getenv("MACHINE")) == NULL) {
741 #ifdef MACHINE
742                 machine = MACHINE;
743 #else
744                 static struct utsname utsname;
745
746                 if (uname(&utsname) == -1)
747                         err(2, "uname");
748                 machine = utsname.machine;
749 #endif
750         }
751
752         if ((machine_arch = getenv("MACHINE_ARCH")) == NULL) {
753 #ifdef MACHINE_ARCH
754                 machine_arch = MACHINE_ARCH;
755 #else
756                 machine_arch = "unknown";
757 #endif
758         }
759
760         /*
761          * Set machine_cpu to the minumum supported CPU revision based
762          * on the target architecture, if not already set.
763          */
764         if ((machine_cpu = getenv("MACHINE_CPU")) == NULL) {
765                 if (!strcmp(machine_arch, "i386"))
766                         machine_cpu = "i386";
767                 else if (!strcmp(machine_arch, "alpha"))
768                         machine_cpu = "ev4";
769                 else
770                         machine_cpu = "unknown";
771         }
772
773         /*
774          * Initialize the parsing, directory and variable modules to prepare
775          * for the reading of inclusion paths and variable settings on the
776          * command line
777          */
778         Proc_Init();
779
780         Dir_Init();             /* Initialize directory structures so -I flags
781                                  * can be processed correctly */
782         Var_Init(environ);      /* As well as the lists of variables for
783                                  * parsing arguments */
784
785         /*
786          * Initialize various variables.
787          *      MAKE also gets this name, for compatibility
788          *      .MAKEFLAGS gets set to the empty string just in case.
789          *      MFLAGS also gets initialized empty, for compatibility.
790          */
791         Var_SetGlobal("MAKE", argv[0]);
792         Var_SetGlobal(".MAKEFLAGS", "");
793         Var_SetGlobal("MFLAGS", "");
794         Var_SetGlobal("MACHINE", machine);
795         Var_SetGlobal("MACHINE_ARCH", machine_arch);
796         Var_SetGlobal("MACHINE_CPU", machine_cpu);
797 #ifdef MAKE_VERSION
798         Var_SetGlobal("MAKE_VERSION", MAKE_VERSION);
799 #endif
800
801         /*
802          * First snag things out of the MAKEFLAGS environment
803          * variable.  Then parse the command line arguments.
804          */
805         Main_ParseArgLine(getenv("MAKEFLAGS"), 1);
806
807         MainParseArgs(argc, argv);
808
809         /*
810          * Find where we are...
811          */
812         if (getcwd(curdir, MAXPATHLEN) == NULL)
813                 err(2, NULL);
814
815         {
816         struct stat sa;
817
818         if (stat(curdir, &sa) == -1)
819             err(2, "%s", curdir);
820         }
821
822         /*
823          * The object directory location is determined using the
824          * following order of preference:
825          *
826          *      1. MAKEOBJDIRPREFIX`cwd`
827          *      2. MAKEOBJDIR
828          *      3. PATH_OBJDIR.${MACHINE}
829          *      4. PATH_OBJDIR
830          *      5. PATH_OBJDIRPREFIX`cwd`
831          *
832          * If one of the first two fails, use the current directory.
833          * If the remaining three all fail, use the current directory.
834          *
835          * Once things are initted,
836          * have to add the original directory to the search path,
837          * and modify the paths for the Makefiles apropriately.  The
838          * current directory is also placed as a variable for make scripts.
839          */
840         if (!(pathp = getenv("MAKEOBJDIRPREFIX"))) {
841                 if (!(path = getenv("MAKEOBJDIR"))) {
842                         path = PATH_OBJDIR;
843                         pathp = PATH_OBJDIRPREFIX;
844                         snprintf(mdpath, MAXPATHLEN, "%s.%s", path, machine);
845                         if (!(objdir = chdir_verify_path(mdpath, obpath)))
846                                 if (!(objdir=chdir_verify_path(path, obpath))) {
847                                         snprintf(mdpath, MAXPATHLEN,
848                                                         "%s%s", pathp, curdir);
849                                         if (!(objdir=chdir_verify_path(mdpath,
850                                                                        obpath)))
851                                                 objdir = curdir;
852                                 }
853                 }
854                 else if (!(objdir = chdir_verify_path(path, obpath)))
855                         objdir = curdir;
856         }
857         else {
858                 snprintf(mdpath, MAXPATHLEN, "%s%s", pathp, curdir);
859                 if (!(objdir = chdir_verify_path(mdpath, obpath)))
860                         objdir = curdir;
861         }
862         Dir_InitDot();          /* Initialize the "." directory */
863         if (objdir != curdir)
864                 Path_AddDir(&dirSearchPath, curdir);
865         Var_SetGlobal(".DIRECTIVE_MAKEENV", "YES");
866         Var_SetGlobal(".ST_EXPORTVAR", "YES");
867         Var_SetGlobal(".CURDIR", curdir);
868         Var_SetGlobal(".OBJDIR", objdir);
869
870         if (getenv("MAKE_JOBS_FIFO") != NULL)
871                 forceJobs = TRUE;
872         /*
873          * Be compatible if user did not specify -j and did not explicitly
874          * turned compatibility on
875          */
876         if (!compatMake && !forceJobs)
877                 compatMake = TRUE;
878
879         /*
880          * Initialize target and suffix modules in preparation for
881          * parsing the makefile(s)
882          */
883         Targ_Init();
884         Suff_Init();
885
886         DEFAULT = NULL;
887         time(&now);
888
889         /*
890          * Set up the .TARGETS variable to contain the list of targets to be
891          * created. If none specified, make the variable empty -- the parser
892          * will fill the thing in with the default or .MAIN target.
893          */
894         if (Lst_IsEmpty(&create)) {
895                 Var_SetGlobal(".TARGETS", "");
896         } else {
897                 LstNode *ln;
898
899                 for (ln = Lst_First(&create); ln != NULL; ln = Lst_Succ(ln)) {
900                         char *name = Lst_Datum(ln);
901
902                         Var_Append(".TARGETS", name, VAR_GLOBAL);
903                 }
904         }
905
906
907         /*
908          * If no user-supplied system path was given (through the -m option)
909          * add the directories from the DEFSYSPATH (more than one may be given
910          * as dir1:...:dirn) to the system include path.
911          */
912         if (TAILQ_EMPTY(&sysIncPath)) {
913                 char syspath[] = PATH_DEFSYSPATH;
914
915                 for (start = syspath; *start != '\0'; start = cp) {
916                         for (cp = start; *cp != '\0' && *cp != ':'; cp++)
917                                 continue;
918                         if (*cp == '\0') {
919                                 Path_AddDir(&sysIncPath, start);
920                         } else {
921                                 *cp++ = '\0';
922                                 Path_AddDir(&sysIncPath, start);
923                         }
924                 }
925         }
926
927         /*
928          * Read in the built-in rules first, followed by the specified
929          * makefile, if it was (makefile != (char *) NULL), or the default
930          * Makefile and makefile, in that order, if it wasn't.
931          */
932         if (!noBuiltins) {
933                 /* Path of sys.mk */
934                 Lst sysMkPath = Lst_Initializer(sysMkPath);
935                 LstNode *ln;
936                 char    defsysmk[] = PATH_DEFSYSMK;
937
938                 Path_Expand(defsysmk, &sysIncPath, &sysMkPath);
939                 if (Lst_IsEmpty(&sysMkPath))
940                         Fatal("make: no system rules (%s).", PATH_DEFSYSMK);
941                 LST_FOREACH(ln, &sysMkPath) {
942                         if (!ReadMakefile(Lst_Datum(ln)))
943                                 break;
944                 }
945                 if (ln != NULL)
946                         Fatal("make: cannot open %s.", (char *)Lst_Datum(ln));
947                 Lst_Destroy(&sysMkPath, free);
948         }
949
950         if (!Lst_IsEmpty(&makefiles)) {
951                 LstNode *ln;
952
953                 LST_FOREACH(ln, &makefiles) {
954                         if (!ReadMakefile(Lst_Datum(ln)))
955                                 break;
956                 }
957                 if (ln != NULL)
958                         Fatal("make: cannot open %s.", (char *)Lst_Datum(ln));
959         } else if (!ReadMakefile("BSDmakefile"))
960             if (!ReadMakefile("makefile"))
961                 ReadMakefile("Makefile");
962
963         ReadMakefile(".depend");
964
965         /* Install all the flags into the MAKE envariable. */
966         {
967                 const char *p;
968
969                 if (((p = Var_Value(".MAKEFLAGS", VAR_GLOBAL)) != NULL) && *p)
970                         setenv("MAKEFLAGS", p, 1);
971         }
972
973         /*
974          * For compatibility, look at the directories in the VPATH variable
975          * and add them to the search path, if the variable is defined. The
976          * variable's value is in the same format as the PATH envariable, i.e.
977          * <directory>:<directory>:<directory>...
978          */
979         if (Var_Exists("VPATH", VAR_CMD)) {
980                 /*
981                  * GCC stores string constants in read-only memory, but
982                  * Var_Subst will want to write this thing, so store it
983                  * in an array
984                  */
985                 static char VPATH[] = "${VPATH}";
986                 Buffer  *buf;
987                 char    *vpath;
988                 char    *ptr;
989                 char    savec;
990
991                 buf = Var_Subst(VPATH, VAR_CMD, FALSE);
992
993                 vpath = Buf_Data(buf);
994                 do {
995                         /* skip to end of directory */
996                         for (ptr = vpath; *ptr != ':' && *ptr != '\0'; ptr++)
997                                 ;
998
999                         /* Save terminator character so know when to stop */
1000                         savec = *ptr;
1001                         *ptr = '\0';
1002
1003                         /* Add directory to search path */
1004                         Path_AddDir(&dirSearchPath, vpath);
1005
1006                         vpath = ptr + 1;
1007                 } while (savec != '\0');
1008
1009                 Buf_Destroy(buf, TRUE);
1010         }
1011
1012         /*
1013          * Now that all search paths have been read for suffixes et al, it's
1014          * time to add the default search path to their lists...
1015          */
1016         Suff_DoPaths();
1017
1018         /* print the initial graph, if the user requested it */
1019         if (DEBUG(GRAPH1))
1020                 Targ_PrintGraph(1);
1021
1022         /* print the values of any variables requested by the user */
1023         if (Lst_IsEmpty(&variables)) {
1024                 /*
1025                  * Since the user has not requested that any variables
1026                  * be printed, we can build targets.
1027                  *
1028                  * Have read the entire graph and need to make a list of targets
1029                  * to create. If none was given on the command line, we consult
1030                  * the parsing module to find the main target(s) to create.
1031                  */
1032                 Lst targs = Lst_Initializer(targs);
1033
1034                 if (Lst_IsEmpty(&create))
1035                         Parse_MainName(&targs);
1036                 else
1037                         Targ_FindList(&targs, &create, TARG_CREATE);
1038
1039                 if (compatMake) {
1040                         /*
1041                          * Compat_Init will take care of creating
1042                          * all the targets as well as initializing
1043                          * the module.
1044                          */
1045                         Compat_Run(&targs);
1046                         outOfDate = 0;
1047                 } else {
1048                         /*
1049                          * Initialize job module before traversing
1050                          * the graph, now that any .BEGIN and .END
1051                          * targets have been read.  This is done
1052                          * only if the -q flag wasn't given (to
1053                          * prevent the .BEGIN from being executed
1054                          * should it exist).
1055                          */
1056                         if (!queryFlag) {
1057                                 Job_Init(jobLimit);
1058                                 jobsRunning = TRUE;
1059                         }
1060
1061                         /* Traverse the graph, checking on all the targets */
1062                         outOfDate = Make_Run(&targs);
1063                 }
1064                 Lst_Destroy(&targs, NOFREE);
1065
1066         } else {
1067                 Var_Print(&variables, expandVars);
1068         }
1069
1070         Lst_Destroy(&variables, free);
1071         Lst_Destroy(&makefiles, free);
1072         Lst_Destroy(&create, free);
1073
1074         /* print the graph now it's been processed if the user requested it */
1075         if (DEBUG(GRAPH2))
1076                 Targ_PrintGraph(2);
1077
1078         if (queryFlag && outOfDate)
1079                 return (1);
1080         else
1081                 return (0);
1082 }
1083