git: b0c40a00a67f - main - Merge commit 'ee914ef902ae018bd4f67192832120f9bf05651f' into new_merge

Simon J. Gerraty sjg at FreeBSD.org
Fri Jun 25 23:01:54 UTC 2021


The branch main has been updated by sjg:

URL: https://cgit.FreeBSD.org/src/commit/?id=b0c40a00a67f611868fc0f10bde6b28eb75931be

commit b0c40a00a67f611868fc0f10bde6b28eb75931be
Merge: cab31e0e216c ee914ef902ae
Author:     Simon J. Gerraty <sjg at FreeBSD.org>
AuthorDate: 2021-06-25 21:31:14 +0000
Commit:     Simon J. Gerraty <sjg at FreeBSD.org>
CommitDate: 2021-06-25 21:31:14 +0000

    Merge commit 'ee914ef902ae018bd4f67192832120f9bf05651f' into new_merge

 contrib/bmake/ChangeLog                            |  113 +
 contrib/bmake/FILES                                |   13 +
 contrib/bmake/VERSION                              |    2 +-
 contrib/bmake/arch.c                               |  104 +-
 contrib/bmake/buf.h                                |    4 +-
 contrib/bmake/compat.c                             |   42 +-
 contrib/bmake/cond.c                               |  279 +-
 contrib/bmake/dir.c                                |   62 +-
 contrib/bmake/dir.h                                |    6 +-
 contrib/bmake/enum.h                               |   62 +-
 contrib/bmake/for.c                                |   46 +-
 contrib/bmake/hash.c                               |   68 +-
 contrib/bmake/hash.h                               |   14 +-
 contrib/bmake/import.sh                            |   17 +-
 contrib/bmake/job.c                                |  423 +--
 contrib/bmake/job.h                                |   20 +-
 contrib/bmake/lst.c                                |   10 +-
 contrib/bmake/lst.h                                |   12 +-
 contrib/bmake/main.c                               |  250 +-
 contrib/bmake/make.c                               |   91 +-
 contrib/bmake/make.h                               |  129 +-
 contrib/bmake/meta.c                               |  194 +-
 contrib/bmake/meta.h                               |    8 +-
 contrib/bmake/metachar.h                           |    4 +-
 contrib/bmake/mk/ChangeLog                         |   35 +
 contrib/bmake/mk/dirdeps.mk                        |   76 +-
 contrib/bmake/mk/dpadd.mk                          |    7 +-
 contrib/bmake/mk/install-mk                        |    4 +-
 contrib/bmake/mk/meta.autodep.mk                   |    6 +-
 contrib/bmake/mk/meta2deps.py                      |   54 +-
 contrib/bmake/mk/rst2htm.mk                        |    6 +-
 contrib/bmake/nonints.h                            |  153 +-
 contrib/bmake/parse.c                              |  512 ++--
 contrib/bmake/str.c                                |  101 +-
 contrib/bmake/str.h                                |  366 +++
 contrib/bmake/suff.c                               |   71 +-
 contrib/bmake/targ.c                               |   14 +-
 contrib/bmake/unit-tests/Makefile                  |   28 +-
 contrib/bmake/unit-tests/archive.mk                |    6 +-
 contrib/bmake/unit-tests/cmd-errors-jobs.exp       |    2 +-
 contrib/bmake/unit-tests/cmd-errors-lint.exp       |    2 +-
 contrib/bmake/unit-tests/cmd-errors.exp            |    2 +-
 contrib/bmake/unit-tests/cond-func-empty.mk        |   10 +-
 contrib/bmake/unit-tests/cond-func-make-main.mk    |    6 +-
 contrib/bmake/unit-tests/cond-late.exp             |    2 +-
 contrib/bmake/unit-tests/cond-short.mk             |   14 +-
 contrib/bmake/unit-tests/cond-token-string.exp     |    2 +-
 contrib/bmake/unit-tests/cond-token-var.mk         |   23 +-
 contrib/bmake/unit-tests/cond1.exp                 |    2 +-
 contrib/bmake/unit-tests/counter-append.mk         |    4 +-
 contrib/bmake/unit-tests/counter.mk                |    4 +-
 contrib/bmake/unit-tests/dep-var.mk                |    4 +-
 contrib/bmake/unit-tests/deptgt-makeflags.exp      |   10 +-
 contrib/bmake/unit-tests/deptgt-order.exp          |    3 +
 contrib/bmake/unit-tests/deptgt-order.mk           |   18 +-
 contrib/bmake/unit-tests/deptgt.exp                |    8 +-
 contrib/bmake/unit-tests/deptgt.mk                 |    4 +-
 contrib/bmake/unit-tests/directive-export-impl.exp |   88 +-
 contrib/bmake/unit-tests/directive-export-impl.mk  |   23 +-
 contrib/bmake/unit-tests/directive-export.mk       |   15 +-
 contrib/bmake/unit-tests/directive-for-errors.exp  |    2 +-
 contrib/bmake/unit-tests/directive-for-errors.mk   |    6 +-
 contrib/bmake/unit-tests/directive-for-escape.exp  |   32 +-
 contrib/bmake/unit-tests/directive-for-escape.mk   |   21 +-
 contrib/bmake/unit-tests/directive-for.exp         |    2 +-
 contrib/bmake/unit-tests/directive-undef.exp       |    3 +-
 contrib/bmake/unit-tests/directive-undef.mk        |   21 +-
 .../bmake/unit-tests/directive-unexport-env.exp    |   20 +-
 contrib/bmake/unit-tests/directive.exp             |    8 +-
 contrib/bmake/unit-tests/include-main.exp          |    2 +-
 contrib/bmake/unit-tests/job-output-null.exp       |    4 +
 contrib/bmake/unit-tests/job-output-null.mk        |   32 +
 .../bmake/unit-tests/jobs-empty-commands-error.exp |    5 +
 .../bmake/unit-tests/jobs-empty-commands-error.mk  |   19 +
 contrib/bmake/unit-tests/moderrs.exp               |   97 +-
 contrib/bmake/unit-tests/moderrs.mk                |   25 +-
 contrib/bmake/unit-tests/modts.exp                 |    4 +-
 contrib/bmake/unit-tests/modword.exp               |   24 +-
 contrib/bmake/unit-tests/modword.mk                |    3 +-
 contrib/bmake/unit-tests/opt-chdir.mk              |    6 +-
 contrib/bmake/unit-tests/opt-debug-errors-jobs.exp |   48 +
 contrib/bmake/unit-tests/opt-debug-errors-jobs.mk  |   36 +
 contrib/bmake/unit-tests/opt-debug-lint.exp        |    2 +-
 contrib/bmake/unit-tests/opt-debug-lint.mk         |   20 +-
 contrib/bmake/unit-tests/opt-debug.exp             |    6 +-
 contrib/bmake/unit-tests/opt-file.mk               |    6 +-
 contrib/bmake/unit-tests/opt-jobs-no-action.mk     |    4 +-
 contrib/bmake/unit-tests/recursive.mk              |    7 +-
 contrib/bmake/unit-tests/sh-jobs.mk                |    8 +-
 contrib/bmake/unit-tests/shell-csh.mk              |    4 +-
 contrib/bmake/unit-tests/suff-incomplete.exp       |   10 +-
 contrib/bmake/unit-tests/suff-main-several.exp     |   24 +-
 contrib/bmake/unit-tests/suff-rebuild.exp          |   14 +-
 contrib/bmake/unit-tests/var-class-cmdline.exp     |    3 +
 contrib/bmake/unit-tests/var-class-cmdline.mk      |   80 +-
 contrib/bmake/unit-tests/var-eval-short.exp        |   29 +
 contrib/bmake/unit-tests/var-eval-short.mk         |  163 ++
 contrib/bmake/unit-tests/var-op-append.exp         |   12 +-
 contrib/bmake/unit-tests/var-op-append.mk          |    4 +-
 contrib/bmake/unit-tests/var-op-assign.mk          |    4 +-
 contrib/bmake/unit-tests/var-op-sunsh.mk           |   12 +-
 contrib/bmake/unit-tests/varcmd.mk                 |   14 +-
 contrib/bmake/unit-tests/vardebug.exp              |  119 +-
 contrib/bmake/unit-tests/varmisc.exp               |    2 +-
 contrib/bmake/unit-tests/varmod-assign.exp         |   22 +-
 contrib/bmake/unit-tests/varmod-assign.mk          |   39 +-
 contrib/bmake/unit-tests/varmod-defined.exp        |   34 +-
 contrib/bmake/unit-tests/varmod-defined.mk         |    6 +-
 contrib/bmake/unit-tests/varmod-edge.exp           |   12 +-
 contrib/bmake/unit-tests/varmod-edge.mk            |   26 +-
 contrib/bmake/unit-tests/varmod-hash.exp           |    6 +-
 contrib/bmake/unit-tests/varmod-ifelse.exp         |   22 +-
 contrib/bmake/unit-tests/varmod-ifelse.mk          |   64 +-
 contrib/bmake/unit-tests/varmod-indirect.exp       |   84 +-
 contrib/bmake/unit-tests/varmod-indirect.mk        |  100 +-
 contrib/bmake/unit-tests/varmod-loop-varname.exp   |   11 +
 contrib/bmake/unit-tests/varmod-loop-varname.mk    |  127 +
 contrib/bmake/unit-tests/varmod-loop.exp           |   19 +-
 contrib/bmake/unit-tests/varmod-loop.mk            |  156 +-
 contrib/bmake/unit-tests/varmod-match-escape.exp   |   74 +-
 contrib/bmake/unit-tests/varmod-match-escape.mk    |    8 +-
 contrib/bmake/unit-tests/varmod-order.exp          |    4 +-
 contrib/bmake/unit-tests/varmod-range.exp          |   10 +-
 contrib/bmake/unit-tests/varmod-remember.exp       |    2 -
 contrib/bmake/unit-tests/varmod-remember.mk        |   29 +-
 contrib/bmake/unit-tests/varmod-shell.mk           |    9 +-
 contrib/bmake/unit-tests/varmod-subst-regex.exp    |   25 +-
 contrib/bmake/unit-tests/varmod-subst-regex.mk     |   54 +-
 contrib/bmake/unit-tests/varmod-subst.exp          |    2 +-
 contrib/bmake/unit-tests/varmod-subst.mk           |   10 +-
 contrib/bmake/unit-tests/varmod-sun-shell.exp      |    2 +
 contrib/bmake/unit-tests/varmod-sun-shell.mk       |   21 +
 contrib/bmake/unit-tests/varmod-sysv.exp           |  147 +-
 contrib/bmake/unit-tests/varmod-sysv.mk            |   57 +-
 contrib/bmake/unit-tests/varmod-to-separator.exp   |   12 +-
 contrib/bmake/unit-tests/varmod-unique.mk          |   12 +-
 contrib/bmake/unit-tests/varname-dot-shell.exp     |   32 +-
 contrib/bmake/unit-tests/varname-empty.exp         |   60 +-
 contrib/bmake/unit-tests/varname-empty.mk          |    4 +-
 contrib/bmake/unit-tests/varname.exp               |   33 +-
 contrib/bmake/unit-tests/varparse-dynamic.mk       |    6 +-
 contrib/bmake/unit-tests/varparse-errors.exp       |    4 +-
 contrib/bmake/unit-tests/varparse-errors.mk        |    4 +-
 contrib/bmake/var.c                                | 3073 +++++++++++---------
 144 files changed, 5499 insertions(+), 3548 deletions(-)

