mirror of
https://github.com/mirror/make.git
synced 2024-12-28 05:40:10 +08:00
9d5b5bd2f5
Taylor. There are two forms of this: first, it was possible to lose tokens when using -j and -l at the same time, because waiting jobs were not checked when determining whether any jobs were outstanding. Second, if you had an exported recursive variable that contained a $(shell ...) function there is a possibility to lose tokens, since a token was taken but the child list was not updated until after the shell function was complete. To resolve this I introduced a new variable that counted the number of tokens we have obtained, rather than checking whether there were any children on the list. I also added some sanity checks to make sure we weren't writing back too many or not enough tokens. And, the master make will drain the token pipe before exiting and compare the count of tokens at the end to what was written there at the beginning. Also: * Ensure a bug in the environment (missing "=") doesn't cause make to core. * Rename the .DEFAULT_TARGET variable to .DEFAULT_GOAL, to match the terminology in the documentation and other variables like MAKECMDGOALS. * Add documentation of the .DEFAULT_GOAL special variable. Still need to document the secondary expansion stuff...
107 lines
3.2 KiB
C
107 lines
3.2 KiB
C
/* Definitions for managing subprocesses in GNU Make.
|
|
Copyright (C) 1992, 1993, 1996, 1999 Free Software Foundation, Inc.
|
|
This file is part of GNU Make.
|
|
|
|
GNU Make is free software; you can redistribute it and/or modify
|
|
it under the terms of the GNU General Public License as published by
|
|
the Free Software Foundation; either version 2, or (at your option)
|
|
any later version.
|
|
|
|
GNU Make is distributed in the hope that it will be useful,
|
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
GNU General Public License for more details.
|
|
|
|
You should have received a copy of the GNU General Public License
|
|
along with GNU Make; see the file COPYING. If not, write to
|
|
the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
|
|
Boston, MA 02111-1307, USA. */
|
|
|
|
#ifndef SEEN_JOB_H
|
|
#define SEEN_JOB_H
|
|
|
|
#ifdef HAVE_FCNTL_H
|
|
# include <fcntl.h>
|
|
#else
|
|
# include <sys/file.h>
|
|
#endif
|
|
|
|
/* How to set close-on-exec for a file descriptor. */
|
|
|
|
#if !defined F_SETFD
|
|
# define CLOSE_ON_EXEC(_d)
|
|
#else
|
|
# ifndef FD_CLOEXEC
|
|
# define FD_CLOEXEC 1
|
|
# endif
|
|
# define CLOSE_ON_EXEC(_d) (void) fcntl ((_d), F_SETFD, FD_CLOEXEC)
|
|
#endif
|
|
|
|
/* Structure describing a running or dead child process. */
|
|
|
|
struct child
|
|
{
|
|
struct child *next; /* Link in the chain. */
|
|
|
|
struct file *file; /* File being remade. */
|
|
|
|
char **environment; /* Environment for commands. */
|
|
|
|
char **command_lines; /* Array of variable-expanded cmd lines. */
|
|
unsigned int command_line; /* Index into above. */
|
|
char *command_ptr; /* Ptr into command_lines[command_line]. */
|
|
|
|
pid_t pid; /* Child process's ID number. */
|
|
#ifdef VMS
|
|
int efn; /* Completion event flag number */
|
|
int cstatus; /* Completion status */
|
|
#endif
|
|
char *sh_batch_file; /* Script file for shell commands */
|
|
unsigned int remote:1; /* Nonzero if executing remotely. */
|
|
|
|
unsigned int noerror:1; /* Nonzero if commands contained a `-'. */
|
|
|
|
unsigned int good_stdin:1; /* Nonzero if this child has a good stdin. */
|
|
unsigned int deleted:1; /* Nonzero if targets have been deleted. */
|
|
};
|
|
|
|
extern struct child *children;
|
|
|
|
extern void new_job PARAMS ((struct file *file));
|
|
extern void reap_children PARAMS ((int block, int err));
|
|
extern void start_waiting_jobs PARAMS ((void));
|
|
|
|
extern char **construct_command_argv PARAMS ((char *line, char **restp, struct file *file, char** batch_file));
|
|
#ifdef VMS
|
|
extern int child_execute_job PARAMS ((char *argv, struct child *child));
|
|
#elif defined(__EMX__)
|
|
extern int child_execute_job PARAMS ((int stdin_fd, int stdout_fd, char **argv, char **envp));
|
|
#else
|
|
extern void child_execute_job PARAMS ((int stdin_fd, int stdout_fd, char **argv, char **envp));
|
|
#endif
|
|
#ifdef _AMIGA
|
|
extern void exec_command PARAMS ((char **argv));
|
|
#elif defined(__EMX__)
|
|
extern int exec_command PARAMS ((char **argv, char **envp));
|
|
#else
|
|
extern void exec_command PARAMS ((char **argv, char **envp));
|
|
#endif
|
|
|
|
extern unsigned int job_slots_used;
|
|
|
|
extern void block_sigs PARAMS ((void));
|
|
#ifdef POSIX
|
|
extern void unblock_sigs PARAMS ((void));
|
|
#else
|
|
#ifdef HAVE_SIGSETMASK
|
|
extern int fatal_signal_mask;
|
|
#define unblock_sigs() sigsetmask (0)
|
|
#else
|
|
#define unblock_sigs()
|
|
#endif
|
|
#endif
|
|
|
|
extern unsigned int jobserver_tokens;
|
|
|
|
#endif /* SEEN_JOB_H */
|