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
8 * This code is derived from software contributed to Berkeley by
11 * Redistribution and use in source and binary forms, with or without
12 * modification, are permitted provided that the following conditions
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.
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
39 * $DragonFly: src/usr.bin/make/shell.c,v 1.25 2005/09/22 09:13:38 okumoto Exp $
47 #include "pathnames.h"
53 * Helper function for sorting the builtin list alphabetically.
56 sort_builtins(const void *p1
, const void *p2
)
58 return (strcmp(*(const char* const*)p1
, *(const char* const*)p2
));
62 * Free a shell structure and all associated strings.
65 Shell_Destroy(Shell
*sh
)
77 ArgArray_Done(&sh
->builtins
);
84 * Dump a shell specification to stderr.
87 Shell_Dump(const Shell
*sh
)
91 fprintf(stderr
, "Shell %p:\n", sh
);
92 fprintf(stderr
, " name='%s' path='%s'\n", sh
->name
, sh
->path
);
93 fprintf(stderr
, " hasEchoCtl=%d echoOff='%s' echoOn='%s'\n",
94 sh
->hasEchoCtl
, sh
->echoOff
, sh
->echoOn
);
95 fprintf(stderr
, " noPrint='%s'\n", sh
->noPrint
);
96 fprintf(stderr
, " hasErrCtl=%d errCheck='%s' ignErr='%s'\n",
97 sh
->hasErrCtl
, sh
->errCheck
, sh
->ignErr
);
98 fprintf(stderr
, " echo='%s' exit='%s'\n", sh
->echo
, sh
->exit
);
99 fprintf(stderr
, " builtins=%d\n", sh
->builtins
.argc
- 1);
100 for (i
= 1; i
< sh
->builtins
.argc
; i
++)
101 fprintf(stderr
, " '%s'", sh
->builtins
.argv
[i
]);
102 fprintf(stderr
, "\n meta='%s'\n", sh
->meta
);
103 fprintf(stderr
, " unsetenv=%d\n", sh
->unsetenv
);
107 * Parse a shell specification line and return the new Shell structure.
108 * In case of an error a message is printed and NULL is returned.
111 * A shell specification consists of a .SHELL target, with dependency
112 * operator, followed by a series of blank-separated words. Double
113 * quotes can be used to use blanks in words. A backslash escapes
114 * anything (most notably a double-quote and a space) and
115 * provides the functionality it does in C. Each word consists of
116 * keyword and value separated by an equal sign. There should be no
117 * unnecessary spaces in the word. The keywords are as follows:
118 * name Name of shell.
119 * path Location of shell. Overrides "name" if given
120 * quiet Command to turn off echoing.
121 * echo Command to turn echoing on
122 * filter Result of turning off echoing that shouldn't be
124 * echoFlag Flag to turn echoing on at the start
125 * errFlag Flag to turn error checking on at the start
126 * hasErrCtl True if shell has error checking control
127 * check Command to turn on error checking if hasErrCtl
128 * is true or template of command to echo a command
129 * for which error checking is off if hasErrCtl is
131 * ignore Command to turn off error checking if hasErrCtl
132 * is true or template of command to execute a
133 * command so as to ignore any errors it returns if
134 * hasErrCtl is false.
135 * builtins A space separated list of builtins. If one
136 * of these builtins is detected when make wants
137 * to execute a command line, the command line is
138 * handed to the shell. Otherwise make may try to
139 * execute the command directly. If this list is empty
140 * it is assumed, that the command must always be
141 * handed over to the shell.
142 * meta The shell meta characters. If this is not specified
143 * or empty, commands are alway passed to the shell.
144 * Otherwise they are not passed when they contain
145 * neither a meta character nor a builtin command.
148 ShellParseSpec(const char spec
[], bool *fullSpec
)
158 sh
= emalloc(sizeof(*sh
));
159 memset(sh
, 0, sizeof(*sh
));
160 ArgArray_Init(&sh
->builtins
);
163 * Parse the specification by keyword but skip the first word
165 brk_string(&aa
, spec
, true);
167 for (arg
= 1; arg
< aa
.argc
; arg
++) {
169 * Split keyword and value
172 if ((eq
= strchr(keyw
, '=')) == NULL
) {
173 Parse_Error(PARSE_FATAL
, "missing '=' in shell "
174 "specification keyword '%s'", keyw
);
181 if (strcmp(keyw
, "path") == 0) {
183 sh
->path
= estrdup(eq
);
184 } else if (strcmp(keyw
, "name") == 0) {
186 sh
->name
= estrdup(eq
);
187 } else if (strcmp(keyw
, "quiet") == 0) {
189 sh
->echoOff
= estrdup(eq
);
191 } else if (strcmp(keyw
, "echo") == 0) {
193 sh
->echoOn
= estrdup(eq
);
195 } else if (strcmp(keyw
, "filter") == 0) {
197 sh
->noPrint
= estrdup(eq
);
199 } else if (strcmp(keyw
, "echoFlag") == 0) {
201 sh
->echo
= estrdup(eq
);
203 } else if (strcmp(keyw
, "errFlag") == 0) {
205 sh
->exit
= estrdup(eq
);
207 } else if (strcmp(keyw
, "hasErrCtl") == 0) {
209 *eq
== 'Y' || *eq
== 'y' ||
210 *eq
== 'T' || *eq
== 't');
212 } else if (strcmp(keyw
, "check") == 0) {
214 sh
->errCheck
= estrdup(eq
);
216 } else if (strcmp(keyw
, "ignore") == 0) {
218 sh
->ignErr
= estrdup(eq
);
220 } else if (strcmp(keyw
, "builtins") == 0) {
221 ArgArray_Done(&sh
->builtins
);
222 brk_string(&sh
->builtins
, eq
, true);
223 qsort(sh
->builtins
.argv
+ 1, sh
->builtins
.argc
- 1,
224 sizeof(char *), sort_builtins
);
226 } else if (strcmp(keyw
, "meta") == 0) {
228 sh
->meta
= estrdup(eq
);
230 } else if (strcmp(keyw
, "unsetenv") == 0) {
232 *eq
== 'Y' || *eq
== 'y' ||
233 *eq
== 'T' || *eq
== 't');
236 Parse_Error(PARSE_FATAL
, "unknown keyword in shell "
237 "specification '%s'", keyw
);
246 * Some checks (could be more)
249 if ((sh
->echoOn
!= NULL
) ^ (sh
->echoOff
!= NULL
)) {
250 Parse_Error(PARSE_FATAL
, "Shell must have either both "
251 "echoOff and echoOn or none of them");
256 if (sh
->echoOn
!= NULL
&& sh
->echoOff
!= NULL
)
257 sh
->hasEchoCtl
= true;
264 * Find a matching shell in 'shells' given its final component.
266 * Descriptions for various shells. What the list of builtins should contain
267 * is debatable: either all builtins or only those which may specified on
268 * a single line without use of meta-characters. For correct makefiles that
269 * contain only correct command lines there is no difference. But if a command
270 * line, for example, is: 'if -foo bar' and there is an executable named 'if'
271 * in the path, the first possibility would execute that 'if' while in the
272 * second case the shell would give an error. Histerically only a small
273 * subset of the builtins and no reserved words where given in the list which
274 * corresponds roughly to the first variant. So go with this but add missing
278 * A pointer to a Shell structure, or NULL if no shell with
279 * the given name is found.
282 Shell_Match(const char name
[])
285 const char *shellDir
= PATH_DEFSHELLDIR
;
287 shell
= emalloc(sizeof(Shell
));
289 if (strcmp(name
, "csh") == 0) {
291 * CSH description. The csh can do echo control by playing
292 * with the setting of the 'echo' shell variable. Sadly,
293 * however, it is unable to do error control nicely.
295 shell
->name
= strdup(name
);
296 shell
->path
= str_concat(shellDir
, '/', name
);
297 shell
->hasEchoCtl
= true;
298 shell
->echoOff
= strdup("unset verbose");
299 shell
->echoOn
= strdup("set verbose");
300 shell
->noPrint
= strdup("unset verbose");
301 shell
->hasErrCtl
= false;
302 shell
->errCheck
= strdup("echo \"%s\"\n");
303 shell
->ignErr
= strdup("csh -c \"%s || exit 0\"");
304 shell
->echo
= strdup("v");
305 shell
->exit
= strdup("e");
306 shell
->meta
= strdup("#=|^(){};&<>*?[]:$`\\@\n");
307 brk_string(&shell
->builtins
,
308 "alias cd eval exec exit read set ulimit unalias "
309 "umask unset wait", true);
310 shell
->unsetenv
= false;
312 } else if (strcmp(name
, "sh") == 0) {
314 * SH description. Echo control is also possible and, under
315 * sun UNIX anyway, one can even control error checking.
318 shell
->name
= strdup(name
);
319 shell
->path
= str_concat(shellDir
, '/', name
);
320 shell
->hasEchoCtl
= true;
321 shell
->echoOff
= strdup("set -");
322 shell
->echoOn
= strdup("set -v");
323 shell
->noPrint
= strdup("set -");
324 #ifdef OLDBOURNESHELL
325 shell
->hasErrCtl
= false;
326 shell
->errCheck
= strdup("echo \"%s\"\n");
327 shell
->ignErr
= strdup("sh -c '%s || exit 0'\n");
329 shell
->hasErrCtl
= true;
330 shell
->errCheck
= strdup("set -e");
331 shell
->ignErr
= strdup("set +e");
333 shell
->echo
= strdup("v");
334 shell
->exit
= strdup("e");
335 shell
->meta
= strdup("#=|^(){};&<>*?[]:$`\\\n");
336 brk_string(&shell
->builtins
,
337 "alias cd eval exec exit read set ulimit unalias "
338 "umask unset wait", true);
339 shell
->unsetenv
= false;
341 } else if (strcmp(name
, "ksh") == 0) {
343 * KSH description. The Korn shell has a superset of
344 * the Bourne shell's functionality. There are probably
345 * builtins missing here.
347 shell
->name
= strdup(name
);
348 shell
->path
= str_concat(shellDir
, '/', name
);
349 shell
->hasEchoCtl
= true;
350 shell
->echoOff
= strdup("set -");
351 shell
->echoOn
= strdup("set -v");
352 shell
->noPrint
= strdup("set -");
353 shell
->hasErrCtl
= true;
354 shell
->errCheck
= strdup("set -e");
355 shell
->ignErr
= strdup("set +e");
356 shell
->echo
= strdup("v");
357 shell
->exit
= strdup("e");
358 shell
->meta
= strdup("#=|^(){};&<>*?[]:$`\\\n");
359 brk_string(&shell
->builtins
,
360 "alias cd eval exec exit read set ulimit unalias "
361 "umask unset wait", true);
362 shell
->unsetenv
= true;
373 * Given the line following a .SHELL target, parse it as a shell
377 * A pointer to a Shell structure, or NULL if no the spec was invalid.
380 Shell_Parse(const char line
[])
385 /* parse the specification */
386 if ((sh
= ShellParseSpec(line
, &fullSpec
)) == NULL
)
389 if (sh
->path
== NULL
) {
392 * If no path was given, the user wants one of the pre-defined
393 * shells, yes? So we find the one s/he wants with the help of
394 * ShellMatch and set things up the right way.
396 if (sh
->name
== NULL
) {
397 Parse_Error(PARSE_FATAL
,
398 "Neither path nor name specified");
403 Parse_Error(PARSE_FATAL
, "No path specified");
407 if ((match
= Shell_Match(sh
->name
)) == NULL
) {
408 Parse_Error(PARSE_FATAL
, "%s: no matching shell",
421 * The user provided a path. If s/he gave nothing else
422 * (fullSpec is false), try and find a matching shell in the
423 * ones we know of. Else we just take the specification at its
424 * word and copy it to a new location. In either case, we need
425 * to record the path the user gave for the shell.
427 if (sh
->name
== NULL
) {
428 /* get the base name as the name */
429 if ((sh
->name
= strrchr(sh
->path
, '/')) == NULL
) {
430 sh
->name
= estrdup(sh
->path
);
432 sh
->name
= estrdup(sh
->name
+ 1);
438 if ((match
= Shell_Match(sh
->name
)) == NULL
) {
439 Parse_Error(PARSE_FATAL
,
440 "%s: no matching shell", sh
->name
);
446 match
->path
= sh
->path
;