job.c (146571) | job.c (146572) |
---|---|
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 --- 26 unchanged lines hidden (view full) --- 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 * @(#)job.c 8.2 (Berkeley) 3/19/94 40 */ 41 42#include <sys/cdefs.h> | 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 --- 26 unchanged lines hidden (view full) --- 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 * @(#)job.c 8.2 (Berkeley) 3/19/94 40 */ 41 42#include <sys/cdefs.h> |
43__FBSDID("$FreeBSD: head/usr.bin/make/job.c 146571 2005-05-24 13:19:40Z harti $"); | 43__FBSDID("$FreeBSD: head/usr.bin/make/job.c 146572 2005-05-24 15:30:03Z harti $"); |
44 45#ifndef OLD_JOKE 46#define OLD_JOKE 0 47#endif /* OLD_JOKE */ 48 49/*- 50 * job.c -- 51 * handle the creation etc. of our child processes. --- 19 unchanged lines hidden (view full) --- 71 * commands attached to the .BEGIN target are executed 72 * before this function returns. Hence, the makefile must 73 * have been parsed before this function is called. 74 * 75 * Job_Full Return TRUE if the job table is filled. 76 * 77 * Job_Empty Return TRUE if the job table is completely empty. 78 * | 44 45#ifndef OLD_JOKE 46#define OLD_JOKE 0 47#endif /* OLD_JOKE */ 48 49/*- 50 * job.c -- 51 * handle the creation etc. of our child processes. --- 19 unchanged lines hidden (view full) --- 71 * commands attached to the .BEGIN target are executed 72 * before this function returns. Hence, the makefile must 73 * have been parsed before this function is called. 74 * 75 * Job_Full Return TRUE if the job table is filled. 76 * 77 * Job_Empty Return TRUE if the job table is completely empty. 78 * |
79 * Job_ParseShell Given the line following a .SHELL target, parse the 80 * line as a shell specification. Returns FALSE if the 81 * spec was incorrect. 82 * | |
83 * Job_Finish Perform any final processing which needs doing. This 84 * includes the execution of any commands which have 85 * been/were attached to the .END target. It should only 86 * be called when the job table is empty. 87 * 88 * Job_AbortAll Abort all currently running jobs. It doesn't handle 89 * output or do anything for the jobs, just kills them. 90 * It should only be called in an emergency, as it were. --- 42 unchanged lines hidden (view full) --- 133#include "config.h" 134#include "dir.h" 135#include "globals.h" 136#include "GNode.h" 137#include "job.h" 138#include "make.h" 139#include "parse.h" 140#include "pathnames.h" | 79 * Job_Finish Perform any final processing which needs doing. This 80 * includes the execution of any commands which have 81 * been/were attached to the .END target. It should only 82 * be called when the job table is empty. 83 * 84 * Job_AbortAll Abort all currently running jobs. It doesn't handle 85 * output or do anything for the jobs, just kills them. 86 * It should only be called in an emergency, as it were. --- 42 unchanged lines hidden (view full) --- 129#include "config.h" 130#include "dir.h" 131#include "globals.h" 132#include "GNode.h" 133#include "job.h" 134#include "make.h" 135#include "parse.h" 136#include "pathnames.h" |
137#include "shell.h" |
|
141#include "str.h" 142#include "suff.h" 143#include "targ.h" 144#include "util.h" 145#include "var.h" 146 147#define TMPPAT "/tmp/makeXXXXXXXXXX" 148 --- 114 unchanged lines hidden (view full) --- 263#define outBuf output.o_pipe.op_outBuf 264#define curPos output.o_pipe.op_curPos 265#define outFile output.o_file.of_outFile 266#define outFd output.o_file.of_outFd 267 268TAILQ_HEAD(JobList, Job); 269 270/* | 138#include "str.h" 139#include "suff.h" 140#include "targ.h" 141#include "util.h" 142#include "var.h" 143 144#define TMPPAT "/tmp/makeXXXXXXXXXX" 145 --- 114 unchanged lines hidden (view full) --- 260#define outBuf output.o_pipe.op_outBuf 261#define curPos output.o_pipe.op_curPos 262#define outFile output.o_file.of_outFile 263#define outFd output.o_file.of_outFd 264 265TAILQ_HEAD(JobList, Job); 266 267/* |
271 * Shell Specifications: 272 * 273 * Some special stuff goes on if a shell doesn't have error control. In such 274 * a case, errCheck becomes a printf template for echoing the command, 275 * should echoing be on and ignErr becomes another printf template for 276 * executing the command while ignoring the return status. If either of these 277 * strings is empty when hasErrCtl is FALSE, the command will be executed 278 * anyway as is and if it causes an error, so be it. 279 */ 280struct Shell { 281 TAILQ_ENTRY(Shell) link; /* link all shell descriptions */ 282 283 /* 284 * the name of the shell. For Bourne and C shells, this is used 285 * only to find the shell description when used as the single 286 * source of a .SHELL target. For user-defined shells, this is 287 * the full path of the shell. 288 */ 289 char *name; 290 char *path; 291 292 /* True if both echoOff and echoOn defined */ 293 Boolean hasEchoCtl; 294 295 char *echoOff; /* command to turn off echo */ 296 char *echoOn; /* command to turn it back on */ 297 298 /* 299 * What the shell prints, when given the echo-off command. 300 * This line will not be printed when received from the shell. 301 * This is usually the command which was executed to turn off echoing. 302 */ 303 char *noPrint; 304 305 /* set if can control error checking for individual commands */ 306 Boolean hasErrCtl; 307 308 /* string to turn error checking on */ 309 char *errCheck; 310 311 /* string to turn off error checking */ 312 char *ignErr; 313 314 char *echo; /* command line flag: echo commands */ 315 char *exit; /* command line flag: exit on error */ 316 317 ArgArray builtins; 318 char *meta; 319 320 Boolean unsetenv; /* unsetenv("ENV") before exec */ 321}; 322TAILQ_HEAD(Shells, Shell); 323 324/* | |
325 * error handling variables 326 */ 327static int errors = 0; /* number of errors reported */ 328static int aborting = 0; /* why is the make aborting? */ 329#define ABORT_ERROR 1 /* Because of an error */ 330#define ABORT_INTERRUPT 2 /* Because it was interrupted */ 331#define ABORT_WAIT 3 /* Waiting for jobs to finish */ 332 --- 20 unchanged lines hidden (view full) --- 353 * Return values from JobStart. 354 */ 355#define JOB_RUNNING 0 /* Job is running */ 356#define JOB_ERROR 1 /* Error in starting the job */ 357#define JOB_FINISHED 2 /* The job is already finished */ 358#define JOB_STOPPED 3 /* The job is stopped */ 359 360/* | 268 * error handling variables 269 */ 270static int errors = 0; /* number of errors reported */ 271static int aborting = 0; /* why is the make aborting? */ 272#define ABORT_ERROR 1 /* Because of an error */ 273#define ABORT_INTERRUPT 2 /* Because it was interrupted */ 274#define ABORT_WAIT 3 /* Waiting for jobs to finish */ 275 --- 20 unchanged lines hidden (view full) --- 296 * Return values from JobStart. 297 */ 298#define JOB_RUNNING 0 /* Job is running */ 299#define JOB_ERROR 1 /* Error in starting the job */ 300#define JOB_FINISHED 2 /* The job is already finished */ 301#define JOB_STOPPED 3 /* The job is stopped */ 302 303/* |
361 * Descriptions for various shells. What the list of builtins should contain 362 * is debatable: either all builtins or only those which may specified on 363 * a single line without use of meta-characters. For correct makefiles that 364 * contain only correct command lines there is no difference. But if a command 365 * line, for example, is: 'if -foo bar' and there is an executable named 'if' 366 * in the path, the first possibility would execute that 'if' while in the 367 * second case the shell would give an error. Histerically only a small 368 * subset of the builtins and no reserved words where given in the list which 369 * corresponds roughly to the first variant. So go with this but add missing 370 * words. 371 */ 372#define CSH_BUILTINS \ 373 "alias cd eval exec exit read set ulimit unalias " \ 374 "umask unset wait" 375 376#define SH_BUILTINS \ 377 "alias cd eval exec exit read set ulimit unalias " \ 378 "umask unset wait" 379 380#define CSH_META "#=|^(){};&<>*?[]:$`\\@\n" 381#define SH_META "#=|^(){};&<>*?[]:$`\\\n" 382 383static const char *const shells_init[] = { 384 /* 385 * CSH description. The csh can do echo control by playing 386 * with the setting of the 'echo' shell variable. Sadly, 387 * however, it is unable to do error control nicely. 388 */ 389 "name=csh path='" PATH_DEFSHELLDIR "/csh' " 390 "quiet='unset verbose' echo='set verbose' filter='unset verbose' " 391 "hasErrCtl=N check='echo \"%s\"\n' ignore='csh -c \"%s || exit 0\"' " 392 "echoFlag=v errFlag=e " 393 "meta='" CSH_META "' builtins='" CSH_BUILTINS "'", 394 395 /* 396 * SH description. Echo control is also possible and, under 397 * sun UNIX anyway, one can even control error checking. 398 */ 399 "name=sh path='" PATH_DEFSHELLDIR "/sh' " 400 "quiet='set -' echo='set -v' filter='set -' " 401 "hasErrCtl=Y check='set -e' ignore='set +e' " 402 "echoFlag=v errFlag=e " 403 "meta='" SH_META "' builtins='" SH_BUILTINS "'", 404 405 /* 406 * KSH description. The Korn shell has a superset of 407 * the Bourne shell's functionality. There are probably builtins 408 * missing here. 409 */ 410 "name=ksh path='" PATH_DEFSHELLDIR "/ksh' " 411 "quiet='set -' echo='set -v' filter='set -' " 412 "hasErrCtl=Y check='set -e' ignore='set +e' " 413 "echoFlag=v errFlag=e " 414 "meta='" SH_META "' builtins='" SH_BUILTINS "' unsetenv=T", 415 416 NULL 417}; 418 419/* 420 * This is the shell to which we pass all commands in the Makefile. 421 * It is set by the Job_ParseShell function. 422 */ 423static struct Shell *commandShell = NULL; 424 425/* 426 * This is the list of all known shells. 427 */ 428static struct Shells shells = TAILQ_HEAD_INITIALIZER(shells); 429 430/* | |
431 * The maximum number of jobs that may run. This is initialize from the 432 * -j argument for the leading make and from the FIFO for sub-makes. 433 */ 434static int maxJobs; 435 436static int nJobs; /* The number of children currently running */ 437 438/* The structures that describe them */ --- 83 unchanged lines hidden (view full) --- 522 int errCheck; 523 524 pid_t child_pid; 525} ProcStuff; 526 527static void JobRestart(Job *); 528static int JobStart(GNode *, int, Job *); 529static void JobDoOutput(Job *, Boolean); | 304 * The maximum number of jobs that may run. This is initialize from the 305 * -j argument for the leading make and from the FIFO for sub-makes. 306 */ 307static int maxJobs; 308 309static int nJobs; /* The number of children currently running */ 310 311/* The structures that describe them */ --- 83 unchanged lines hidden (view full) --- 395 int errCheck; 396 397 pid_t child_pid; 398} ProcStuff; 399 400static void JobRestart(Job *); 401static int JobStart(GNode *, int, Job *); 402static void JobDoOutput(Job *, Boolean); |
530static struct Shell *JobMatchShell(const char *); | |
531static void JobInterrupt(int, int); 532static void JobRestartJobs(void); 533static void ProcExec(const ProcStuff *) __dead2; 534static int Compat_RunCommand(char *, struct GNode *); | 403static void JobInterrupt(int, int); 404static void JobRestartJobs(void); 405static void ProcExec(const ProcStuff *) __dead2; 406static int Compat_RunCommand(char *, struct GNode *); |
535static void JobShellDump(const struct Shell *) __unused; | |
536 537static GNode *curTarg = NULL; 538static GNode *ENDNode; 539 540/** 541 * Create a fifo file with a uniq filename, and returns a file 542 * descriptor to that fifo. 543 */ --- 1982 unchanged lines hidden (view full) --- 2526 */ 2527void 2528Job_Make(GNode *gn) 2529{ 2530 2531 JobStart(gn, 0, NULL); 2532} 2533 | 407 408static GNode *curTarg = NULL; 409static GNode *ENDNode; 410 411/** 412 * Create a fifo file with a uniq filename, and returns a file 413 * descriptor to that fifo. 414 */ --- 1982 unchanged lines hidden (view full) --- 2397 */ 2398void 2399Job_Make(GNode *gn) 2400{ 2401 2402 JobStart(gn, 0, NULL); 2403} 2404 |
2534static int 2535sort_builtins(const void *p1, const void *p2) 2536{ 2537 2538 return (strcmp(*(const char* const*)p1, *(const char* const*)p2)); 2539} 2540 | |
2541/** | 2405/** |
2542 * JobFreeShell 2543 * Free a shell structure and all associated strings. 2544 */ 2545static void 2546JobFreeShell(struct Shell *sh) 2547{ 2548 2549 if (sh != NULL) { 2550 free(sh->name); 2551 free(sh->path); 2552 free(sh->echoOff); 2553 free(sh->echoOn); 2554 free(sh->noPrint); 2555 free(sh->errCheck); 2556 free(sh->ignErr); 2557 free(sh->echo); 2558 free(sh->exit); 2559 ArgArray_Done(&sh->builtins); 2560 free(sh->meta); 2561 free(sh); 2562 } 2563} 2564 2565/** 2566 * Dump a shell specification to stderr. 2567 */ 2568static void 2569JobShellDump(const struct Shell *sh) 2570{ 2571 int i; 2572 2573 fprintf(stderr, "Shell %p:\n", sh); 2574 fprintf(stderr, " name='%s' path='%s'\n", sh->name, sh->path); 2575 fprintf(stderr, " hasEchoCtl=%d echoOff='%s' echoOn='%s'\n", 2576 sh->hasEchoCtl, sh->echoOff, sh->echoOn); 2577 fprintf(stderr, " noPrint='%s'\n", sh->noPrint); 2578 fprintf(stderr, " hasErrCtl=%d errCheck='%s' ignErr='%s'\n", 2579 sh->hasErrCtl, sh->errCheck, sh->ignErr); 2580 fprintf(stderr, " echo='%s' exit='%s'\n", sh->echo, sh->exit); 2581 fprintf(stderr, " builtins=%d\n", sh->builtins.argc - 1); 2582 for (i = 1; i < sh->builtins.argc; i++) 2583 fprintf(stderr, " '%s'", sh->builtins.argv[i]); 2584 fprintf(stderr, "\n meta='%s'\n", sh->meta); 2585 fprintf(stderr, " unsetenv=%d\n", sh->unsetenv); 2586} 2587 2588/** 2589 * Parse a shell specification line and return the new Shell structure. 2590 * In case of an error a message is printed and NULL is returned. 2591 */ 2592static struct Shell * 2593JobParseShellSpec(const char *spec, Boolean *fullSpec) 2594{ 2595 ArgArray aa; 2596 struct Shell *sh; 2597 char *eq; 2598 char *keyw; 2599 int arg; 2600 2601 *fullSpec = FALSE; 2602 2603 sh = emalloc(sizeof(*sh)); 2604 memset(sh, 0, sizeof(*sh)); 2605 ArgArray_Init(&sh->builtins); 2606 2607 /* 2608 * Parse the specification by keyword but skip the first word 2609 */ 2610 brk_string(&aa, spec, TRUE); 2611 2612 for (arg = 1; arg < aa.argc; arg++) { 2613 /* 2614 * Split keyword and value 2615 */ 2616 keyw = aa.argv[arg]; 2617 if ((eq = strchr(keyw, '=')) == NULL) { 2618 Parse_Error(PARSE_FATAL, "missing '=' in shell " 2619 "specification keyword '%s'", keyw); 2620 ArgArray_Done(&aa); 2621 JobFreeShell(sh); 2622 return (NULL); 2623 } 2624 *eq++ = '\0'; 2625 2626 if (strcmp(keyw, "path") == 0) { 2627 free(sh->path); 2628 sh->path = estrdup(eq); 2629 } else if (strcmp(keyw, "name") == 0) { 2630 free(sh->name); 2631 sh->name = estrdup(eq); 2632 } else if (strcmp(keyw, "quiet") == 0) { 2633 free(sh->echoOff); 2634 sh->echoOff = estrdup(eq); 2635 *fullSpec = TRUE; 2636 } else if (strcmp(keyw, "echo") == 0) { 2637 free(sh->echoOn); 2638 sh->echoOn = estrdup(eq); 2639 *fullSpec = TRUE; 2640 } else if (strcmp(keyw, "filter") == 0) { 2641 free(sh->noPrint); 2642 sh->noPrint = estrdup(eq); 2643 *fullSpec = TRUE; 2644 } else if (strcmp(keyw, "echoFlag") == 0) { 2645 free(sh->echo); 2646 sh->echo = estrdup(eq); 2647 *fullSpec = TRUE; 2648 } else if (strcmp(keyw, "errFlag") == 0) { 2649 free(sh->exit); 2650 sh->exit = estrdup(eq); 2651 *fullSpec = TRUE; 2652 } else if (strcmp(keyw, "hasErrCtl") == 0) { 2653 sh->hasErrCtl = (*eq == 'Y' || *eq == 'y' || 2654 *eq == 'T' || *eq == 't'); 2655 *fullSpec = TRUE; 2656 } else if (strcmp(keyw, "check") == 0) { 2657 free(sh->errCheck); 2658 sh->errCheck = estrdup(eq); 2659 *fullSpec = TRUE; 2660 } else if (strcmp(keyw, "ignore") == 0) { 2661 free(sh->ignErr); 2662 sh->ignErr = estrdup(eq); 2663 *fullSpec = TRUE; 2664 } else if (strcmp(keyw, "builtins") == 0) { 2665 ArgArray_Done(&sh->builtins); 2666 brk_string(&sh->builtins, eq, TRUE); 2667 qsort(sh->builtins.argv + 1, sh->builtins.argc - 1, 2668 sizeof(char *), sort_builtins); 2669 *fullSpec = TRUE; 2670 } else if (strcmp(keyw, "meta") == 0) { 2671 free(sh->meta); 2672 sh->meta = estrdup(eq); 2673 *fullSpec = TRUE; 2674 } else if (strcmp(keyw, "unsetenv") == 0) { 2675 sh->unsetenv = (*eq == 'Y' || *eq == 'y' || 2676 *eq == 'T' || *eq == 't'); 2677 *fullSpec = TRUE; 2678 } else { 2679 Parse_Error(PARSE_FATAL, "unknown keyword in shell " 2680 "specification '%s'", keyw); 2681 ArgArray_Done(&aa); 2682 JobFreeShell(sh); 2683 return (NULL); 2684 } 2685 } 2686 ArgArray_Done(&aa); 2687 2688 /* 2689 * Some checks (could be more) 2690 */ 2691 if (*fullSpec) { 2692 if ((sh->echoOn != NULL) ^ (sh->echoOff != NULL)) { 2693 Parse_Error(PARSE_FATAL, "Shell must have either both " 2694 "echoOff and echoOn or none of them"); 2695 JobFreeShell(sh); 2696 return (NULL); 2697 } 2698 2699 if (sh->echoOn != NULL && sh->echoOff != NULL) 2700 sh->hasEchoCtl = TRUE; 2701 } 2702 2703 return (sh); 2704} 2705 2706/** 2707 * Parse the builtin shell specifications and put them into the shell 2708 * list. Then select the default shell to be the current shell. This 2709 * is called from main() before any parsing (including MAKEFLAGS and 2710 * command line) is done. 2711 */ 2712void 2713Shell_Init(void) 2714{ 2715 int i; 2716 struct Shell *sh; 2717 Boolean fullSpec; 2718 2719 for (i = 0; shells_init[i] != NULL; i++) { 2720 sh = JobParseShellSpec(shells_init[i], &fullSpec); 2721 TAILQ_INSERT_TAIL(&shells, sh, link); 2722 if (strcmp(sh->name, DEFSHELLNAME) == 0) 2723 commandShell = sh; 2724 } 2725} 2726 2727/** | |
2728 * Job_Init 2729 * Initialize the process module, given a maximum number of jobs. 2730 * 2731 * Side Effects: 2732 * lists and counters are initialized 2733 */ 2734void 2735Job_Init(int maxproc) --- 179 unchanged lines hidden (view full) --- 2915 return (TRUE); 2916 } 2917 } else { 2918 return (FALSE); 2919 } 2920} 2921 2922/** | 2406 * Job_Init 2407 * Initialize the process module, given a maximum number of jobs. 2408 * 2409 * Side Effects: 2410 * lists and counters are initialized 2411 */ 2412void 2413Job_Init(int maxproc) --- 179 unchanged lines hidden (view full) --- 2593 return (TRUE); 2594 } 2595 } else { 2596 return (FALSE); 2597 } 2598} 2599 2600/** |
2923 * Find a matching shell in 'shells' given its final component. 2924 * 2925 * Results: 2926 * A pointer to a freshly allocated Shell structure with the contents 2927 * from static description or NULL if no shell with the given name 2928 * is found. 2929 */ 2930static struct Shell * 2931JobMatchShell(const char *name) 2932{ 2933 struct Shell *sh; 2934 2935 TAILQ_FOREACH(sh, &shells, link) 2936 if (strcmp(sh->name, name) == 0) 2937 return (sh); 2938 2939 return (NULL); 2940} 2941 2942/** 2943 * Job_ParseShell 2944 * Parse a shell specification and set up commandShell appropriately. 2945 * 2946 * Results: 2947 * TRUE if the specification was correct. FALSE otherwise. 2948 * 2949 * Side Effects: 2950 * commandShell points to a Shell structure (either predefined or 2951 * created from the shell spec). 2952 * 2953 * Notes: 2954 * A shell specification consists of a .SHELL target, with dependency 2955 * operator, followed by a series of blank-separated words. Double 2956 * quotes can be used to use blanks in words. A backslash escapes 2957 * anything (most notably a double-quote and a space) and 2958 * provides the functionality it does in C. Each word consists of 2959 * keyword and value separated by an equal sign. There should be no 2960 * unnecessary spaces in the word. The keywords are as follows: 2961 * name Name of shell. 2962 * path Location of shell. Overrides "name" if given 2963 * quiet Command to turn off echoing. 2964 * echo Command to turn echoing on 2965 * filter Result of turning off echoing that shouldn't be 2966 * printed. 2967 * echoFlag Flag to turn echoing on at the start 2968 * errFlag Flag to turn error checking on at the start 2969 * hasErrCtl True if shell has error checking control 2970 * check Command to turn on error checking if hasErrCtl 2971 * is TRUE or template of command to echo a command 2972 * for which error checking is off if hasErrCtl is 2973 * FALSE. 2974 * ignore Command to turn off error checking if hasErrCtl 2975 * is TRUE or template of command to execute a 2976 * command so as to ignore any errors it returns if 2977 * hasErrCtl is FALSE. 2978 * builtins A space separated list of builtins. If one 2979 * of these builtins is detected when make wants 2980 * to execute a command line, the command line is 2981 * handed to the shell. Otherwise make may try to 2982 * execute the command directly. If this list is empty 2983 * it is assumed, that the command must always be 2984 * handed over to the shell. 2985 * meta The shell meta characters. If this is not specified 2986 * or empty, commands are alway passed to the shell. 2987 * Otherwise they are not passed when they contain 2988 * neither a meta character nor a builtin command. 2989 */ 2990Boolean 2991Job_ParseShell(const char line[]) 2992{ 2993 Boolean fullSpec; 2994 struct Shell *sh; 2995 struct Shell *match; 2996 2997 /* parse the specification */ 2998 if ((sh = JobParseShellSpec(line, &fullSpec)) == NULL) 2999 return (FALSE); 3000 3001 if (sh->path == NULL) { 3002 /* 3003 * If no path was given, the user wants one of the pre-defined 3004 * shells, yes? So we find the one s/he wants with the help of 3005 * JobMatchShell and set things up the right way. 3006 */ 3007 if (sh->name == NULL) { 3008 Parse_Error(PARSE_FATAL, 3009 "Neither path nor name specified"); 3010 JobFreeShell(sh); 3011 return (FALSE); 3012 } 3013 if (fullSpec) { 3014 Parse_Error(PARSE_FATAL, "No path specified"); 3015 JobFreeShell(sh); 3016 return (FALSE); 3017 } 3018 if ((match = JobMatchShell(sh->name)) == NULL) { 3019 Parse_Error(PARSE_FATAL, "%s: no matching shell", 3020 sh->name); 3021 JobFreeShell(sh); 3022 return (FALSE); 3023 } 3024 JobFreeShell(sh); 3025 commandShell = match; 3026 3027 return (TRUE); 3028 } 3029 3030 /* 3031 * The user provided a path. If s/he gave nothing else 3032 * (fullSpec is FALSE), try and find a matching shell in the 3033 * ones we know of. Else we just take the specification at its 3034 * word and copy it to a new location. In either case, we need 3035 * to record the path the user gave for the shell. 3036 */ 3037 if (sh->name == NULL) { 3038 /* get the base name as the name */ 3039 if ((sh->name = strrchr(sh->path, '/')) == NULL) { 3040 sh->name = estrdup(sh->path); 3041 } else { 3042 sh->name = estrdup(sh->name + 1); 3043 } 3044 } 3045 3046 if (!fullSpec) { 3047 if ((match = JobMatchShell(sh->name)) == NULL) { 3048 Parse_Error(PARSE_FATAL, 3049 "%s: no matching shell", sh->name); 3050 JobFreeShell(sh); 3051 return (FALSE); 3052 } 3053 3054 /* set the patch on the matching shell */ 3055 free(match->path); 3056 match->path = sh->path; 3057 sh->path = NULL; 3058 3059 JobFreeShell(sh); 3060 commandShell = match; 3061 return (TRUE); 3062 } 3063 3064 TAILQ_INSERT_HEAD(&shells, sh, link); 3065 3066 /* set the new shell */ 3067 commandShell = sh; 3068 return (TRUE); 3069} 3070 3071/** | |
3072 * JobInterrupt 3073 * Handle the receipt of an interrupt. 3074 * 3075 * Side Effects: 3076 * All children are killed. Another job will be started if the 3077 * .INTERRUPT target was given. 3078 */ 3079static void --- 896 unchanged lines hidden --- | 2601 * JobInterrupt 2602 * Handle the receipt of an interrupt. 2603 * 2604 * Side Effects: 2605 * All children are killed. Another job will be started if the 2606 * .INTERRUPT target was given. 2607 */ 2608static void --- 896 unchanged lines hidden --- |