Sun Nov 1 17:07:03 2020 UTC ()
make(1): extract EscapeShellDblQuot from JobPrintCommand


(rillig)
diff -r1.298 -r1.299 src/usr.bin/make/job.c

cvs diff -r1.298 -r1.299 src/usr.bin/make/job.c (expand / switch to unified diff)

--- src/usr.bin/make/job.c 2020/11/01 16:57:02 1.298
+++ src/usr.bin/make/job.c 2020/11/01 17:07:03 1.299
@@ -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" */
146MAKE_RCSID("$NetBSD: job.c,v 1.298 2020/11/01 16:57:02 rillig Exp $"); 146MAKE_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. */
 678static char *
 679EscapeShellDblQuot(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) {