]> CyberLeo.Net >> Repos - FreeBSD/releng/9.2.git/blob - usr.bin/make/shell.c
- Copy stable/9 to releng/9.2 as part of the 9.2-RELEASE cycle.
[FreeBSD/releng/9.2.git] / usr.bin / make / shell.c
1 /*-
2  * Copyright (c) 1988, 1989, 1990, 1993
3  *      The Regents of the University of California.  All rights reserved.
4  * Copyright (c) 1988, 1989 by Adam de Boor
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
40 #include <sys/cdefs.h>
41 __FBSDID("$FreeBSD$");
42
43 #include <sys/queue.h>
44 #include <stdio.h>
45 #include <stdlib.h>
46 #include <string.h>
47
48 #include "parse.h"
49 #include "pathnames.h"
50 #include "shell.h"
51 #include "util.h"
52
53 /*
54  * Descriptions for various shells. What the list of builtins should contain
55  * is debatable: either all builtins or only those which may specified on
56  * a single line without use of meta-characters. For correct makefiles that
57  * contain only correct command lines there is no difference. But if a command
58  * line, for example, is: 'if -foo bar' and there is an executable named 'if'
59  * in the path, the first possibility would execute that 'if' while in the
60  * second case the shell would give an error. Histerically only a small
61  * subset of the builtins and no reserved words where given in the list which
62  * corresponds roughly to the first variant. So go with this but add missing
63  * words.
64  */
65 #define CSH_BUILTINS                                            \
66         "alias cd eval exec exit read set ulimit unalias "      \
67         "umask unset wait"
68
69 #define SH_BUILTINS                                             \
70         "alias cd eval exec exit read set ulimit unalias "      \
71         "umask unset wait"
72
73 #define CSH_META        "#=|^(){};&<>*?[]:$`\\@\n"
74 #define SH_META         "#=|^(){};&<>*?[]:$`\\\n"
75
76 static const char *const shells_init[] = {
77         /*
78          * CSH description. The csh can do echo control by playing
79          * with the setting of the 'echo' shell variable. Sadly,
80          * however, it is unable to do error control nicely.
81          */
82         "name=csh path='" PATH_DEFSHELLDIR "/csh' "
83         "quiet='unset verbose' echo='set verbose' filter='unset verbose' "
84         "hasErrCtl=N check='echo \"%s\"\n' ignore='csh -c \"%s || exit 0\"' "
85         "echoFlag=v errFlag=e "
86         "meta='" CSH_META "' builtins='" CSH_BUILTINS "'",
87
88         /*
89          * SH description. Echo control is also possible and, under
90          * sun UNIX anyway, one can even control error checking.
91          */
92         "name=sh path='" PATH_DEFSHELLDIR "/sh' "
93         "quiet='set -' echo='set -v' filter='set -' "
94         "hasErrCtl=Y check='set -e' ignore='set +e' "
95         "echoFlag=v errFlag=e "
96         "meta='" SH_META "' builtins='" SH_BUILTINS "'",
97
98         /*
99          * KSH description. The Korn shell has a superset of
100          * the Bourne shell's functionality. There are probably builtins
101          * missing here.
102          */
103         "name=ksh path='" PATH_DEFSHELLDIR "/ksh' "
104         "quiet='set -' echo='set -v' filter='set -' "
105         "hasErrCtl=Y check='set -e' ignore='set +e' "
106         "echoFlag=v errFlag=e "
107         "meta='" SH_META "' builtins='" SH_BUILTINS "' unsetenv=T",
108
109         NULL
110 };
111
112 /*
113  * This is the shell to which we pass all commands in the Makefile.
114  * It is set by the Job_ParseShell function.
115  */
116 struct Shell *commandShell;
117
118 /*
119  * This is the list of all known shells.
120  */
121 static struct Shells shells = TAILQ_HEAD_INITIALIZER(shells);
122
123 void ShellDump(const struct Shell *) __unused;
124
125 /**
126  * Helper function for sorting the builtin list alphabetically.
127  */
128 static int
129 sort_builtins(const void *p1, const void *p2)
130 {
131
132         return (strcmp(*(const char* const*)p1, *(const char* const*)p2));
133 }
134
135 /**
136  * Free a shell structure and all associated strings.
137  */
138 static void
139 ShellFree(struct Shell *sh)
140 {
141
142         if (sh != NULL) {
143                 free(sh->name);
144                 free(sh->path);
145                 free(sh->echoOff);
146                 free(sh->echoOn);
147                 free(sh->noPrint);
148                 free(sh->errCheck);
149                 free(sh->ignErr);
150                 free(sh->echo);
151                 free(sh->exit);
152                 ArgArray_Done(&sh->builtins);
153                 free(sh->meta);
154                 free(sh);
155         }
156 }
157
158 /**
159  * Dump a shell specification to stderr.
160  */
161 void
162 ShellDump(const struct Shell *sh)
163 {
164         int i;
165
166         fprintf(stderr, "Shell %p:\n", sh);
167         fprintf(stderr, "  name='%s' path='%s'\n", sh->name, sh->path);
168         fprintf(stderr, "  hasEchoCtl=%d echoOff='%s' echoOn='%s'\n",
169             sh->hasEchoCtl, sh->echoOff, sh->echoOn);
170         fprintf(stderr, "  noPrint='%s'\n", sh->noPrint);
171         fprintf(stderr, "  hasErrCtl=%d errCheck='%s' ignErr='%s'\n",
172             sh->hasErrCtl, sh->errCheck, sh->ignErr);
173         fprintf(stderr, "  echo='%s' exit='%s'\n", sh->echo, sh->exit);
174         fprintf(stderr, "  builtins=%d\n", sh->builtins.argc - 1);
175         for (i = 1; i < sh->builtins.argc; i++)
176                 fprintf(stderr, " '%s'", sh->builtins.argv[i]);
177         fprintf(stderr, "\n  meta='%s'\n", sh->meta);
178         fprintf(stderr, "  unsetenv=%d\n", sh->unsetenv);
179 }
180
181 /**
182  * Parse a shell specification line and return the new Shell structure.
183  * In case of an error a message is printed and NULL is returned.
184  */
185 static struct Shell *
186 ShellParseSpec(const char *spec, Boolean *fullSpec)
187 {
188         ArgArray        aa;
189         struct Shell    *sh;
190         char            *eq;
191         char            *keyw;
192         int             arg;
193
194         *fullSpec = FALSE;
195
196         sh = emalloc(sizeof(*sh));
197         memset(sh, 0, sizeof(*sh));
198         ArgArray_Init(&sh->builtins);
199
200         /*
201          * Parse the specification by keyword but skip the first word
202          */
203         brk_string(&aa, spec, TRUE);
204
205         for (arg = 1; arg < aa.argc; arg++) {
206                 /*
207                  * Split keyword and value
208                  */
209                 keyw = aa.argv[arg];
210                 if ((eq = strchr(keyw, '=')) == NULL) {
211                         Parse_Error(PARSE_FATAL, "missing '=' in shell "
212                             "specification keyword '%s'", keyw);
213                         ArgArray_Done(&aa);
214                         ShellFree(sh);
215                         return (NULL);
216                 }
217                 *eq++ = '\0';
218
219                 if (strcmp(keyw, "path") == 0) {
220                         free(sh->path);
221                         sh->path = estrdup(eq);
222                 } else if (strcmp(keyw, "name") == 0) {
223                         free(sh->name);
224                         sh->name = estrdup(eq);
225                 } else if (strcmp(keyw, "quiet") == 0) {
226                         free(sh->echoOff);
227                         sh->echoOff = estrdup(eq);
228                         *fullSpec = TRUE;
229                 } else if (strcmp(keyw, "echo") == 0) {
230                         free(sh->echoOn);
231                         sh->echoOn = estrdup(eq);
232                         *fullSpec = TRUE;
233                 } else if (strcmp(keyw, "filter") == 0) {
234                         free(sh->noPrint);
235                         sh->noPrint = estrdup(eq);
236                         *fullSpec = TRUE;
237                 } else if (strcmp(keyw, "echoFlag") == 0) {
238                         free(sh->echo);
239                         sh->echo = estrdup(eq);
240                         *fullSpec = TRUE;
241                 } else if (strcmp(keyw, "errFlag") == 0) {
242                         free(sh->exit);
243                         sh->exit = estrdup(eq);
244                         *fullSpec = TRUE;
245                 } else if (strcmp(keyw, "hasErrCtl") == 0) {
246                         sh->hasErrCtl = (*eq == 'Y' || *eq == 'y' ||
247                             *eq == 'T' || *eq == 't');
248                         *fullSpec = TRUE;
249                 } else if (strcmp(keyw, "check") == 0) {
250                         free(sh->errCheck);
251                         sh->errCheck = estrdup(eq);
252                         *fullSpec = TRUE;
253                 } else if (strcmp(keyw, "ignore") == 0) {
254                         free(sh->ignErr);
255                         sh->ignErr = estrdup(eq);
256                         *fullSpec = TRUE;
257                 } else if (strcmp(keyw, "builtins") == 0) {
258                         ArgArray_Done(&sh->builtins);
259                         brk_string(&sh->builtins, eq, TRUE);
260                         qsort(sh->builtins.argv + 1, sh->builtins.argc - 1,
261                             sizeof(char *), sort_builtins);
262                         *fullSpec = TRUE;
263                 } else if (strcmp(keyw, "meta") == 0) {
264                         free(sh->meta);
265                         sh->meta = estrdup(eq);
266                         *fullSpec = TRUE;
267                 } else if (strcmp(keyw, "unsetenv") == 0) {
268                         sh->unsetenv = (*eq == 'Y' || *eq == 'y' ||
269                             *eq == 'T' || *eq == 't');
270                         *fullSpec = TRUE;
271                 } else {
272                         Parse_Error(PARSE_FATAL, "unknown keyword in shell "
273                             "specification '%s'", keyw);
274                         ArgArray_Done(&aa);
275                         ShellFree(sh);
276                         return (NULL);
277                 }
278         }
279         ArgArray_Done(&aa);
280
281         /*
282          * Some checks (could be more)
283          */
284         if (*fullSpec) {
285                 if ((sh->echoOn != NULL) ^ (sh->echoOff != NULL)) {
286                         Parse_Error(PARSE_FATAL, "Shell must have either both "
287                             "echoOff and echoOn or none of them");
288                         ShellFree(sh);
289                         return (NULL);
290                 }
291
292                 if (sh->echoOn != NULL && sh->echoOff != NULL)
293                         sh->hasEchoCtl = TRUE;
294         }
295
296         return (sh);
297 }
298
299 /**
300  * Parse the builtin shell specifications and put them into the shell
301  * list. Then select the default shell to be the current shell. This
302  * is called from main() before any parsing (including MAKEFLAGS and
303  * command line) is done.
304  */
305 void
306 Shell_Init(void)
307 {
308         int i;
309         struct Shell *sh;
310         Boolean fullSpec;
311
312         for (i = 0; shells_init[i] != NULL; i++) {
313                 sh = ShellParseSpec(shells_init[i], &fullSpec);
314                 TAILQ_INSERT_TAIL(&shells, sh, link);
315                 if (strcmp(sh->name, DEFSHELLNAME) == 0)
316                         commandShell = sh;
317         }
318 }
319
320 /**
321  * Find a matching shell in 'shells' given its final component.
322  *
323  * Results:
324  *      A pointer to a freshly allocated Shell structure with the contents
325  *      from static description or NULL if no shell with the given name
326  *      is found.
327  */
328 static struct Shell *
329 ShellMatch(const char *name)
330 {
331         struct Shell    *sh;
332
333         TAILQ_FOREACH(sh, &shells, link)
334                 if (strcmp(sh->name, name) == 0)
335                         return (sh);
336
337         return (NULL);
338 }
339
340 /**
341  * Parse a shell specification and set up commandShell appropriately.
342  *
343  * Results:
344  *      TRUE if the specification was correct. FALSE otherwise.
345  *
346  * Side Effects:
347  *      commandShell points to a Shell structure.
348  *      created from the shell spec).
349  *
350  * Notes:
351  *      A shell specification consists of a .SHELL target, with dependency
352  *      operator, followed by a series of blank-separated words. Double
353  *      quotes can be used to use blanks in words. A backslash escapes
354  *      anything (most notably a double-quote and a space) and
355  *      provides the functionality it does in C. Each word consists of
356  *      keyword and value separated by an equal sign. There should be no
357  *      unnecessary spaces in the word. The keywords are as follows:
358  *          name            Name of shell.
359  *          path            Location of shell. Overrides "name" if given
360  *          quiet           Command to turn off echoing.
361  *          echo            Command to turn echoing on
362  *          filter          Result of turning off echoing that shouldn't be
363  *                          printed.
364  *          echoFlag        Flag to turn echoing on at the start
365  *          errFlag         Flag to turn error checking on at the start
366  *          hasErrCtl       True if shell has error checking control
367  *          check           Command to turn on error checking if hasErrCtl
368  *                          is TRUE or template of command to echo a command
369  *                          for which error checking is off if hasErrCtl is
370  *                          FALSE.
371  *          ignore          Command to turn off error checking if hasErrCtl
372  *                          is TRUE or template of command to execute a
373  *                          command so as to ignore any errors it returns if
374  *                          hasErrCtl is FALSE.
375  *          builtins        A space separated list of builtins. If one
376  *                          of these builtins is detected when make wants
377  *                          to execute a command line, the command line is
378  *                          handed to the shell. Otherwise make may try to
379  *                          execute the command directly. If this list is empty
380  *                          it is assumed, that the command must always be
381  *                          handed over to the shell.
382  *          meta            The shell meta characters. If this is not specified
383  *                          or empty, commands are alway passed to the shell.
384  *                          Otherwise they are not passed when they contain
385  *                          neither a meta character nor a builtin command.
386  *          unsetenv        Unsetenv("ENV") before executing anything.
387  */
388 Boolean
389 Shell_Parse(const char line[])
390 {
391         Boolean         fullSpec;
392         struct Shell    *sh;
393         struct Shell    *match;
394
395         /* parse the specification */
396         if ((sh = ShellParseSpec(line, &fullSpec)) == NULL)
397                 return (FALSE);
398
399         if (sh->path == NULL) {
400                 /*
401                  * If no path was given, the user wants one of the pre-defined
402                  * shells, yes? So we find the one s/he wants with the help of
403                  * JobMatchShell and set things up the right way.
404                  */
405                 if (sh->name == NULL) {
406                         Parse_Error(PARSE_FATAL,
407                             "Neither path nor name specified");
408                         ShellFree(sh);
409                         return (FALSE);
410                 }
411                 if (fullSpec) {
412                         /*
413                          * XXX May want to merge sh into match. But this
414                          * require ShellParseSpec to return information
415                          * which attributes actuall have been specified.
416                          */
417                         Parse_Error(PARSE_FATAL, "No path specified");
418                         ShellFree(sh);
419                         return (FALSE);
420                 }
421                 if ((match = ShellMatch(sh->name)) == NULL) {
422                         Parse_Error(PARSE_FATAL, "%s: no matching shell",
423                             sh->name);
424                         ShellFree(sh);
425                         return (FALSE);
426                 }
427                 ShellFree(sh);
428                 commandShell = match;
429
430                 return (TRUE);
431         }
432
433         /*
434          * The user provided a path. If s/he gave nothing else
435          * (fullSpec is FALSE), try and find a matching shell in the
436          * ones we know of. Else we just take the specification at its
437          * word and copy it to a new location. In either case, we need
438          * to record the path the user gave for the shell.
439          */
440         if (sh->name == NULL) {
441                 /* get the base name as the name */
442                 if ((sh->name = strrchr(sh->path, '/')) == NULL) {
443                         sh->name = estrdup(sh->path);
444                 } else {
445                         sh->name = estrdup(sh->name + 1);
446                 }
447         }
448
449         if (!fullSpec) {
450                 if ((match = ShellMatch(sh->name)) == NULL) {
451                         Parse_Error(PARSE_FATAL,
452                             "%s: no matching shell", sh->name);
453                         ShellFree(sh);
454                         return (FALSE);
455                 }
456
457                 /* set the patch on the matching shell */
458                 free(match->path);
459                 match->path = sh->path;
460                 sh->path = NULL;
461
462                 ShellFree(sh);
463                 commandShell = match;
464                 return (TRUE);
465         }
466
467         TAILQ_INSERT_HEAD(&shells, sh, link);
468
469         /* set the new shell */
470         commandShell = sh;
471         return (TRUE);
472 }