| @@ -1,14 +1,14 @@ | | | @@ -1,14 +1,14 @@ |
1 | /* $NetBSD: job.c,v 1.297 2020/10/31 11:54:33 rillig Exp $ */ | | 1 | /* $NetBSD: job.c,v 1.298 2020/11/01 16:57:02 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.297 2020/10/31 11:54:33 rillig Exp $"); | | 146 | MAKE_RCSID("$NetBSD: job.c,v 1.298 2020/11/01 16:57:02 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 |
| @@ -636,26 +636,54 @@ static Job * | | | @@ -636,26 +636,54 @@ static Job * |
636 | JobFindPid(int pid, JobState status, Boolean isJobs) | | 636 | JobFindPid(int pid, JobState status, Boolean isJobs) |
637 | { | | 637 | { |
638 | Job *job; | | 638 | Job *job; |
639 | | | 639 | |
640 | for (job = job_table; job < job_table_end; job++) { | | 640 | for (job = job_table; job < job_table_end; job++) { |
641 | if ((job->job_state == status) && job->pid == pid) | | 641 | if ((job->job_state == status) && job->pid == pid) |
642 | return job; | | 642 | return job; |
643 | } | | 643 | } |
644 | if (DEBUG(JOB) && isJobs) | | 644 | if (DEBUG(JOB) && isJobs) |
645 | job_table_dump("no pid"); | | 645 | job_table_dump("no pid"); |
646 | return NULL; | | 646 | return NULL; |
647 | } | | 647 | } |
648 | | | 648 | |
| | | 649 | /* Parse leading '@', '-' and '+', which control the exact execution mode. */ |
| | | 650 | static void |
| | | 651 | ParseRunOptions( |
| | | 652 | char **pp, |
| | | 653 | Boolean *out_shutUp, Boolean *out_errOff, Boolean *out_runAlways) |
| | | 654 | { |
| | | 655 | char *p = *pp; |
| | | 656 | *out_shutUp = FALSE; |
| | | 657 | *out_errOff = FALSE; |
| | | 658 | *out_runAlways = FALSE; |
| | | 659 | |
| | | 660 | for (;;) { |
| | | 661 | if (*p == '@') |
| | | 662 | *out_shutUp = !DEBUG(LOUD); |
| | | 663 | else if (*p == '-') |
| | | 664 | *out_errOff = TRUE; |
| | | 665 | else if (*p == '+') |
| | | 666 | *out_runAlways = TRUE; |
| | | 667 | else |
| | | 668 | break; |
| | | 669 | p++; |
| | | 670 | } |
| | | 671 | |
| | | 672 | pp_skip_whitespace(&p); |
| | | 673 | |
| | | 674 | *pp = p; |
| | | 675 | } |
| | | 676 | |
649 | /*- | | 677 | /*- |
650 | *----------------------------------------------------------------------- | | 678 | *----------------------------------------------------------------------- |
651 | * JobPrintCommand -- | | 679 | * JobPrintCommand -- |
652 | * Put out another command for the given job. If the command starts | | 680 | * Put out another command for the given job. If the command starts |
653 | * with an @ or a - we process it specially. In the former case, | | 681 | * with an @ or a - we process it specially. In the former case, |
654 | * so long as the -s and -n flags weren't given to make, we stick | | 682 | * so long as the -s and -n flags weren't given to make, we stick |
655 | * a shell-specific echoOff command in the script. In the latter, | | 683 | * a shell-specific echoOff command in the script. In the latter, |
656 | * we ignore errors for the entire job, unless the shell has error | | 684 | * we ignore errors for the entire job, unless the shell has error |
657 | * control. | | 685 | * control. |
658 | * If the command is just "..." we take all future commands for this | | 686 | * If the command is just "..." we take all future commands for this |
659 | * job to be commands to be executed once the entire graph has been | | 687 | * job to be commands to be executed once the entire graph has been |
660 | * made and return non-zero to signal that the end of the commands | | 688 | * made and return non-zero to signal that the end of the commands |
661 | * was reached. These commands are later attached to the postCommands | | 689 | * was reached. These commands are later attached to the postCommands |
| @@ -664,79 +692,64 @@ JobFindPid(int pid, JobState status, Boo | | | @@ -664,79 +692,64 @@ JobFindPid(int pid, JobState status, Boo |
664 | * Side Effects: | | 692 | * Side Effects: |
665 | * If the command begins with a '-' and the shell has no error control, | | 693 | * If the command begins with a '-' and the shell has no error control, |
666 | * the JOB_IGNERR flag is set in the job descriptor. | | 694 | * the JOB_IGNERR flag is set in the job descriptor. |
667 | * numCommands is incremented if the command is actually printed. | | 695 | * numCommands is incremented if the command is actually printed. |
668 | *----------------------------------------------------------------------- | | 696 | *----------------------------------------------------------------------- |
669 | */ | | 697 | */ |
670 | static void | | 698 | static void |
671 | JobPrintCommand(Job *job, char *cmd) | | 699 | JobPrintCommand(Job *job, char *cmd) |
672 | { | | 700 | { |
673 | const char *const cmdp = cmd; | | 701 | const char *const cmdp = cmd; |
674 | Boolean noSpecials; /* true if we shouldn't worry about | | 702 | Boolean noSpecials; /* true if we shouldn't worry about |
675 | * inserting special commands into | | 703 | * inserting special commands into |
676 | * the input stream. */ | | 704 | * the input stream. */ |
677 | Boolean shutUp = FALSE; /* true if we put a no echo command | | 705 | Boolean shutUp; /* true if we put a no echo command |
678 | * into the command file */ | | 706 | * into the command file */ |
679 | Boolean errOff = FALSE; /* true if we turned error checking | | 707 | Boolean errOff; /* true if we turned error checking |
680 | * off before printing the command | | 708 | * off before printing the command |
681 | * and need to turn it back on */ | | 709 | * and need to turn it back on */ |
| | | 710 | Boolean runAlways; |
682 | const char *cmdTemplate; /* Template to use when printing the | | 711 | const char *cmdTemplate; /* Template to use when printing the |
683 | * command */ | | 712 | * command */ |
684 | char *cmdStart; /* Start of expanded command */ | | 713 | char *cmdStart; /* Start of expanded command */ |
685 | char *escCmd = NULL; /* Command with quotes/backticks escaped */ | | 714 | char *escCmd = NULL; /* Command with quotes/backticks escaped */ |
686 | | | 715 | |
687 | noSpecials = NoExecute(job->node); | | 716 | noSpecials = NoExecute(job->node); |
688 | | | 717 | |
689 | #define DBPRINTF(fmt, arg) if (DEBUG(JOB)) { \ | | 718 | #define DBPRINTF(fmt, arg) if (DEBUG(JOB)) { \ |
690 | debug_printf(fmt, arg); \ | | 719 | debug_printf(fmt, arg); \ |
691 | } \ | | 720 | } \ |
692 | (void)fprintf(job->cmdFILE, fmt, arg); \ | | 721 | (void)fprintf(job->cmdFILE, fmt, arg); \ |
693 | (void)fflush(job->cmdFILE); | | 722 | (void)fflush(job->cmdFILE); |
694 | | | 723 | |
695 | numCommands++; | | 724 | numCommands++; |
696 | | | 725 | |
697 | Var_Subst(cmd, job->node, VARE_WANTRES, &cmd); | | 726 | Var_Subst(cmd, job->node, VARE_WANTRES, &cmd); |
698 | /* TODO: handle errors */ | | 727 | /* TODO: handle errors */ |
699 | cmdStart = cmd; | | 728 | cmdStart = cmd; |
700 | | | 729 | |
701 | cmdTemplate = "%s\n"; | | 730 | cmdTemplate = "%s\n"; |
702 | | | 731 | |
703 | /* | | 732 | ParseRunOptions(&cmd, &shutUp, &errOff, &runAlways); |
704 | * Check for leading @' and -'s to control echoing and error checking. | | | |
705 | */ | | | |
706 | while (*cmd == '@' || *cmd == '-' || (*cmd == '+')) { | | | |
707 | switch (*cmd) { | | | |
708 | case '@': | | | |
709 | shutUp = DEBUG(LOUD) ? FALSE : TRUE; | | | |
710 | break; | | | |
711 | case '-': | | | |
712 | errOff = TRUE; | | | |
713 | break; | | | |
714 | case '+': | | | |
715 | if (noSpecials) { | | | |
716 | /* | | | |
717 | * We're not actually executing anything... | | | |
718 | * but this one needs to be - use compat mode just for it. | | | |
719 | */ | | | |
720 | Compat_RunCommand(cmdp, job->node); | | | |
721 | free(cmdStart); | | | |
722 | return; | | | |
723 | } | | | |
724 | break; | | | |
725 | } | | | |
726 | cmd++; | | | |
727 | } | | | |
728 | | | 733 | |
729 | pp_skip_whitespace(&cmd); | | 734 | if (runAlways && noSpecials) { |
| | | 735 | /* |
| | | 736 | * We're not actually executing anything... |
| | | 737 | * but this one needs to be - use compat mode just for it. |
| | | 738 | */ |
| | | 739 | Compat_RunCommand(cmdp, job->node); |
| | | 740 | free(cmdStart); |
| | | 741 | return; |
| | | 742 | } |
730 | | | 743 | |
731 | /* | | 744 | /* |
732 | * If the shell doesn't have error control the alternate echo'ing will | | 745 | * If the shell doesn't have error control the alternate echo'ing will |
733 | * be done (to avoid showing additional error checking code) | | 746 | * be done (to avoid showing additional error checking code) |
734 | * and this will need the characters '$ ` \ "' escaped | | 747 | * and this will need the characters '$ ` \ "' escaped |
735 | */ | | 748 | */ |
736 | | | 749 | |
737 | if (!commandShell->hasErrCtl) { | | 750 | if (!commandShell->hasErrCtl) { |
738 | int i, j; | | 751 | int i, j; |
739 | | | 752 | |
740 | /* Worst that could happen is every char needs escaping. */ | | 753 | /* Worst that could happen is every char needs escaping. */ |
741 | escCmd = bmake_malloc((strlen(cmd) * 2) + 1); | | 754 | escCmd = bmake_malloc((strlen(cmd) * 2) + 1); |
742 | for (i = 0, j = 0; cmd[i] != '\0'; i++, j++) { | | 755 | for (i = 0, j = 0; cmd[i] != '\0'; i++, j++) { |