| @@ -1,14 +1,14 @@ | | | @@ -1,14 +1,14 @@ |
1 | /* $NetBSD: job.c,v 1.402 2021/01/29 23:45:35 rillig Exp $ */ | | 1 | /* $NetBSD: job.c,v 1.403 2021/01/30 13:02:54 rillig Exp $ */ |
2 | | | 2 | |
3 | /* | | 3 | /* |
4 | * Copyright (c) 1988, 1989, 1990 The Regents of the University of California. | | 4 | * Copyright (c) 1988, 1989, 1990 The Regents of the University of California. |
5 | * All rights reserved. | | 5 | * All rights reserved. |
6 | * | | 6 | * |
7 | * This code is derived from software contributed to Berkeley by | | 7 | * This code is derived from software contributed to Berkeley by |
8 | * Adam de Boor. | | 8 | * Adam de Boor. |
9 | * | | 9 | * |
10 | * Redistribution and use in source and binary forms, with or without | | 10 | * Redistribution and use in source and binary forms, with or without |
11 | * modification, are permitted provided that the following conditions | | 11 | * modification, are permitted provided that the following conditions |
12 | * are met: | | 12 | * are met: |
13 | * 1. Redistributions of source code must retain the above copyright | | 13 | * 1. Redistributions of source code must retain the above copyright |
14 | * notice, this list of conditions and the following disclaimer. | | 14 | * notice, this list of conditions and the following disclaimer. |
| @@ -133,27 +133,27 @@ | | | @@ -133,27 +133,27 @@ |
133 | #ifndef USE_SELECT | | 133 | #ifndef USE_SELECT |
134 | #include <poll.h> | | 134 | #include <poll.h> |
135 | #endif | | 135 | #endif |
136 | #include <signal.h> | | 136 | #include <signal.h> |
137 | #include <utime.h> | | 137 | #include <utime.h> |
138 | | | 138 | |
139 | #include "make.h" | | 139 | #include "make.h" |
140 | #include "dir.h" | | 140 | #include "dir.h" |
141 | #include "job.h" | | 141 | #include "job.h" |
142 | #include "pathnames.h" | | 142 | #include "pathnames.h" |
143 | #include "trace.h" | | 143 | #include "trace.h" |
144 | | | 144 | |
145 | /* "@(#)job.c 8.2 (Berkeley) 3/19/94" */ | | 145 | /* "@(#)job.c 8.2 (Berkeley) 3/19/94" */ |
146 | MAKE_RCSID("$NetBSD: job.c,v 1.402 2021/01/29 23:45:35 rillig Exp $"); | | 146 | MAKE_RCSID("$NetBSD: job.c,v 1.403 2021/01/30 13:02:54 rillig Exp $"); |
147 | | | 147 | |
148 | /* | | 148 | /* |
149 | * A shell defines how the commands are run. All commands for a target are | | 149 | * A shell defines how the commands are run. All commands for a target are |
150 | * written into a single file, which is then given to the shell to execute | | 150 | * written into a single file, which is then given to the shell to execute |
151 | * the commands from it. The commands are written to the file using a few | | 151 | * the commands from it. The commands are written to the file using a few |
152 | * templates for echo control and error control. | | 152 | * templates for echo control and error control. |
153 | * | | 153 | * |
154 | * The name of the shell is the basename for the predefined shells, such as | | 154 | * The name of the shell is the basename for the predefined shells, such as |
155 | * "sh", "csh", "bash". For custom shells, it is the full pathname, and its | | 155 | * "sh", "csh", "bash". For custom shells, it is the full pathname, and its |
156 | * basename is used to select the type of shell; the longest match wins. | | 156 | * basename is used to select the type of shell; the longest match wins. |
157 | * So /usr/pkg/bin/bash has type sh, /usr/local/bin/tcsh has type csh. | | 157 | * So /usr/pkg/bin/bash has type sh, /usr/local/bin/tcsh has type csh. |
158 | * | | 158 | * |
159 | * The echoing of command lines is controlled using hasEchoCtl, echoOff, | | 159 | * The echoing of command lines is controlled using hasEchoCtl, echoOff, |
| @@ -1006,38 +1006,43 @@ JobPrintCommands(Job *job) | | | @@ -1006,38 +1006,43 @@ JobPrintCommands(Job *job) |
1006 | if (strcmp(cmd, "...") == 0) { | | 1006 | if (strcmp(cmd, "...") == 0) { |
1007 | job->node->type |= OP_SAVE_CMDS; | | 1007 | job->node->type |= OP_SAVE_CMDS; |
1008 | job->tailCmds = ln->next; | | 1008 | job->tailCmds = ln->next; |
1009 | break; | | 1009 | break; |
1010 | } | | 1010 | } |
1011 | | | 1011 | |
1012 | JobPrintCommand(job, &wr, ln, ln->datum); | | 1012 | JobPrintCommand(job, &wr, ln, ln->datum); |
1013 | seen = TRUE; | | 1013 | seen = TRUE; |
1014 | } | | 1014 | } |
1015 | | | 1015 | |
1016 | return seen; | | 1016 | return seen; |
1017 | } | | 1017 | } |
1018 | | | 1018 | |
1019 | /* Save the delayed commands, to be executed when everything else is done. */ | | 1019 | /* |
| | | 1020 | * Save the delayed commands (those after '...'), to be executed later in |
| | | 1021 | * the '.END' node, when everything else is done. |
| | | 1022 | */ |
1020 | static void | | 1023 | static void |
1021 | JobSaveCommands(Job *job) | | 1024 | JobSaveCommands(Job *job) |
1022 | { | | 1025 | { |
1023 | StringListNode *ln; | | 1026 | StringListNode *ln; |
1024 | | | 1027 | |
1025 | for (ln = job->tailCmds; ln != NULL; ln = ln->next) { | | 1028 | for (ln = job->tailCmds; ln != NULL; ln = ln->next) { |
1026 | const char *cmd = ln->datum; | | 1029 | const char *cmd = ln->datum; |
1027 | char *expanded_cmd; | | 1030 | char *expanded_cmd; |
1028 | /* XXX: This Var_Subst is only intended to expand the dynamic | | 1031 | /* |
| | | 1032 | * XXX: This Var_Subst is only intended to expand the dynamic |
1029 | * variables such as .TARGET, .IMPSRC. It is not intended to | | 1033 | * variables such as .TARGET, .IMPSRC. It is not intended to |
1030 | * expand the other variables as well; see deptgt-end.mk. */ | | 1034 | * expand the other variables as well; see deptgt-end.mk. |
| | | 1035 | */ |
1031 | (void)Var_Subst(cmd, job->node, VARE_WANTRES, &expanded_cmd); | | 1036 | (void)Var_Subst(cmd, job->node, VARE_WANTRES, &expanded_cmd); |
1032 | /* TODO: handle errors */ | | 1037 | /* TODO: handle errors */ |
1033 | Lst_Append(&Targ_GetEndNode()->commands, expanded_cmd); | | 1038 | Lst_Append(&Targ_GetEndNode()->commands, expanded_cmd); |
1034 | } | | 1039 | } |
1035 | } | | 1040 | } |
1036 | | | 1041 | |
1037 | | | 1042 | |
1038 | /* Called to close both input and output pipes when a job is finished. */ | | 1043 | /* Called to close both input and output pipes when a job is finished. */ |
1039 | static void | | 1044 | static void |
1040 | JobClosePipes(Job *job) | | 1045 | JobClosePipes(Job *job) |
1041 | { | | 1046 | { |
1042 | clearfd(job); | | 1047 | clearfd(job); |
1043 | (void)close(job->outPipe); | | 1048 | (void)close(job->outPipe); |
| @@ -1650,59 +1655,48 @@ JobStart(GNode *gn, Boolean special) | | | @@ -1650,59 +1655,48 @@ JobStart(GNode *gn, Boolean special) |
1650 | job->status = JOB_ST_SET_UP; | | 1655 | job->status = JOB_ST_SET_UP; |
1651 | | | 1656 | |
1652 | job->special = special || gn->type & OP_SPECIAL; | | 1657 | job->special = special || gn->type & OP_SPECIAL; |
1653 | job->ignerr = opts.ignoreErrors || gn->type & OP_IGNORE; | | 1658 | job->ignerr = opts.ignoreErrors || gn->type & OP_IGNORE; |
1654 | job->echo = !(opts.beSilent || gn->type & OP_SILENT); | | 1659 | job->echo = !(opts.beSilent || gn->type & OP_SILENT); |
1655 | | | 1660 | |
1656 | /* | | 1661 | /* |
1657 | * Check the commands now so any attributes from .DEFAULT have a | | 1662 | * Check the commands now so any attributes from .DEFAULT have a |
1658 | * chance to migrate to the node. | | 1663 | * chance to migrate to the node. |
1659 | */ | | 1664 | */ |
1660 | cmdsOK = Job_CheckCommands(gn, Error); | | 1665 | cmdsOK = Job_CheckCommands(gn, Error); |
1661 | | | 1666 | |
1662 | job->inPollfd = NULL; | | 1667 | job->inPollfd = NULL; |
1663 | /* | | 1668 | |
1664 | * If the -n flag wasn't given, we open up OUR (not the child's) | | | |
1665 | * temporary file to stuff commands in it. The thing is rd/wr so | | | |
1666 | * we don't need to reopen it to feed it to the shell. If the -n | | | |
1667 | * flag *was* given, we just set the file to be stdout. Cute, huh? | | | |
1668 | */ | | | |
1669 | if (Lst_IsEmpty(&gn->commands)) { | | 1669 | if (Lst_IsEmpty(&gn->commands)) { |
1670 | job->cmdFILE = stdout; | | 1670 | job->cmdFILE = stdout; |
1671 | run = FALSE; | | 1671 | run = FALSE; |
1672 | } else if (((gn->type & OP_MAKE) && !opts.noRecursiveExecute) || | | 1672 | } else if (((gn->type & OP_MAKE) && !opts.noRecursiveExecute) || |
1673 | (!opts.noExecute && !opts.touchFlag)) { | | 1673 | (!opts.noExecute && !opts.touchFlag)) { |
1674 | /* | | 1674 | /* |
1675 | * The above conditions look very similar to | | 1675 | * The above condition looks very similar to |
1676 | * GNode_ShouldExecute but are subtly different. | | 1676 | * GNode_ShouldExecute but is subtly different. |
1677 | * They prevent that .MAKE targets are touched. | | 1677 | * It prevents that .MAKE targets are touched. |
1678 | */ | | 1678 | */ |
1679 | | | 1679 | |
1680 | JobWriteShellCommands(job, gn, cmdsOK, &run); | | 1680 | JobWriteShellCommands(job, gn, cmdsOK, &run); |
1681 | (void)fflush(job->cmdFILE); | | 1681 | (void)fflush(job->cmdFILE); |
1682 | } else if (!GNode_ShouldExecute(gn)) { | | 1682 | } else if (!GNode_ShouldExecute(gn)) { |
1683 | /* | | 1683 | /* |
1684 | * Not executing anything -- just print all the commands to | | 1684 | * Not executing anything -- just print all the commands to |
1685 | * stdout in one fell swoop. This will still set up | | 1685 | * stdout in one fell swoop. This will still set up |
1686 | * job->tailCmds correctly. | | 1686 | * job->tailCmds correctly. |
1687 | */ | | 1687 | */ |
1688 | SwitchOutputTo(gn); | | 1688 | SwitchOutputTo(gn); |
1689 | job->cmdFILE = stdout; | | 1689 | job->cmdFILE = stdout; |
1690 | /* | | | |
1691 | * Only print the commands if they're ok, but don't die if | | | |
1692 | * they're not -- just let the user know they're bad and | | | |
1693 | * keep going. It doesn't do any harm in this case and may | | | |
1694 | * do some good. | | | |
1695 | */ | | | |
1696 | if (cmdsOK) | | 1690 | if (cmdsOK) |
1697 | JobPrintCommands(job); | | 1691 | JobPrintCommands(job); |
1698 | /* Don't execute the shell, thank you. */ | | 1692 | /* Don't execute the shell, thank you. */ |
1699 | run = FALSE; | | 1693 | run = FALSE; |
1700 | (void)fflush(job->cmdFILE); | | 1694 | (void)fflush(job->cmdFILE); |
1701 | } else { | | 1695 | } else { |
1702 | /* | | 1696 | /* |
1703 | * Just touch the target and note that no shell should be | | 1697 | * Just touch the target and note that no shell should be |
1704 | * executed. Set cmdFILE to stdout to make life easier. | | 1698 | * executed. Set cmdFILE to stdout to make life easier. |
1705 | */ | | 1699 | */ |
1706 | job->cmdFILE = stdout; | | 1700 | job->cmdFILE = stdout; |
1707 | Job_Touch(gn, job->echo); | | 1701 | Job_Touch(gn, job->echo); |
1708 | run = FALSE; | | 1702 | run = FALSE; |