| @@ -1,14 +1,14 @@ | | | @@ -1,14 +1,14 @@ |
1 | /* $NetBSD: job.c,v 1.298 2020/11/01 16:57:02 rillig Exp $ */ | | 1 | /* $NetBSD: job.c,v 1.299 2020/11/01 17:07:03 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.298 2020/11/01 16:57:02 rillig Exp $"); | | 146 | MAKE_RCSID("$NetBSD: job.c,v 1.299 2020/11/01 17:07:03 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 |
| @@ -664,26 +664,44 @@ ParseRunOptions( | | | @@ -664,26 +664,44 @@ ParseRunOptions( |
664 | *out_errOff = TRUE; | | 664 | *out_errOff = TRUE; |
665 | else if (*p == '+') | | 665 | else if (*p == '+') |
666 | *out_runAlways = TRUE; | | 666 | *out_runAlways = TRUE; |
667 | else | | 667 | else |
668 | break; | | 668 | break; |
669 | p++; | | 669 | p++; |
670 | } | | 670 | } |
671 | | | 671 | |
672 | pp_skip_whitespace(&p); | | 672 | pp_skip_whitespace(&p); |
673 | | | 673 | |
674 | *pp = p; | | 674 | *pp = p; |
675 | } | | 675 | } |
676 | | | 676 | |
| | | 677 | /* Escape a string for a double-quoted string literal in sh, csh and ksh. */ |
| | | 678 | static char * |
| | | 679 | EscapeShellDblQuot(const char *cmd) |
| | | 680 | { |
| | | 681 | size_t i, j; |
| | | 682 | |
| | | 683 | /* Worst that could happen is every char needs escaping. */ |
| | | 684 | char *esc = bmake_malloc(strlen(cmd) * 2 + 1); |
| | | 685 | for (i = 0, j = 0; cmd[i] != '\0'; i++, j++) { |
| | | 686 | if (cmd[i] == '$' || cmd[i] == '`' || cmd[i] == '\\' || cmd[i] == '"') |
| | | 687 | esc[j++] = '\\'; |
| | | 688 | esc[j] = cmd[i]; |
| | | 689 | } |
| | | 690 | esc[j] = '\0'; |
| | | 691 | |
| | | 692 | return esc; |
| | | 693 | } |
| | | 694 | |
677 | /*- | | 695 | /*- |
678 | *----------------------------------------------------------------------- | | 696 | *----------------------------------------------------------------------- |
679 | * JobPrintCommand -- | | 697 | * JobPrintCommand -- |
680 | * Put out another command for the given job. If the command starts | | 698 | * Put out another command for the given job. If the command starts |
681 | * with an @ or a - we process it specially. In the former case, | | 699 | * with an @ or a - we process it specially. In the former case, |
682 | * so long as the -s and -n flags weren't given to make, we stick | | 700 | * so long as the -s and -n flags weren't given to make, we stick |
683 | * a shell-specific echoOff command in the script. In the latter, | | 701 | * a shell-specific echoOff command in the script. In the latter, |
684 | * we ignore errors for the entire job, unless the shell has error | | 702 | * we ignore errors for the entire job, unless the shell has error |
685 | * control. | | 703 | * control. |
686 | * If the command is just "..." we take all future commands for this | | 704 | * If the command is just "..." we take all future commands for this |
687 | * job to be commands to be executed once the entire graph has been | | 705 | * job to be commands to be executed once the entire graph has been |
688 | * made and return non-zero to signal that the end of the commands | | 706 | * made and return non-zero to signal that the end of the commands |
689 | * was reached. These commands are later attached to the postCommands | | 707 | * was reached. These commands are later attached to the postCommands |
| @@ -737,39 +755,28 @@ JobPrintCommand(Job *job, char *cmd) | | | @@ -737,39 +755,28 @@ JobPrintCommand(Job *job, char *cmd) |
737 | * but this one needs to be - use compat mode just for it. | | 755 | * but this one needs to be - use compat mode just for it. |
738 | */ | | 756 | */ |
739 | Compat_RunCommand(cmdp, job->node); | | 757 | Compat_RunCommand(cmdp, job->node); |
740 | free(cmdStart); | | 758 | free(cmdStart); |
741 | return; | | 759 | return; |
742 | } | | 760 | } |
743 | | | 761 | |
744 | /* | | 762 | /* |
745 | * If the shell doesn't have error control the alternate echo'ing will | | 763 | * If the shell doesn't have error control the alternate echo'ing will |
746 | * be done (to avoid showing additional error checking code) | | 764 | * be done (to avoid showing additional error checking code) |
747 | * and this will need the characters '$ ` \ "' escaped | | 765 | * and this will need the characters '$ ` \ "' escaped |
748 | */ | | 766 | */ |
749 | | | 767 | |
750 | if (!commandShell->hasErrCtl) { | | 768 | if (!commandShell->hasErrCtl) |
751 | int i, j; | | 769 | escCmd = EscapeShellDblQuot(cmd); |
752 | | | | |
753 | /* Worst that could happen is every char needs escaping. */ | | | |
754 | escCmd = bmake_malloc((strlen(cmd) * 2) + 1); | | | |
755 | for (i = 0, j = 0; cmd[i] != '\0'; i++, j++) { | | | |
756 | if (cmd[i] == '$' || cmd[i] == '`' || cmd[i] == '\\' || | | | |
757 | cmd[i] == '"') | | | |
758 | escCmd[j++] = '\\'; | | | |
759 | escCmd[j] = cmd[i]; | | | |
760 | } | | | |
761 | escCmd[j] = '\0'; | | | |
762 | } | | | |
763 | | | 770 | |
764 | if (shutUp) { | | 771 | if (shutUp) { |
765 | if (!(job->flags & JOB_SILENT) && !noSpecials && | | 772 | if (!(job->flags & JOB_SILENT) && !noSpecials && |
766 | commandShell->hasEchoCtl) { | | 773 | commandShell->hasEchoCtl) { |
767 | DBPRINTF("%s\n", commandShell->echoOff); | | 774 | DBPRINTF("%s\n", commandShell->echoOff); |
768 | } else { | | 775 | } else { |
769 | if (commandShell->hasErrCtl) | | 776 | if (commandShell->hasErrCtl) |
770 | shutUp = FALSE; | | 777 | shutUp = FALSE; |
771 | } | | 778 | } |
772 | } | | 779 | } |
773 | | | 780 | |
774 | if (errOff) { | | 781 | if (errOff) { |
775 | if (!noSpecials) { | | 782 | if (!noSpecials) { |