diff --cc contrib/bmake/job.c
index eb5454cde574,000000000000..c27c47d0b054
mode 100644,000000..100644
--- a/contrib/bmake/job.c
+++ b/contrib/bmake/job.c
@@@ -1,3012 -1,0 +1,3049 @@@
- /*	$NetBSD: job.c,v 1.420 2021/02/05 22:15:44 sjg Exp $	*/
++/*	$NetBSD: job.c,v 1.435 2021/06/16 09:47:51 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,
 + *			the .BEGIN target is made including all of its
 + *			dependencies 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 a special dependency line with target '.SHELL',
 + *			define the shell that is used for the creation
 + *			commands in jobs mode.
 + *
 + *	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. Do not handle
 + *			output or do anything for the jobs, just kill them.
 + *			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.420 2021/02/05 22:15:44 sjg Exp $");
++MAKE_RCSID("$NetBSD: job.c,v 1.435 2021/06/16 09:47:51 rillig Exp $");
 +
 +/*
 + * 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,
 + * errOn, errOff and runChkTmpl.
 + *
 + * In case a shell doesn't have error control, echoTmpl is a printf template
 + * for echoing the command, should echoing be on; runIgnTmpl is another
 + * printf template for executing the command while ignoring the return
 + * 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
++ * 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 unwanted
 + * shell code injection, the escaped command is safe to use in double quotes.
 + *
 + * 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;
 +
- 	Boolean hasEchoCtl;	/* whether both echoOff and echoOn are there */
++	bool 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 */
 +
