| @@ -1,14 +1,14 @@ | | | @@ -1,14 +1,14 @@ |
1 | /* $NetBSD: job.c,v 1.317 2020/11/14 12:38:06 rillig Exp $ */ | | 1 | /* $NetBSD: job.c,v 1.318 2020/11/14 13:07:39 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.317 2020/11/14 12:38:06 rillig Exp $"); | | 146 | MAKE_RCSID("$NetBSD: job.c,v 1.318 2020/11/14 13:07:39 rillig Exp $"); |
147 | | | 147 | |
148 | /* A shell defines how the commands are run. All commands for a target are | | 148 | /* A shell defines how the commands are run. All commands for a target are |
149 | * written into a single file, which is then given to the shell to execute | | 149 | * written into a single file, which is then given to the shell to execute |
150 | * the commands from it. The commands are written to the file using a few | | 150 | * the commands from it. The commands are written to the file using a few |
151 | * templates for echo control and error control. | | 151 | * templates for echo control and error control. |
152 | * | | 152 | * |
153 | * The name of the shell is the basename for the predefined shells, such as | | 153 | * The name of the shell is the basename for the predefined shells, such as |
154 | * "sh", "csh", "bash". For custom shells, it is the full pathname, and its | | 154 | * "sh", "csh", "bash". For custom shells, it is the full pathname, and its |
155 | * basename is used to select the type of shell; the longest match wins. | | 155 | * basename is used to select the type of shell; the longest match wins. |
156 | * So /usr/pkg/bin/bash has type sh, /usr/local/bin/tcsh has type csh. | | 156 | * So /usr/pkg/bin/bash has type sh, /usr/local/bin/tcsh has type csh. |
157 | * | | 157 | * |
158 | * The echoing of command lines is controlled using hasEchoCtl, echoOff, | | 158 | * The echoing of command lines is controlled using hasEchoCtl, echoOff, |
159 | * echoOn, noPrint and noPrintLen. When echoOff is executed by the shell, it | | 159 | * echoOn, noPrint and noPrintLen. When echoOff is executed by the shell, it |
| @@ -682,26 +682,42 @@ EscapeShellDblQuot(const char *cmd) | | | @@ -682,26 +682,42 @@ EscapeShellDblQuot(const char *cmd) |
682 | | | 682 | |
683 | /* Worst that could happen is every char needs escaping. */ | | 683 | /* Worst that could happen is every char needs escaping. */ |
684 | char *esc = bmake_malloc(strlen(cmd) * 2 + 1); | | 684 | char *esc = bmake_malloc(strlen(cmd) * 2 + 1); |
685 | for (i = 0, j = 0; cmd[i] != '\0'; i++, j++) { | | 685 | for (i = 0, j = 0; cmd[i] != '\0'; i++, j++) { |
686 | if (cmd[i] == '$' || cmd[i] == '`' || cmd[i] == '\\' || cmd[i] == '"') | | 686 | if (cmd[i] == '$' || cmd[i] == '`' || cmd[i] == '\\' || cmd[i] == '"') |
687 | esc[j++] = '\\'; | | 687 | esc[j++] = '\\'; |
688 | esc[j] = cmd[i]; | | 688 | esc[j] = cmd[i]; |
689 | } | | 689 | } |
690 | esc[j] = '\0'; | | 690 | esc[j] = '\0'; |
691 | | | 691 | |
692 | return esc; | | 692 | return esc; |
693 | } | | 693 | } |
694 | | | 694 | |
| | | 695 | static void |
| | | 696 | JobPrintf(Job *job, const char *fmt, const char *arg) |
| | | 697 | { |
| | | 698 | if (DEBUG(JOB)) |
| | | 699 | debug_printf(fmt, arg); |
| | | 700 | |
| | | 701 | (void)fprintf(job->cmdFILE, fmt, arg); |
| | | 702 | (void)fflush(job->cmdFILE); |
| | | 703 | } |
| | | 704 | |
| | | 705 | static void |
| | | 706 | JobPrintln(Job *job, const char *line) |
| | | 707 | { |
| | | 708 | JobPrintf(job, "%s\n", line); |
| | | 709 | } |
| | | 710 | |
695 | /*- | | 711 | /*- |
696 | *----------------------------------------------------------------------- | | 712 | *----------------------------------------------------------------------- |
697 | * JobPrintCommand -- | | 713 | * JobPrintCommand -- |
698 | * Put out another command for the given job. If the command starts | | 714 | * Put out another command for the given job. If the command starts |
699 | * with an @ or a - we process it specially. In the former case, | | 715 | * with an @ or a - we process it specially. In the former case, |
700 | * so long as the -s and -n flags weren't given to make, we stick | | 716 | * so long as the -s and -n flags weren't given to make, we stick |
701 | * a shell-specific echoOff command in the script. In the latter, | | 717 | * a shell-specific echoOff command in the script. In the latter, |
702 | * we ignore errors for the entire job, unless the shell has error | | 718 | * we ignore errors for the entire job, unless the shell has error |
703 | * control. | | 719 | * control. |
704 | * If the command is just "..." we take all future commands for this | | 720 | * If the command is just "..." we take all future commands for this |
705 | * job to be commands to be executed once the entire graph has been | | 721 | * job to be commands to be executed once the entire graph has been |
706 | * made and return non-zero to signal that the end of the commands | | 722 | * made and return non-zero to signal that the end of the commands |
707 | * was reached. These commands are later attached to the postCommands | | 723 | * was reached. These commands are later attached to the postCommands |
| @@ -723,32 +739,26 @@ JobPrintCommand(Job *job, char *cmd) | | | @@ -723,32 +739,26 @@ JobPrintCommand(Job *job, char *cmd) |
723 | Boolean shutUp; /* true if we put a no echo command | | 739 | Boolean shutUp; /* true if we put a no echo command |
724 | * into the command file */ | | 740 | * into the command file */ |
725 | Boolean errOff; /* true if we turned error checking | | 741 | Boolean errOff; /* true if we turned error checking |
726 | * off before printing the command | | 742 | * off before printing the command |
727 | * and need to turn it back on */ | | 743 | * and need to turn it back on */ |
728 | Boolean runAlways; | | 744 | Boolean runAlways; |
729 | const char *cmdTemplate; /* Template to use when printing the | | 745 | const char *cmdTemplate; /* Template to use when printing the |
730 | * command */ | | 746 | * command */ |
731 | char *cmdStart; /* Start of expanded command */ | | 747 | char *cmdStart; /* Start of expanded command */ |
732 | char *escCmd = NULL; /* Command with quotes/backticks escaped */ | | 748 | char *escCmd = NULL; /* Command with quotes/backticks escaped */ |
733 | | | 749 | |
734 | noSpecials = !GNode_ShouldExecute(job->node); | | 750 | noSpecials = !GNode_ShouldExecute(job->node); |
735 | | | 751 | |
736 | #define DBPRINTF(fmt, arg) if (DEBUG(JOB)) { \ | | | |
737 | debug_printf(fmt, arg); \ | | | |
738 | } \ | | | |
739 | (void)fprintf(job->cmdFILE, fmt, arg); \ | | | |
740 | (void)fflush(job->cmdFILE); | | | |
741 | | | | |
742 | numCommands++; | | 752 | numCommands++; |
743 | | | 753 | |
744 | Var_Subst(cmd, job->node, VARE_WANTRES, &cmd); | | 754 | Var_Subst(cmd, job->node, VARE_WANTRES, &cmd); |
745 | /* TODO: handle errors */ | | 755 | /* TODO: handle errors */ |
746 | cmdStart = cmd; | | 756 | cmdStart = cmd; |
747 | | | 757 | |
748 | cmdTemplate = "%s\n"; | | 758 | cmdTemplate = "%s\n"; |
749 | | | 759 | |
750 | ParseRunOptions(&cmd, &shutUp, &errOff, &runAlways); | | 760 | ParseRunOptions(&cmd, &shutUp, &errOff, &runAlways); |
751 | | | 761 | |
752 | if (runAlways && noSpecials) { | | 762 | if (runAlways && noSpecials) { |
753 | /* | | 763 | /* |
754 | * We're not actually executing anything... | | 764 | * We're not actually executing anything... |
| @@ -761,139 +771,136 @@ JobPrintCommand(Job *job, char *cmd) | | | @@ -761,139 +771,136 @@ JobPrintCommand(Job *job, char *cmd) |
761 | | | 771 | |
762 | /* | | 772 | /* |
763 | * If the shell doesn't have error control the alternate echo'ing will | | 773 | * If the shell doesn't have error control the alternate echo'ing will |
764 | * be done (to avoid showing additional error checking code) | | 774 | * be done (to avoid showing additional error checking code) |
765 | * and this will need the characters '$ ` \ "' escaped | | 775 | * and this will need the characters '$ ` \ "' escaped |
766 | */ | | 776 | */ |
767 | | | 777 | |
768 | if (!commandShell->hasErrCtl) | | 778 | if (!commandShell->hasErrCtl) |
769 | escCmd = EscapeShellDblQuot(cmd); | | 779 | escCmd = EscapeShellDblQuot(cmd); |
770 | | | 780 | |
771 | if (shutUp) { | | 781 | if (shutUp) { |
772 | if (!(job->flags & JOB_SILENT) && !noSpecials && | | 782 | if (!(job->flags & JOB_SILENT) && !noSpecials && |
773 | (commandShell->hasEchoCtl)) { | | 783 | (commandShell->hasEchoCtl)) { |
774 | DBPRINTF("%s\n", commandShell->echoOff); | | 784 | JobPrintln(job, commandShell->echoOff); |
775 | } else { | | 785 | } else { |
776 | if (commandShell->hasErrCtl) | | 786 | if (commandShell->hasErrCtl) |
777 | shutUp = FALSE; | | 787 | shutUp = FALSE; |
778 | } | | 788 | } |
779 | } | | 789 | } |
780 | | | 790 | |
781 | if (errOff) { | | 791 | if (errOff) { |
782 | if (!noSpecials) { | | 792 | if (!noSpecials) { |
783 | if (commandShell->hasErrCtl) { | | 793 | if (commandShell->hasErrCtl) { |
784 | /* | | 794 | /* |
785 | * we don't want the error-control commands showing | | 795 | * we don't want the error-control commands showing |
786 | * up either, so we turn off echoing while executing | | 796 | * up either, so we turn off echoing while executing |
787 | * them. We could put another field in the shell | | 797 | * them. We could put another field in the shell |
788 | * structure to tell JobDoOutput to look for this | | 798 | * structure to tell JobDoOutput to look for this |
789 | * string too, but why make it any more complex than | | 799 | * string too, but why make it any more complex than |
790 | * it already is? | | 800 | * it already is? |
791 | */ | | 801 | */ |
792 | if (!(job->flags & JOB_SILENT) && !shutUp && | | 802 | if (!(job->flags & JOB_SILENT) && !shutUp && |
793 | (commandShell->hasEchoCtl)) { | | 803 | (commandShell->hasEchoCtl)) { |
794 | DBPRINTF("%s\n", commandShell->echoOff); | | 804 | JobPrintln(job, commandShell->echoOff); |
795 | DBPRINTF("%s\n", commandShell->errOffOrExecIgnore); | | 805 | JobPrintln(job, commandShell->errOffOrExecIgnore); |
796 | DBPRINTF("%s\n", commandShell->echoOn); | | 806 | JobPrintln(job, commandShell->echoOn); |
797 | } else { | | 807 | } else { |
798 | DBPRINTF("%s\n", commandShell->errOffOrExecIgnore); | | 808 | JobPrintln(job, commandShell->errOffOrExecIgnore); |
799 | } | | 809 | } |
800 | } else if (commandShell->errOffOrExecIgnore && | | 810 | } else if (commandShell->errOffOrExecIgnore && |
801 | commandShell->errOffOrExecIgnore[0] != '\0') { | | 811 | commandShell->errOffOrExecIgnore[0] != '\0') { |
802 | /* | | 812 | /* |
803 | * The shell has no error control, so we need to be | | 813 | * The shell has no error control, so we need to be |
804 | * weird to get it to ignore any errors from the command. | | 814 | * weird to get it to ignore any errors from the command. |
805 | * If echoing is turned on, we turn it off and use the | | 815 | * If echoing is turned on, we turn it off and use the |
806 | * errOnOrEcho template to echo the command. Leave echoing | | 816 | * errOnOrEcho template to echo the command. Leave echoing |
807 | * off so the user doesn't see the weirdness we go through | | 817 | * off so the user doesn't see the weirdness we go through |
808 | * to ignore errors. Set cmdTemplate to use the weirdness | | 818 | * to ignore errors. Set cmdTemplate to use the weirdness |
809 | * instead of the simple "%s\n" template. | | 819 | * instead of the simple "%s\n" template. |
810 | */ | | 820 | */ |
811 | job->flags |= JOB_IGNERR; | | 821 | job->flags |= JOB_IGNERR; |
812 | if (!(job->flags & JOB_SILENT) && !shutUp) { | | 822 | if (!(job->flags & JOB_SILENT) && !shutUp) { |
813 | if (commandShell->hasEchoCtl) { | | 823 | if (commandShell->hasEchoCtl) { |
814 | DBPRINTF("%s\n", commandShell->echoOff); | | 824 | JobPrintln(job, commandShell->echoOff); |
815 | } | | 825 | } |
816 | DBPRINTF(commandShell->errOnOrEcho, escCmd); | | 826 | JobPrintf(job, commandShell->errOnOrEcho, escCmd); |
817 | shutUp = TRUE; | | 827 | shutUp = TRUE; |
818 | } else { | | 828 | } else { |
819 | if (!shutUp) { | | 829 | if (!shutUp) |
820 | DBPRINTF(commandShell->errOnOrEcho, escCmd); | | 830 | JobPrintf(job, commandShell->errOnOrEcho, escCmd); |
821 | } | | | |
822 | } | | 831 | } |
823 | cmdTemplate = commandShell->errOffOrExecIgnore; | | 832 | cmdTemplate = commandShell->errOffOrExecIgnore; |
824 | /* | | 833 | /* |
825 | * The error ignoration (hee hee) is already taken care | | 834 | * The error ignoration (hee hee) is already taken care |
826 | * of by the errOffOrExecIgnore template, so pretend error | | 835 | * of by the errOffOrExecIgnore template, so pretend error |
827 | * checking is still on. | | 836 | * checking is still on. |
828 | */ | | 837 | */ |
829 | errOff = FALSE; | | 838 | errOff = FALSE; |
830 | } else { | | 839 | } else { |
831 | errOff = FALSE; | | 840 | errOff = FALSE; |
832 | } | | 841 | } |
833 | } else { | | 842 | } else { |
834 | errOff = FALSE; | | 843 | errOff = FALSE; |
835 | } | | 844 | } |
836 | } else { | | 845 | } else { |
837 | | | 846 | |
838 | /* | | 847 | /* |
839 | * If errors are being checked and the shell doesn't have error control | | 848 | * If errors are being checked and the shell doesn't have error control |
840 | * but does supply an errExit template, then setup commands to run | | 849 | * but does supply an errExit template, then setup commands to run |
841 | * through it. | | 850 | * through it. |
842 | */ | | 851 | */ |
843 | | | 852 | |
844 | if (!commandShell->hasErrCtl && commandShell->errExit && | | 853 | if (!commandShell->hasErrCtl && commandShell->errExit && |
845 | commandShell->errExit[0] != '\0') { | | 854 | commandShell->errExit[0] != '\0') { |
846 | if (!(job->flags & JOB_SILENT) && !shutUp) { | | 855 | if (!(job->flags & JOB_SILENT) && !shutUp) { |
847 | if (commandShell->hasEchoCtl) { | | 856 | if (commandShell->hasEchoCtl) |
848 | DBPRINTF("%s\n", commandShell->echoOff); | | 857 | JobPrintln(job, commandShell->echoOff); |
849 | } | | 858 | JobPrintf(job, commandShell->errOnOrEcho, escCmd); |
850 | DBPRINTF(commandShell->errOnOrEcho, escCmd); | | | |
851 | shutUp = TRUE; | | 859 | shutUp = TRUE; |
852 | } | | 860 | } |
853 | /* If it's a comment line or blank, treat as an ignored error */ | | 861 | /* If it's a comment line or blank, treat as an ignored error */ |
854 | if (escCmd[0] == commandShell->commentChar || | | 862 | if (escCmd[0] == commandShell->commentChar || |
855 | (escCmd[0] == '\0')) | | 863 | (escCmd[0] == '\0')) |
856 | cmdTemplate = commandShell->errOffOrExecIgnore; | | 864 | cmdTemplate = commandShell->errOffOrExecIgnore; |
857 | else | | 865 | else |
858 | cmdTemplate = commandShell->errExit; | | 866 | cmdTemplate = commandShell->errExit; |
859 | errOff = FALSE; | | 867 | errOff = FALSE; |
860 | } | | 868 | } |
861 | } | | 869 | } |
862 | | | 870 | |
863 | if (DEBUG(SHELL) && strcmp(shellName, "sh") == 0 && | | 871 | if (DEBUG(SHELL) && strcmp(shellName, "sh") == 0 && |
864 | !(job->flags & JOB_TRACED)) { | | 872 | !(job->flags & JOB_TRACED)) { |
865 | DBPRINTF("set -%s\n", "x"); | | 873 | JobPrintln(job, "set -x"); |
866 | job->flags |= JOB_TRACED; | | 874 | job->flags |= JOB_TRACED; |
867 | } | | 875 | } |
868 | | | 876 | |
869 | DBPRINTF(cmdTemplate, cmd); | | 877 | JobPrintf(job, cmdTemplate, cmd); |
870 | free(cmdStart); | | 878 | free(cmdStart); |
871 | free(escCmd); | | 879 | free(escCmd); |
872 | if (errOff) { | | 880 | if (errOff) { |
873 | /* | | 881 | /* |
874 | * If echoing is already off, there's no point in issuing the | | 882 | * If echoing is already off, there's no point in issuing the |
875 | * echoOff command. Otherwise we issue it and pretend it was on | | 883 | * echoOff command. Otherwise we issue it and pretend it was on |
876 | * for the whole command... | | 884 | * for the whole command... |
877 | */ | | 885 | */ |
878 | if (!shutUp && !(job->flags & JOB_SILENT) && commandShell->hasEchoCtl) { | | 886 | if (!shutUp && !(job->flags & JOB_SILENT) && commandShell->hasEchoCtl) { |
879 | DBPRINTF("%s\n", commandShell->echoOff); | | 887 | JobPrintln(job, commandShell->echoOff); |
880 | shutUp = TRUE; | | 888 | shutUp = TRUE; |
881 | } | | 889 | } |
882 | DBPRINTF("%s\n", commandShell->errOnOrEcho); | | 890 | JobPrintln(job, commandShell->errOnOrEcho); |
883 | } | | | |
884 | if (shutUp && commandShell->hasEchoCtl) { | | | |
885 | DBPRINTF("%s\n", commandShell->echoOn); | | | |
886 | } | | 891 | } |
| | | 892 | if (shutUp && commandShell->hasEchoCtl) |
| | | 893 | JobPrintln(job, commandShell->echoOn); |
887 | } | | 894 | } |
888 | | | 895 | |
889 | /* Print all commands to the shell file that is later executed. | | 896 | /* Print all commands to the shell file that is later executed. |
890 | * | | 897 | * |
891 | * The special command "..." stops printing and saves the remaining commands | | 898 | * The special command "..." stops printing and saves the remaining commands |
892 | * to be executed later. */ | | 899 | * to be executed later. */ |
893 | static void | | 900 | static void |
894 | JobPrintCommands(Job *job) | | 901 | JobPrintCommands(Job *job) |
895 | { | | 902 | { |
896 | StringListNode *ln; | | 903 | StringListNode *ln; |
897 | | | 904 | |
898 | for (ln = job->node->commands->first; ln != NULL; ln = ln->next) { | | 905 | for (ln = job->node->commands->first; ln != NULL; ln = ln->next) { |
899 | const char *cmd = ln->datum; | | 906 | const char *cmd = ln->datum; |