Date: Thu, 14 Jan 2021 06:22:16 GMT From: "Simon J. Gerraty" <sjg@FreeBSD.org> To: src-committers@FreeBSD.org, dev-commits-src-all@FreeBSD.org, dev-commits-src-main@FreeBSD.org Subject: git: 06b9b3e0ad0d - main - Merge bmake-20210110 Message-ID: <202101140622.10E6MGAx018193@gitrepo.freebsd.org>
next in thread | raw e-mail | index | archive | help
The branch main has been updated by sjg: URL: https://cgit.FreeBSD.org/src/commit/?id=06b9b3e0ad0dc3f0166b3e8f26ced68c271cf527 commit 06b9b3e0ad0dc3f0166b3e8f26ced68c271cf527 Merge: 0495ed398c4f 8e11a9b4250b Author: Simon J. Gerraty <sjg@FreeBSD.org> AuthorDate: 2021-01-14 06:21:37 +0000 Commit: Simon J. Gerraty <sjg@FreeBSD.org> CommitDate: 2021-01-14 06:21:37 +0000 Merge bmake-20210110 Quite a lot of churn on style, but lots of good work refactoring complicated functions and lots more unit-tests. Thanks mostly to rillig at NetBSD Some interesting entries from ChangeLog o .MAKE.{UID,GID} represent uid and gid running make. o allow env var MAKE_OBJDIR_CHECK_WRITABLE=no to skip writable checks in InitObjdir. Explicit .OBJDIR target always allows read-only directory. o add more unit tests for META MODE Merge commit '8e11a9b4250be3c3379c45fa820bff78d99d5946' into main Change-Id: I464fd4c013067f0915671c1ccc96d2d8090b2b9c contrib/bmake/ChangeLog | 241 +- contrib/bmake/FILES | 64 +- contrib/bmake/LICENSE | 4 +- contrib/bmake/PSD.doc/tutorial.ms | 10 +- contrib/bmake/VERSION | 2 +- contrib/bmake/arch.c | 1323 ++--- contrib/bmake/bmake.1 | 18 +- contrib/bmake/bmake.cat1 | 248 +- contrib/bmake/buf.c | 139 +- contrib/bmake/buf.h | 28 +- contrib/bmake/compat.c | 932 +-- contrib/bmake/cond.c | 1611 +++--- contrib/bmake/dir.c | 2047 ++++--- contrib/bmake/dir.h | 36 +- contrib/bmake/enum.c | 11 +- contrib/bmake/enum.h | 69 +- contrib/bmake/filemon/filemon.h | 6 +- contrib/bmake/filemon/filemon_dev.c | 6 +- contrib/bmake/filemon/filemon_ktrace.c | 79 +- contrib/bmake/for.c | 633 +- contrib/bmake/hash.c | 41 +- contrib/bmake/hash.h | 72 +- contrib/bmake/import.sh | 87 + contrib/bmake/job.c | 3893 +++++++------ contrib/bmake/job.h | 84 +- contrib/bmake/lst.c | 304 +- contrib/bmake/lst.h | 88 +- contrib/bmake/main.c | 364 +- contrib/bmake/make-conf.h | 20 +- contrib/bmake/make.1 | 18 +- contrib/bmake/make.c | 1825 +++--- contrib/bmake/make.h | 812 +-- contrib/bmake/make_malloc.c | 7 +- contrib/bmake/make_malloc.h | 12 +- contrib/bmake/meta.c | 359 +- contrib/bmake/meta.h | 4 +- contrib/bmake/metachar.h | 4 +- contrib/bmake/mk/ChangeLog | 39 + contrib/bmake/mk/dirdeps-options.mk | 5 +- contrib/bmake/mk/dirdeps-targets.mk | 7 +- contrib/bmake/mk/dirdeps.mk | 25 +- contrib/bmake/mk/init.mk | 17 +- contrib/bmake/mk/install-mk | 4 +- contrib/bmake/mk/meta.subdir.mk | 4 +- contrib/bmake/mk/mkopt.sh | 0 contrib/bmake/mk/own.mk | 6 +- contrib/bmake/mk/sys.mk | 6 +- contrib/bmake/nonints.h | 278 +- contrib/bmake/os.sh | 0 contrib/bmake/parse.c | 4058 ++++++------- contrib/bmake/pathnames.h | 15 +- contrib/bmake/str.c | 15 +- contrib/bmake/suff.c | 2897 +++++----- contrib/bmake/targ.c | 568 +- contrib/bmake/trace.c | 16 +- contrib/bmake/trace.h | 6 +- contrib/bmake/unit-tests/Makefile | 159 +- contrib/bmake/unit-tests/cmd-errors-jobs.exp | 9 + contrib/bmake/unit-tests/cmd-errors-jobs.mk | 32 + contrib/bmake/unit-tests/cmd-errors.mk | 4 +- contrib/bmake/unit-tests/cmdline.mk | 2 +- contrib/bmake/unit-tests/compat-error.exp | 15 + contrib/bmake/unit-tests/compat-error.mk | 37 + contrib/bmake/unit-tests/cond-eof.exp | 9 + contrib/bmake/unit-tests/cond-eof.mk | 20 + contrib/bmake/unit-tests/cond-func-empty.mk | 27 +- contrib/bmake/unit-tests/cond-func-exists.mk | 11 +- contrib/bmake/unit-tests/cond-func-make-main.exp | 3 + contrib/bmake/unit-tests/cond-func-make-main.mk | 62 + contrib/bmake/unit-tests/cond-short.exp | 12 +- contrib/bmake/unit-tests/cond-short.mk | 64 +- contrib/bmake/unit-tests/cond-token-string.exp | 2 +- contrib/bmake/unit-tests/dep-percent.exp | 5 +- contrib/bmake/unit-tests/depsrc-meta.exp | 4 + contrib/bmake/unit-tests/depsrc-meta.mk | 27 +- contrib/bmake/unit-tests/depsrc-optional.exp | 18 +- contrib/bmake/unit-tests/depsrc.exp | 3 + contrib/bmake/unit-tests/depsrc.mk | 17 +- .../unit-tests/deptgt-begin-fail-indirect.exp | 6 + .../bmake/unit-tests/deptgt-begin-fail-indirect.mk | 16 + contrib/bmake/unit-tests/deptgt-begin-fail.exp | 6 + contrib/bmake/unit-tests/deptgt-begin-fail.mk | 10 + contrib/bmake/unit-tests/deptgt-end-fail-all.exp | 7 + contrib/bmake/unit-tests/deptgt-end-fail-all.mk | 19 + .../bmake/unit-tests/deptgt-end-fail-indirect.exp | 7 + .../bmake/unit-tests/deptgt-end-fail-indirect.mk | 16 + contrib/bmake/unit-tests/deptgt-end-fail.exp | 163 + contrib/bmake/unit-tests/deptgt-end-fail.mk | 69 + contrib/bmake/unit-tests/deptgt-suffixes.exp | 26 + contrib/bmake/unit-tests/deptgt-suffixes.mk | 23 +- contrib/bmake/unit-tests/deptgt.exp | 1 + contrib/bmake/unit-tests/deptgt.mk | 10 +- contrib/bmake/unit-tests/directive-elif.exp | 32 +- contrib/bmake/unit-tests/directive-elif.mk | 126 +- contrib/bmake/unit-tests/directive-else.exp | 16 +- contrib/bmake/unit-tests/directive-else.mk | 15 +- contrib/bmake/unit-tests/directive-endfor.exp | 4 + contrib/bmake/unit-tests/directive-endfor.mk | 9 + contrib/bmake/unit-tests/directive-endif.exp | 9 +- contrib/bmake/unit-tests/directive-endif.mk | 28 +- contrib/bmake/unit-tests/directive-error.mk | 6 +- contrib/bmake/unit-tests/directive-export-env.mk | 4 +- contrib/bmake/unit-tests/directive-export-impl.exp | 56 + contrib/bmake/unit-tests/directive-export-impl.mk | 62 + .../bmake/unit-tests/directive-export-literal.mk | 4 +- contrib/bmake/unit-tests/directive-export.exp | 5 +- contrib/bmake/unit-tests/directive-export.mk | 16 +- contrib/bmake/unit-tests/directive-for-errors.exp | 22 + contrib/bmake/unit-tests/directive-for-errors.mk | 75 + contrib/bmake/unit-tests/directive-for-escape.exp | 74 + contrib/bmake/unit-tests/directive-for-escape.mk | 96 + contrib/bmake/unit-tests/directive-for-lines.exp | 10 + contrib/bmake/unit-tests/directive-for-lines.mk | 32 + contrib/bmake/unit-tests/directive-for-null.exp | 10 + contrib/bmake/unit-tests/directive-for-null.mk | 19 + contrib/bmake/unit-tests/directive-for.exp | 7 +- contrib/bmake/unit-tests/directive-for.mk | 9 +- contrib/bmake/unit-tests/directive-if.exp | 6 +- contrib/bmake/unit-tests/directive-if.mk | 14 +- contrib/bmake/unit-tests/directive-include.mk | 5 +- contrib/bmake/unit-tests/directive-info.exp | 23 +- contrib/bmake/unit-tests/directive-info.mk | 18 +- .../bmake/unit-tests/directive-misspellings.exp | 45 + contrib/bmake/unit-tests/directive-misspellings.mk | 79 + contrib/bmake/unit-tests/directive-undef.exp | 3 +- contrib/bmake/unit-tests/directive-undef.mk | 85 +- .../bmake/unit-tests/directive-unexport-env.exp | 19 +- contrib/bmake/unit-tests/directive-unexport-env.mk | 19 +- contrib/bmake/unit-tests/directive-unexport.exp | 13 +- contrib/bmake/unit-tests/directive-unexport.mk | 12 +- contrib/bmake/unit-tests/directive-warning.exp | 16 +- contrib/bmake/unit-tests/directive-warning.mk | 10 +- contrib/bmake/unit-tests/jobs-error-indirect.exp | 8 + contrib/bmake/unit-tests/jobs-error-indirect.mk | 21 + .../bmake/unit-tests/jobs-error-nested-make.exp | 11 + contrib/bmake/unit-tests/jobs-error-nested-make.mk | 20 + contrib/bmake/unit-tests/jobs-error-nested.exp | 15 + contrib/bmake/unit-tests/jobs-error-nested.mk | 20 + contrib/bmake/unit-tests/make-exported.mk | 2 +- contrib/bmake/unit-tests/meta-cmd-cmp.exp | 37 + contrib/bmake/unit-tests/meta-cmd-cmp.mk | 52 + contrib/bmake/unit-tests/modmisc.exp | 1 - contrib/bmake/unit-tests/modmisc.mk | 29 +- contrib/bmake/unit-tests/opt-chdir.exp | 4 +- contrib/bmake/unit-tests/opt-debug-errors.exp | 5 +- contrib/bmake/unit-tests/opt-debug-graph1.exp | 36 + contrib/bmake/unit-tests/opt-debug-jobs.exp | 4 +- contrib/bmake/unit-tests/opt-debug-lint.exp | 3 +- contrib/bmake/unit-tests/opt-debug-lint.mk | 15 +- contrib/bmake/unit-tests/opt-file.exp | 13 +- contrib/bmake/unit-tests/opt-file.mk | 101 +- contrib/bmake/unit-tests/opt-jobs-no-action.exp | 61 + contrib/bmake/unit-tests/opt-jobs-no-action.mk | 102 + .../bmake/unit-tests/opt-keep-going-multiple.exp | 9 + .../bmake/unit-tests/opt-keep-going-multiple.mk | 21 + contrib/bmake/unit-tests/opt-keep-going.exp | 5 +- contrib/bmake/unit-tests/opt-keep-going.mk | 6 +- .../bmake/unit-tests/opt-no-action-runflags.exp | 34 + contrib/bmake/unit-tests/opt-no-action-runflags.mk | 32 + contrib/bmake/unit-tests/opt.exp | 4 + contrib/bmake/unit-tests/posix.exp | 5 +- contrib/bmake/unit-tests/qequals.exp | 2 - contrib/bmake/unit-tests/qequals.mk | 8 - contrib/bmake/unit-tests/sh-dots.exp | 12 +- contrib/bmake/unit-tests/sh-errctl.exp | 27 + contrib/bmake/unit-tests/sh-errctl.mk | 26 + contrib/bmake/unit-tests/sh-flags.exp | 4325 ++++++++++++++ contrib/bmake/unit-tests/sh-flags.mk | 138 + contrib/bmake/unit-tests/sh-jobs.exp | 7 +- contrib/bmake/unit-tests/sh-jobs.mk | 34 +- contrib/bmake/unit-tests/sh-meta-chars.mk | 17 +- contrib/bmake/unit-tests/shell-csh.mk | 6 +- contrib/bmake/unit-tests/suff-add-later.exp | 8 +- contrib/bmake/unit-tests/suff-clear-regular.exp | 5 +- contrib/bmake/unit-tests/suff-clear-regular.mk | 3 +- contrib/bmake/unit-tests/suff-clear-single.exp | 5 +- contrib/bmake/unit-tests/suff-incomplete.exp | 42 + contrib/bmake/unit-tests/suff-incomplete.mk | 31 + contrib/bmake/unit-tests/suff-lookup.exp | 21 +- contrib/bmake/unit-tests/suff-main-several.exp | 141 + contrib/bmake/unit-tests/suff-main-several.mk | 42 + contrib/bmake/unit-tests/suff-phony.exp | 13 + contrib/bmake/unit-tests/suff-phony.mk | 21 + contrib/bmake/unit-tests/suff-rebuild.exp | 76 +- contrib/bmake/unit-tests/suff-rebuild.mk | 23 +- contrib/bmake/unit-tests/suff-self.exp | 5 +- contrib/bmake/unit-tests/suff-transform-debug.exp | 62 + contrib/bmake/unit-tests/suff-transform-debug.mk | 12 + .../bmake/unit-tests/suff-transform-endless.exp | 44 +- contrib/bmake/unit-tests/suff-transform-endless.mk | 9 +- contrib/bmake/unit-tests/suff-transform-expand.exp | 5 +- contrib/bmake/unit-tests/suff-transform-select.exp | 45 +- contrib/bmake/unit-tests/suff-transform-select.mk | 7 +- contrib/bmake/unit-tests/use-inference.exp | 5 +- contrib/bmake/unit-tests/use-inference.mk | 6 +- contrib/bmake/unit-tests/var-op-default.mk | 72 +- contrib/bmake/unit-tests/var-op-expand.exp | 9 - contrib/bmake/unit-tests/var-op-expand.mk | 191 +- contrib/bmake/unit-tests/vardebug.exp | 2 +- contrib/bmake/unit-tests/varmisc.mk | 14 +- contrib/bmake/unit-tests/varmod-defined.exp | 18 +- contrib/bmake/unit-tests/varmod-edge.exp | 41 +- contrib/bmake/unit-tests/varmod-extension.exp | 1 + contrib/bmake/unit-tests/varmod-extension.mk | 4 +- contrib/bmake/unit-tests/varmod-gmtime.exp | 40 +- contrib/bmake/unit-tests/varmod-gmtime.mk | 197 +- contrib/bmake/unit-tests/varmod-head.exp | 1 + contrib/bmake/unit-tests/varmod-head.mk | 4 +- contrib/bmake/unit-tests/varmod-ifelse.exp | 4 + contrib/bmake/unit-tests/varmod-ifelse.mk | 20 +- contrib/bmake/unit-tests/varmod-indirect.exp | 59 + contrib/bmake/unit-tests/varmod-indirect.mk | 157 + contrib/bmake/unit-tests/varmod-localtime.exp | 40 +- contrib/bmake/unit-tests/varmod-localtime.mk | 196 +- contrib/bmake/unit-tests/varmod-range.exp | 9 +- contrib/bmake/unit-tests/varmod-root.exp | 1 + contrib/bmake/unit-tests/varmod-root.mk | 4 +- contrib/bmake/unit-tests/varmod-subst-regex.exp | 2 + contrib/bmake/unit-tests/varmod-subst-regex.mk | 7 +- contrib/bmake/unit-tests/varmod-sysv.exp | 4 +- contrib/bmake/unit-tests/varmod-sysv.mk | 16 +- contrib/bmake/unit-tests/varmod-tail.exp | 1 + contrib/bmake/unit-tests/varmod-tail.mk | 4 +- contrib/bmake/unit-tests/varmod-to-many-words.mk | 16 +- contrib/bmake/unit-tests/varmod-to-one-word.mk | 16 +- contrib/bmake/unit-tests/varmod-to-separator.exp | 2 - contrib/bmake/unit-tests/varmod.exp | 2 +- contrib/bmake/unit-tests/varmod.mk | 4 +- contrib/bmake/unit-tests/varname-dot-makeflags.exp | 3 + contrib/bmake/unit-tests/varname-dot-makeflags.mk | 15 + contrib/bmake/unit-tests/varname-dot-shell.exp | 2 +- .../varname-make_print_var_on_error-jobs.exp | 5 +- .../varname-make_print_var_on_error-jobs.mk | 15 +- .../unit-tests/varname-make_print_var_on_error.exp | 3 +- .../unit-tests/varname-make_print_var_on_error.mk | 15 +- contrib/bmake/unit-tests/varname-makeflags.mk | 24 +- contrib/bmake/unit-tests/varparse-dynamic.mk | 12 +- contrib/bmake/unit-tests/varparse-errors.exp | 6 +- contrib/bmake/unit-tests/varparse-errors.mk | 18 +- contrib/bmake/util.c | 91 +- contrib/bmake/var.c | 6056 ++++++++++---------- usr.bin/bmake/Makefile.config | 2 +- usr.bin/bmake/unit-tests/Makefile | 159 +- 243 files changed, 24413 insertions(+), 14581 deletions(-) diff --cc contrib/bmake/import.sh index 000000000000,d4554a078951..d4554a078951 mode 000000,100755..100755 --- a/contrib/bmake/import.sh +++ b/contrib/bmake/import.sh diff --cc contrib/bmake/job.c index 052b9290f9f3,000000000000..d43761ca80ff mode 100644,000000..100644 --- a/contrib/bmake/job.c +++ b/contrib/bmake/job.c @@@ -1,2853 -1,0 +1,3016 @@@ - /* $NetBSD: job.c,v 1.326 2020/11/16 18:28:27 rillig Exp $ */ ++/* $NetBSD: job.c,v 1.397 2021/01/10 23:59:53 rillig Exp $ */ + +/* + * Copyright (c) 1988, 1989, 1990 The Regents of the University of California. + * All rights reserved. + * + * This code is derived from software contributed to Berkeley by + * Adam de Boor. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of the University nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +/* + * Copyright (c) 1988, 1989 by Adam de Boor + * Copyright (c) 1989 by Berkeley Softworks + * All rights reserved. + * + * This code is derived from software contributed to Berkeley by + * Adam de Boor. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * This product includes software developed by the University of + * California, Berkeley and its contributors. + * 4. Neither the name of the University nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +/*- + * job.c -- + * handle the creation etc. of our child processes. + * + * Interface: + * Job_Init Called to initialize this module. In addition, + * any commands attached to the .BEGIN target + * are executed before this function returns. + * Hence, the makefiles must have been parsed + * before this function is called. + * + * Job_End Clean up any memory used. + * + * Job_Make Start the creation of the given target. + * + * Job_CatchChildren + * Check for and handle the termination of any + * children. This must be called reasonably + * frequently to keep the whole make going at + * a decent clip, since job table entries aren't + * removed until their process is caught this way. + * + * Job_CatchOutput + * Print any output our children have produced. + * Should also be called fairly frequently to + * keep the user informed of what's going on. + * If no output is waiting, it will block for + * a time given by the SEL_* constants, below, + * or until output is ready. + * + * Job_ParseShell Given the line following a .SHELL target, parse + * the line as a shell specification. Returns + * FALSE if the spec was incorrect. + * + * Job_Finish Perform any final processing which needs doing. + * This includes the execution of any commands + * which have been/were attached to the .END + * target. It should only be called when the + * job table is empty. + * + * Job_AbortAll Abort all currently running jobs. It doesn't + * handle output or do anything for the jobs, + * just kills them. It should only be called in + * an emergency. + * + * Job_CheckCommands + * Verify that the commands for a target are + * ok. Provide them if necessary and possible. + * + * Job_Touch Update a target without really updating it. + * + * Job_Wait Wait for all currently-running jobs to finish. + */ + +#ifdef HAVE_CONFIG_H +# include "config.h" +#endif +#include <sys/types.h> +#include <sys/stat.h> +#include <sys/file.h> +#include <sys/time.h> +#include "wait.h" + +#include <errno.h> +#if !defined(USE_SELECT) && defined(HAVE_POLL_H) +#include <poll.h> +#else +#ifndef USE_SELECT /* no poll.h */ +# define USE_SELECT +#endif +#if defined(HAVE_SYS_SELECT_H) +# include <sys/select.h> +#endif +#endif +#include <signal.h> +#include <utime.h> +#if defined(HAVE_SYS_SOCKET_H) +# include <sys/socket.h> +#endif + +#include "make.h" +#include "dir.h" +#include "job.h" +#include "pathnames.h" +#include "trace.h" + +/* "@(#)job.c 8.2 (Berkeley) 3/19/94" */ - MAKE_RCSID("$NetBSD: job.c,v 1.326 2020/11/16 18:28:27 rillig Exp $"); ++MAKE_RCSID("$NetBSD: job.c,v 1.397 2021/01/10 23:59:53 rillig Exp $"); + - /* A shell defines how the commands are run. All commands for a target are ++/* ++ * A shell defines how the commands are run. All commands for a target are + * written into a single file, which is then given to the shell to execute + * the commands from it. The commands are written to the file using a few + * templates for echo control and error control. + * + * The name of the shell is the basename for the predefined shells, such as + * "sh", "csh", "bash". For custom shells, it is the full pathname, and its + * basename is used to select the type of shell; the longest match wins. + * So /usr/pkg/bin/bash has type sh, /usr/local/bin/tcsh has type csh. + * + * The echoing of command lines is controlled using hasEchoCtl, echoOff, + * echoOn, noPrint and noPrintLen. When echoOff is executed by the shell, it + * still outputs something, but this something is not interesting, therefore + * it is filtered out using noPrint and noPrintLen. + * + * The error checking for individual commands is controlled using hasErrCtl, - * errOnOrEcho, errOffOrExecIgnore and errExit. ++ * errOn, errOff and runChkTmpl. + * - * If a shell doesn't have error control, errOnOrEcho becomes a printf template - * for echoing the command, should echoing be on; errOffOrExecIgnore becomes ++ * If a shell doesn't have error control, echoTmpl becomes a printf template ++ * for echoing the command, should echoing be on; runIgnTmpl becomes + * another printf template for executing the command while ignoring the return - * status. Finally errExit is a printf template for running the command and ++ * status. Finally runChkTmpl is a printf template for running the command and + * causing the shell to exit on error. If any of these strings are empty when + * hasErrCtl is FALSE, the command will be executed anyway as is, and if it + * causes an error, so be it. Any templates set up to echo the command will + * escape any '$ ` \ "' characters in the command string to avoid common + * problems with echo "%s\n" as a template. + * + * The command-line flags "echo" and "exit" also control the behavior. The + * "echo" flag causes the shell to start echoing commands right away. The + * "exit" flag causes the shell to exit when an error is detected in one of + * the commands. + */ +typedef struct Shell { + - /* The name of the shell. For Bourne and C shells, this is used only to - * find the shell description when used as the single source of a .SHELL - * target. For user-defined shells, this is the full path of the shell. */ - const char *name; ++ /* ++ * The name of the shell. For Bourne and C shells, this is used only ++ * to find the shell description when used as the single source of a ++ * .SHELL target. For user-defined shells, this is the full path of ++ * the shell. ++ */ ++ const char *name; + - Boolean hasEchoCtl; /* True if both echoOff and echoOn defined */ - const char *echoOff; /* command to turn off echo */ - const char *echoOn; /* command to turn it back on again */ - const char *noPrint; /* text to skip when printing output from ++ Boolean hasEchoCtl; /* whether both echoOff and echoOn are there */ ++ const char *echoOff; /* command to turn echoing off */ ++ const char *echoOn; /* command to turn echoing back on */ ++ const char *noPrint; /* text to skip when printing output from the + * shell. This is usually the same as echoOff */ - size_t noPrintLen; /* length of noPrint command */ ++ size_t noPrintLen; /* length of noPrint command */ ++ ++ Boolean hasErrCtl; /* whether error checking can be controlled ++ * for individual commands */ ++ const char *errOn; /* command to turn on error checking */ ++ const char *errOff; /* command to turn off error checking */ ++ ++ const char *echoTmpl; /* template to echo a command */ ++ const char *runIgnTmpl; /* template to run a command ++ * without error checking */ ++ const char *runChkTmpl; /* template to run a command ++ * with error checking */ ++ ++ /* string literal that results in a newline character when it appears ++ * outside of any 'quote' or "quote" characters */ ++ const char *newline; ++ char commentChar; /* character used by shell for comment lines */ ++ ++ const char *echoFlag; /* shell flag to echo commands */ ++ const char *errFlag; /* shell flag to exit on error */ ++} Shell; + - Boolean hasErrCtl; /* set if can control error checking for - * individual commands */ - /* XXX: split into errOn and echoCmd */ - const char *errOnOrEcho; /* template to turn on error checking */ - /* XXX: split into errOff and execIgnore */ - const char *errOffOrExecIgnore; /* template to turn off error checking */ - const char *errExit; /* template to use for testing exit code */ ++typedef struct CommandFlags { ++ /* Whether to echo the command before running it. */ ++ Boolean echo; + - /* string literal that results in a newline character when it appears - * outside of any 'quote' or "quote" characters */ - const char *newline; - char commentChar; /* character used by shell for comment lines */ ++ /* Run the command even in -n or -N mode. */ ++ Boolean always; + - /* - * command-line flags - */ - const char *echo; /* echo commands */ - const char *exit; /* exit on error */ - } Shell; ++ /* ++ * true if we turned error checking off before printing the command ++ * and need to turn it back on ++ */ ++ Boolean ignerr; ++} CommandFlags; ++ ++/* ++ * Write shell commands to a file. ++ * ++ * TODO: keep track of whether commands are echoed. ++ * TODO: keep track of whether error checking is active. ++ */ ++typedef struct ShellWriter { ++ FILE *f; ++ ++ /* we've sent 'set -x' */ ++ Boolean xtraced; ++ ++} ShellWriter; + +/* + * FreeBSD: traditionally .MAKE is not required to + * pass jobs queue to sub-makes. + * Use .MAKE.ALWAYS_PASS_JOB_QUEUE=no to disable. + */ +#define MAKE_ALWAYS_PASS_JOB_QUEUE ".MAKE.ALWAYS_PASS_JOB_QUEUE" +static int Always_pass_job_queue = TRUE; +/* + * FreeBSD: aborting entire parallel make isn't always + * desired. When doing tinderbox for example, failure of + * one architecture should not stop all. + * We still want to bail on interrupt though. + */ +#define MAKE_JOB_ERROR_TOKEN "MAKE_JOB_ERROR_TOKEN" +static int Job_error_token = TRUE; + +/* + * error handling variables + */ - static int errors = 0; /* number of errors reported */ ++static int job_errors = 0; /* number of errors reported */ +typedef enum AbortReason { /* why is the make aborting? */ - ABORT_NONE, - ABORT_ERROR, /* Because of an error */ - ABORT_INTERRUPT, /* Because it was interrupted */ - ABORT_WAIT /* Waiting for jobs to finish */ ++ ABORT_NONE, ++ ABORT_ERROR, /* Because of an error */ ++ ABORT_INTERRUPT, /* Because it was interrupted */ ++ ABORT_WAIT /* Waiting for jobs to finish */ +} AbortReason; +static AbortReason aborting = ABORT_NONE; - #define JOB_TOKENS "+EI+" /* Token to requeue for each abort state */ ++#define JOB_TOKENS "+EI+" /* Token to requeue for each abort state */ + +/* + * this tracks the number of tokens currently "out" to build jobs. + */ +int jobTokensRunning = 0; + - /* The number of commands actually printed to the shell commands file for - * the current job. Should this number be 0, no shell will be executed. */ - static int numCommands; - +typedef enum JobStartResult { - JOB_RUNNING, /* Job is running */ - JOB_ERROR, /* Error in starting the job */ - JOB_FINISHED /* The job is already finished */ ++ JOB_RUNNING, /* Job is running */ ++ JOB_ERROR, /* Error in starting the job */ ++ JOB_FINISHED /* The job is already finished */ +} JobStartResult; + +/* + * Descriptions for various shells. + * + * The build environment may set DEFSHELL_INDEX to one of + * DEFSHELL_INDEX_SH, DEFSHELL_INDEX_KSH, or DEFSHELL_INDEX_CSH, to + * select one of the predefined shells as the default shell. + * + * Alternatively, the build environment may set DEFSHELL_CUSTOM to the + * name or the full path of a sh-compatible shell, which will be used as + * the default shell. + * + * ".SHELL" lines in Makefiles can choose the default shell from the + * set defined here, or add additional shells. + */ + +#ifdef DEFSHELL_CUSTOM +#define DEFSHELL_INDEX_CUSTOM 0 +#define DEFSHELL_INDEX_SH 1 +#define DEFSHELL_INDEX_KSH 2 +#define DEFSHELL_INDEX_CSH 3 +#else /* !DEFSHELL_CUSTOM */ +#define DEFSHELL_INDEX_SH 0 +#define DEFSHELL_INDEX_KSH 1 +#define DEFSHELL_INDEX_CSH 2 +#endif /* !DEFSHELL_CUSTOM */ + +#ifndef DEFSHELL_INDEX +#define DEFSHELL_INDEX 0 /* DEFSHELL_INDEX_CUSTOM or DEFSHELL_INDEX_SH */ +#endif /* !DEFSHELL_INDEX */ + - static Shell shells[] = { ++static Shell shells[] = { +#ifdef DEFSHELL_CUSTOM + /* + * An sh-compatible shell with a non-standard name. + * + * Keep this in sync with the "sh" description below, but avoid + * non-portable features that might not be supplied by all + * sh-compatible shells. + */ - { - DEFSHELL_CUSTOM, /* .name */ - FALSE, /* .hasEchoCtl */ - "", /* .echoOff */ - "", /* .echoOn */ - "", /* .noPrint */ - 0, /* .noPrintLen */ - FALSE, /* .hasErrCtl */ - "echo \"%s\"\n", /* .errOnOrEcho */ - "%s\n", /* .errOffOrExecIgnore */ - "{ %s \n} || exit $?\n", /* .errExit */ - "'\n'", /* .newline */ - '#', /* .commentChar */ - "", /* .echo */ - "", /* .exit */ - }, ++ { ++ DEFSHELL_CUSTOM, /* .name */ ++ FALSE, /* .hasEchoCtl */ ++ "", /* .echoOff */ ++ "", /* .echoOn */ ++ "", /* .noPrint */ ++ 0, /* .noPrintLen */ ++ FALSE, /* .hasErrCtl */ ++ "", /* .errOn */ ++ "", /* .errOff */ ++ "echo \"%s\"\n", /* .echoTmpl */ ++ "%s\n", /* .runIgnTmpl */ ++ "{ %s \n} || exit $?\n", /* .runChkTmpl */ ++ "'\n'", /* .newline */ ++ '#', /* .commentChar */ ++ "", /* .echoFlag */ ++ "", /* .errFlag */ ++ }, +#endif /* DEFSHELL_CUSTOM */ + /* + * SH description. Echo control is also possible and, under + * sun UNIX anyway, one can even control error checking. + */ - { - "sh", /* .name */ - FALSE, /* .hasEchoCtl */ - "", /* .echoOff */ - "", /* .echoOn */ - "", /* .noPrint */ - 0, /* .noPrintLen */ - FALSE, /* .hasErrCtl */ - "echo \"%s\"\n", /* .errOnOrEcho */ - "%s\n", /* .errOffOrExecIgnore */ - "{ %s \n} || exit $?\n", /* .errExit */ - "'\n'", /* .newline */ - '#', /* .commentChar*/ ++ { ++ "sh", /* .name */ ++ FALSE, /* .hasEchoCtl */ ++ "", /* .echoOff */ ++ "", /* .echoOn */ ++ "", /* .noPrint */ ++ 0, /* .noPrintLen */ ++ FALSE, /* .hasErrCtl */ ++ "", /* .errOn */ ++ "", /* .errOff */ ++ "echo \"%s\"\n", /* .echoTmpl */ ++ "%s\n", /* .runIgnTmpl */ ++ "{ %s \n} || exit $?\n", /* .runChkTmpl */ ++ "'\n'", /* .newline */ ++ '#', /* .commentChar*/ +#if defined(MAKE_NATIVE) && defined(__NetBSD__) - "q", /* .echo */ ++ /* XXX: -q is not really echoFlag, it's more like noEchoInSysFlag. */ ++ "q", /* .echoFlag */ +#else - "", /* .echo */ ++ "", /* .echoFlag */ +#endif - "", /* .exit */ - }, ++ "", /* .errFlag */ ++ }, + /* + * KSH description. + */ - { - "ksh", /* .name */ - TRUE, /* .hasEchoCtl */ - "set +v", /* .echoOff */ - "set -v", /* .echoOn */ - "set +v", /* .noPrint */ - 6, /* .noPrintLen */ - FALSE, /* .hasErrCtl */ - "echo \"%s\"\n", /* .errOnOrEcho */ - "%s\n", /* .errOffOrExecIgnore */ - "{ %s \n} || exit $?\n", /* .errExit */ - "'\n'", /* .newline */ - '#', /* .commentChar */ - "v", /* .echo */ - "", /* .exit */ - }, ++ { ++ "ksh", /* .name */ ++ TRUE, /* .hasEchoCtl */ ++ "set +v", /* .echoOff */ ++ "set -v", /* .echoOn */ ++ "set +v", /* .noPrint */ ++ 6, /* .noPrintLen */ ++ FALSE, /* .hasErrCtl */ ++ "", /* .errOn */ ++ "", /* .errOff */ ++ "echo \"%s\"\n", /* .echoTmpl */ ++ "%s\n", /* .runIgnTmpl */ ++ "{ %s \n} || exit $?\n", /* .runChkTmpl */ ++ "'\n'", /* .newline */ ++ '#', /* .commentChar */ ++ "v", /* .echoFlag */ ++ "", /* .errFlag */ ++ }, + /* + * CSH description. The csh can do echo control by playing + * with the setting of the 'echo' shell variable. Sadly, + * however, it is unable to do error control nicely. + */ - { - "csh", /* .name */ - TRUE, /* .hasEchoCtl */ - "unset verbose", /* .echoOff */ - "set verbose", /* .echoOn */ - "unset verbose", /* .noPrint */ - 13, /* .noPrintLen */ - FALSE, /* .hasErrCtl */ - "echo \"%s\"\n", /* .errOnOrEcho */ - /* XXX: Mismatch between errOn and execIgnore */ - "csh -c \"%s || exit 0\"\n", /* .errOffOrExecIgnore */ - "", /* .errExit */ - "'\\\n'", /* .newline */ - '#', /* .commentChar */ - "v", /* .echo */ - "e", /* .exit */ - } ++ { ++ "csh", /* .name */ ++ TRUE, /* .hasEchoCtl */ ++ "unset verbose", /* .echoOff */ ++ "set verbose", /* .echoOn */ ++ "unset verbose", /* .noPrint */ ++ 13, /* .noPrintLen */ ++ FALSE, /* .hasErrCtl */ ++ "", /* .errOn */ ++ "", /* .errOff */ ++ "echo \"%s\"\n", /* .echoTmpl */ ++ "csh -c \"%s || exit 0\"\n", /* .runIgnTmpl */ ++ "", /* .runChkTmpl */ ++ "'\\\n'", /* .newline */ ++ '#', /* .commentChar */ ++ "v", /* .echoFlag */ ++ "e", /* .errFlag */ ++ } +}; + - /* This is the shell to which we pass all commands in the Makefile. - * It is set by the Job_ParseShell function. */ - static Shell *commandShell = &shells[DEFSHELL_INDEX]; ++/* ++ * This is the shell to which we pass all commands in the Makefile. ++ * It is set by the Job_ParseShell function. ++ */ ++static Shell *shell = &shells[DEFSHELL_INDEX]; +const char *shellPath = NULL; /* full pathname of executable image */ +const char *shellName = NULL; /* last component of shellPath */ +char *shellErrFlag = NULL; +static char *shellArgv = NULL; /* Custom shell args */ + + +static Job *job_table; /* The structures that describe them */ +static Job *job_table_end; /* job_table + maxJobs */ +static unsigned int wantToken; /* we want a token */ +static Boolean lurking_children = FALSE; - static Boolean make_suspended = FALSE; /* Whether we've seen a SIGTSTP (etc) */ ++static Boolean make_suspended = FALSE; /* Whether we've seen a SIGTSTP (etc) */ + +/* + * Set of descriptors of pipes connected to + * the output channels of children + */ +static struct pollfd *fds = NULL; - static Job **jobfds = NULL; - static nfds_t nfds = 0; ++static Job **allJobs = NULL; ++static nfds_t nJobs = 0; +static void watchfd(Job *); +static void clearfd(Job *); - static int readyfd(Job *); ++static Boolean readyfd(Job *); + - static GNode *lastNode; /* The node for which output was most recently - * produced. */ - static char *targPrefix = NULL; /* What we print at the start of TARG_FMT */ ++static char *targPrefix = NULL; /* To identify a job change in the output. */ +static Job tokenWaitJob; /* token wait pseudo-job */ + +static Job childExitJob; /* child exit pseudo-job */ - #define CHILD_EXIT "." - #define DO_JOB_RESUME "R" ++#define CHILD_EXIT "." ++#define DO_JOB_RESUME "R" + - enum { npseudojobs = 2 }; /* number of pseudo-jobs */ - - #define TARG_FMT "%s %s ---\n" /* Default format */ - #define MESSAGE(fp, gn) \ - if (opts.maxJobs != 1 && targPrefix && *targPrefix) \ - (void)fprintf(fp, TARG_FMT, targPrefix, gn->name) ++enum { ++ npseudojobs = 2 /* number of pseudo-jobs */ ++}; + +static sigset_t caught_signals; /* Set of signals we handle */ + +static void JobDoOutput(Job *, Boolean); - static void JobInterrupt(int, int) MAKE_ATTR_DEAD; ++static void JobInterrupt(Boolean, int) MAKE_ATTR_DEAD; +static void JobRestartJobs(void); +static void JobSigReset(void); + ++static void ++SwitchOutputTo(GNode *gn) ++{ ++ /* The node for which output was most recently produced. */ ++ static GNode *lastNode = NULL; ++ ++ if (gn == lastNode) ++ return; ++ lastNode = gn; ++ ++ if (opts.maxJobs != 1 && targPrefix != NULL && targPrefix[0] != '\0') ++ (void)fprintf(stdout, "%s %s ---\n", targPrefix, gn->name); ++} ++ +static unsigned +nfds_per_job(void) +{ +#if defined(USE_FILEMON) && !defined(USE_FILEMON_DEV) - if (useMeta) - return 2; ++ if (useMeta) ++ return 2; +#endif - return 1; ++ return 1; ++} ++ ++void ++Job_FlagsToString(const Job *job, char *buf, size_t bufsize) ++{ ++ snprintf(buf, bufsize, "%c%c%c", ++ job->ignerr ? 'i' : '-', ++ !job->echo ? 's' : '-', ++ job->special ? 'S' : '-'); +} + +static void +job_table_dump(const char *where) +{ - Job *job; ++ Job *job; ++ char flags[4]; + - debug_printf("job table @ %s\n", where); - for (job = job_table; job < job_table_end; job++) { - debug_printf("job %d, status %d, flags %d, pid %d\n", - (int)(job - job_table), job->status, job->flags, job->pid); - } ++ debug_printf("job table @ %s\n", where); ++ for (job = job_table; job < job_table_end; job++) { ++ Job_FlagsToString(job, flags, sizeof flags); ++ debug_printf("job %d, status %d, flags %s, pid %d\n", ++ (int)(job - job_table), job->status, flags, job->pid); ++ } +} + +/* + * Delete the target of a failed, interrupted, or otherwise + * unsuccessful job unless inhibited by .PRECIOUS. + */ +static void +JobDeleteTarget(GNode *gn) +{ - const char *file; - - if (gn->type & OP_JOIN) - return; - if (gn->type & OP_PHONY) - return; - if (Targ_Precious(gn)) - return; - if (opts.noExecute) - return; - - file = GNode_Path(gn); - if (eunlink(file) != -1) - Error("*** %s removed", file); ++ const char *file; ++ ++ if (gn->type & OP_JOIN) ++ return; ++ if (gn->type & OP_PHONY) ++ return; ++ if (Targ_Precious(gn)) ++ return; ++ if (opts.noExecute) ++ return; ++ ++ file = GNode_Path(gn); ++ if (eunlink(file) != -1) ++ Error("*** %s removed", file); *** 7771 LINES SKIPPED ***
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?202101140622.10E6MGAx018193>