- 	Boolean hasErrCtl;	/* whether error checking can be controlled
++	bool 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;
 +
 +typedef struct CommandFlags {
 +	/* Whether to echo the command before or instead of running it. */
- 	Boolean echo;
++	bool echo;
 +
 +	/* Run the command even in -n or -N mode. */
- 	Boolean always;
++	bool always;
 +
 +	/*
- 	 * true if we turned error checking off before printing the command
- 	 * and need to turn it back on
++	 * true if we turned error checking off before writing the command to
++	 * the commands file and need to turn it back on
 +	 */
- 	Boolean ignerr;
++	bool 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;
++	bool 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 job_errors = 0;	/* number of errors reported */
- typedef enum AbortReason {	/* why is the make aborting? */
++static enum {			/* Why is the make aborting? */
 +	ABORT_NONE,
- 	ABORT_ERROR,		/* Because of an error */
- 	ABORT_INTERRUPT,	/* Because it was interrupted */
++	ABORT_ERROR,		/* Aborted because of an error */
++	ABORT_INTERRUPT,	/* Aborted because it was interrupted */
 +	ABORT_WAIT		/* Waiting for jobs to finish */
- 	/* XXX: "WAIT" is not a _reason_ for aborting, it's rather a status. */
- } AbortReason;
- static AbortReason aborting = ABORT_NONE;
++} aborting = ABORT_NONE;
 +#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;
 +
 +typedef enum JobStartResult {
 +	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[] = {
 +#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 */
++	false,			/* .hasEchoCtl */
 +	"",			/* .echoOff */
 +	"",			/* .echoOn */
 +	"",			/* .noPrint */
 +	0,			/* .noPrintLen */
- 	FALSE,			/* .hasErrCtl */
++	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 */
++	false,			/* .hasEchoCtl */
 +	"",			/* .echoOff */
 +	"",			/* .echoOn */
 +	"",			/* .noPrint */
 +	0,			/* .noPrintLen */
- 	FALSE,			/* .hasErrCtl */
++	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__)
 +	/* XXX: -q is not really echoFlag, it's more like noEchoInSysFlag. */
 +	"q",			/* .echoFlag */
 +#else
 +	"",			/* .echoFlag */
 +#endif
 +	"",			/* .errFlag */
 +    },
 +    /*
 +     * KSH description.
 +     */
 +    {
 +	"ksh",			/* .name */
- 	TRUE,			/* .hasEchoCtl */
++	true,			/* .hasEchoCtl */
 +	"set +v",		/* .echoOff */
 +	"set -v",		/* .echoOn */
 +	"set +v",		/* .noPrint */
 +	6,			/* .noPrintLen */
- 	FALSE,			/* .hasErrCtl */
++	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 */
++	true,			/* .hasEchoCtl */
 +	"unset verbose",	/* .echoOff */
 +	"set verbose",		/* .echoOn */
 +	"unset verbose",	/* .noPrint */
 +	13,			/* .noPrintLen */
- 	FALSE,			/* .hasErrCtl */
++	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 *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 *shell_freeIt = NULL; /* Allocated memory for custom .SHELL */
 +
 +
 +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 bool lurking_children = false;
++static bool 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 **jobByFdIndex = NULL;
 +static nfds_t fdsLen = 0;
 +static void watchfd(Job *);
 +static void clearfd(Job *);
- static Boolean readyfd(Job *);
++static bool readyfd(Job *);
 +
 +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"
 +
 +enum {
 +	npseudojobs = 2		/* number of pseudo-jobs */
 +};
 +
 +static sigset_t caught_signals;	/* Set of signals we handle */
 +static volatile sig_atomic_t caught_sigchld;
 +
- static void JobDoOutput(Job *, Boolean);
- static void JobInterrupt(Boolean, int) MAKE_ATTR_DEAD;
++static void CollectOutput(Job *, bool);
++static void JobInterrupt(bool, 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;
 +#endif
 +	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)
++DumpJobs(const char *where)
 +{
 +	Job *job;
 +	char flags[4];
 +
 +	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);
 +}
 +
 +/*
 + * JobSigLock/JobSigUnlock
 + *
 + * Signal lock routines to get exclusive access. Currently used to
 + * protect `jobs' and `stoppedJobs' list manipulations.
 + */
 +static void
 +JobSigLock(sigset_t *omaskp)
 +{
 +	if (sigprocmask(SIG_BLOCK, &caught_signals, omaskp) != 0) {
 +		Punt("JobSigLock: sigprocmask: %s", strerror(errno));
 +		sigemptyset(omaskp);
 +	}
 +}
 +
 +static void
 +JobSigUnlock(sigset_t *omaskp)
 +{
 +	(void)sigprocmask(SIG_SETMASK, omaskp, NULL);
 +}
 +
 +static void
 +JobCreatePipe(Job *job, int minfd)
 +{
 +	int i, fd, flags;
 +	int pipe_fds[2];
 +
 +	if (pipe(pipe_fds) == -1)
 +		Punt("Cannot create pipe: %s", strerror(errno));
 +
 +	for (i = 0; i < 2; i++) {
 +		/* Avoid using low numbered fds */
 +		fd = fcntl(pipe_fds[i], F_DUPFD, minfd);
 +		if (fd != -1) {
 +			close(pipe_fds[i]);
 +			pipe_fds[i] = fd;
 +		}
 +	}
 +
 +	job->inPipe = pipe_fds[0];
 +	job->outPipe = pipe_fds[1];
 +
 +	/* Set close-on-exec flag for both */
 +	if (fcntl(job->inPipe, F_SETFD, FD_CLOEXEC) == -1)
 +		Punt("Cannot set close-on-exec: %s", strerror(errno));
 +	if (fcntl(job->outPipe, F_SETFD, FD_CLOEXEC) == -1)
 +		Punt("Cannot set close-on-exec: %s", strerror(errno));
 +
 +	/*
 +	 * We mark the input side of the pipe non-blocking; we poll(2) the
 +	 * pipe when we're waiting for a job token, but we might lose the
 +	 * race for the token when a new one becomes available, so the read
 +	 * from the pipe should not block.
 +	 */
 +	flags = fcntl(job->inPipe, F_GETFL, 0);
 +	if (flags == -1)
 +		Punt("Cannot get flags: %s", strerror(errno));
 +	flags |= O_NONBLOCK;
 +	if (fcntl(job->inPipe, F_SETFL, flags) == -1)
 +		Punt("Cannot set flags: %s", strerror(errno));
 +}
 +
 +/* Pass the signal to each running job. */
 +static void
 +JobCondPassSig(int signo)
 +{
 +	Job *job;
 +
 +	DEBUG1(JOB, "JobCondPassSig(%d) called.\n", signo);
 +
 +	for (job = job_table; job < job_table_end; job++) {
 +		if (job->status != JOB_ST_RUNNING)
 +			continue;
 +		DEBUG2(JOB, "JobCondPassSig passing signal %d to child %d.\n",
 +		    signo, job->pid);
 +		KILLPG(job->pid, signo);
 +	}
 +}
 +
 +/*
 + * SIGCHLD handler.
 + *
 + * Sends a token on the child exit pipe to wake us up from select()/poll().
 + */
 +/*ARGSUSED*/
 +static void
 +JobChildSig(int signo MAKE_ATTR_UNUSED)
 +{
 +	caught_sigchld = 1;
 +	while (write(childExitJob.outPipe, CHILD_EXIT, 1) == -1 &&
 +	       errno == EAGAIN)
 +		continue;
 +}
 +
 +
 +/* Resume all stopped jobs. */
 +/*ARGSUSED*/
 +static void
 +JobContinueSig(int signo MAKE_ATTR_UNUSED)
 +{
 +	/*
 +	 * Defer sending SIGCONT to our stopped children until we return
 +	 * from the signal handler.
 +	 */
 +	while (write(childExitJob.outPipe, DO_JOB_RESUME, 1) == -1 &&
 +	       errno == EAGAIN)
 +		continue;
 +}
 +
 +/*
 + * Pass a signal on to all jobs, then resend to ourselves.
 + * We die by the same signal.
 + */
 +MAKE_ATTR_DEAD static void
 +JobPassSig_int(int signo)
 +{
 +	/* Run .INTERRUPT target then exit */
- 	JobInterrupt(TRUE, signo);
++	JobInterrupt(true, signo);
 +}
 +
 +/*
 + * Pass a signal on to all jobs, then resend to ourselves.
 + * We die by the same signal.
 + */
 +MAKE_ATTR_DEAD static void
 +JobPassSig_term(int signo)
 +{
 +	/* Dont run .INTERRUPT target then exit */
- 	JobInterrupt(FALSE, signo);
++	JobInterrupt(false, signo);
 +}
 +
 +static void
 +JobPassSig_suspend(int signo)
 +{
 +	sigset_t nmask, omask;
 +	struct sigaction act;
 +
 +	/* Suppress job started/continued messages */
- 	make_suspended = TRUE;
++	make_suspended = true;
 +
 +	/* Pass the signal onto every job */
 +	JobCondPassSig(signo);
 +
 +	/*
 +	 * Send ourselves the signal now we've given the message to everyone
 +	 * else. Note we block everything else possible while we're getting
 +	 * the signal. This ensures that all our jobs get continued when we
 +	 * wake up before we take any other signal.
 +	 */
 +	sigfillset(&nmask);
 +	sigdelset(&nmask, signo);
 +	(void)sigprocmask(SIG_SETMASK, &nmask, &omask);
 +
 +	act.sa_handler = SIG_DFL;
 +	sigemptyset(&act.sa_mask);
 +	act.sa_flags = 0;
 +	(void)sigaction(signo, &act, NULL);
 +
 +	DEBUG1(JOB, "JobPassSig passing signal %d to self.\n", signo);
 +
 +	(void)kill(getpid(), signo);
 +
 +	/*
 +	 * We've been continued.
 +	 *
 +	 * A whole host of signals continue to happen!
 +	 * SIGCHLD for any processes that actually suspended themselves.
 +	 * SIGCHLD for any processes that exited while we were alseep.
 +	 * The SIGCONT that actually caused us to wakeup.
 +	 *
 +	 * Since we defer passing the SIGCONT on to our children until
 +	 * the main processing loop, we can be sure that all the SIGCHLD
 +	 * events will have happened by then - and that the waitpid() will
 +	 * collect the child 'suspended' events.
 +	 * For correct sequencing we just need to ensure we process the
 +	 * waitpid() before passing on the SIGCONT.
 +	 *
 +	 * In any case nothing else is needed here.
 +	 */
 +
 +	/* Restore handler and signal mask */
 +	act.sa_handler = JobPassSig_suspend;
 +	(void)sigaction(signo, &act, NULL);
 +	(void)sigprocmask(SIG_SETMASK, &omask, NULL);
 +}
 +
 +static Job *
- JobFindPid(int pid, JobStatus status, Boolean isJobs)
++JobFindPid(int pid, JobStatus status, bool isJobs)
 +{
 +	Job *job;
 +
 +	for (job = job_table; job < job_table_end; job++) {
 +		if (job->status == status && job->pid == pid)
 +			return job;
 +	}
 +	if (DEBUG(JOB) && isJobs)
- 		job_table_dump("no pid");
++		DumpJobs("no pid");
 +	return NULL;
 +}
 +
 +/* Parse leading '@', '-' and '+', which control the exact execution mode. */
 +static void
 +ParseCommandFlags(char **pp, CommandFlags *out_cmdFlags)
 +{
 +	char *p = *pp;
- 	out_cmdFlags->echo = TRUE;
- 	out_cmdFlags->ignerr = FALSE;
- 	out_cmdFlags->always = FALSE;
++	out_cmdFlags->echo = true;
++	out_cmdFlags->ignerr = false;
++	out_cmdFlags->always = false;
 +
 +	for (;;) {
 +		if (*p == '@')
 +			out_cmdFlags->echo = DEBUG(LOUD);
 +		else if (*p == '-')
- 			out_cmdFlags->ignerr = TRUE;
++			out_cmdFlags->ignerr = true;
 +		else if (*p == '+')
- 			out_cmdFlags->always = TRUE;
++			out_cmdFlags->always = true;
 +		else
 +			break;
 +		p++;
 +	}
 +
 +	pp_skip_whitespace(&p);
 +
 +	*pp = p;
 +}
 +
 +/* Escape a string for a double-quoted string literal in sh, csh and ksh. */
 +static char *
 +EscapeShellDblQuot(const char *cmd)
 +{
 +	size_t i, j;
 +
 +	/* Worst that could happen is every char needs escaping. */
 +	char *esc = bmake_malloc(strlen(cmd) * 2 + 1);
 +	for (i = 0, j = 0; cmd[i] != '\0'; i++, j++) {
 +		if (cmd[i] == '$' || cmd[i] == '`' || cmd[i] == '\\' ||
*** 2485 LINES SKIPPED ***


More information about the dev-commits-src-all mailing list