mirror of
https://github.com/mirror/make.git
synced 2025-01-27 21:00:22 +08:00
* Applied some DOS updates.
* Started reworking the jobserver algorithm; not complete yet.
This commit is contained in:
parent
28ef4c4dac
commit
09f1e4cf83
15
ChangeLog
15
ChangeLog
@ -12,6 +12,21 @@
|
|||||||
|
|
||||||
* make.texinfo (Quick Reference): Update with the new features.
|
* make.texinfo (Quick Reference): Update with the new features.
|
||||||
|
|
||||||
|
1999-07-25 Eli Zaretskii <eliz@is.elta.co.il>
|
||||||
|
|
||||||
|
* remake.c [__MSDOS__]: Don't include variables.h, it's already
|
||||||
|
included.
|
||||||
|
|
||||||
|
* function.c (msdos_openpipe) [__MSDOS__]: Return FILE ptr.
|
||||||
|
(func_shell) [__MSDOS__]: Fix the argument list.
|
||||||
|
|
||||||
|
* Makefile.DOS.template: Update from Makefile.in.
|
||||||
|
|
||||||
|
* README.DOS.template: Configure command fixed.
|
||||||
|
|
||||||
|
* configh.dos.template: Update to provide definitions for
|
||||||
|
uintmax_t, fd_set_size_t, and HAVE_SELECT.
|
||||||
|
|
||||||
1999-07-24 Paul D. Smith <psmith@gnu.org>
|
1999-07-24 Paul D. Smith <psmith@gnu.org>
|
||||||
|
|
||||||
* Version 3.77.91 released.
|
* Version 3.77.91 released.
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
# -*-Makefile-*- template for DJGPP
|
# -*-Makefile-*- template for DJGPP
|
||||||
# Makefile.in generated automatically by automake 1.2 from Makefile.am
|
# Makefile.in generated automatically by automake 1.2 from Makefile.am
|
||||||
|
|
||||||
# Copyright (C) 1994, 1995, 1996, 1997 Free Software Foundation, Inc.
|
# Copyright (C) 1994, 1995-1998, 1999 Free Software Foundation, Inc.
|
||||||
# This Makefile.DOS is free software; the Free Software Foundation
|
# This Makefile.DOS is free software; the Free Software Foundation
|
||||||
# gives unlimited permission to copy, distribute and modify it.
|
# gives unlimited permission to copy, distribute and modify it.
|
||||||
|
|
||||||
@ -118,7 +118,11 @@ HEADERS = $(wildcard $(srcdir)/*.h)
|
|||||||
default: all
|
default: all
|
||||||
|
|
||||||
.SUFFIXES:
|
.SUFFIXES:
|
||||||
.SUFFIXES: .c .dvi .info .o .ps .texi .texinfo
|
.SUFFIXES: .S .c .dvi .info .o .ps .s .texi .texinfo .txi
|
||||||
|
|
||||||
|
mostlyclean-hdr:
|
||||||
|
|
||||||
|
clean-hdr:
|
||||||
|
|
||||||
distclean-hdr:
|
distclean-hdr:
|
||||||
-rm -f config.h
|
-rm -f config.h
|
||||||
@ -141,11 +145,17 @@ install-binPROGRAMS: $(bin_PROGRAMS)
|
|||||||
|
|
||||||
uninstall-binPROGRAMS:
|
uninstall-binPROGRAMS:
|
||||||
$(NORMAL_UNINSTALL)
|
$(NORMAL_UNINSTALL)
|
||||||
list='$(bin_PROGRAMS)'; for p in $$list; do rm -f $(bindir)/`echo $$p|sed '$(transform)'`; done
|
list='$(bin_PROGRAMS)'; for p in $$list; do rm -f $(bindir)/`echo $$p|sed '$(transform)'`.exe; done
|
||||||
|
|
||||||
.c.o:
|
.c.o:
|
||||||
$(COMPILE) -c $<
|
$(COMPILE) -c $<
|
||||||
|
|
||||||
|
.s.o:
|
||||||
|
$(COMPILE) -c $<
|
||||||
|
|
||||||
|
.S.o:
|
||||||
|
$(COMPILE) -c $<
|
||||||
|
|
||||||
clean-noinstLIBRARIES:
|
clean-noinstLIBRARIES:
|
||||||
-test -z "$(noinst_LIBRARIES)" || rm -f $(noinst_LIBRARIES)
|
-test -z "$(noinst_LIBRARIES)" || rm -f $(noinst_LIBRARIES)
|
||||||
|
|
||||||
@ -155,7 +165,7 @@ mostlyclean-compile:
|
|||||||
clean-compile:
|
clean-compile:
|
||||||
|
|
||||||
distclean-compile:
|
distclean-compile:
|
||||||
-rm -f *.tab.c
|
-rm -f *.tab.c *_tab.c
|
||||||
|
|
||||||
maintainer-clean-compile:
|
maintainer-clean-compile:
|
||||||
|
|
||||||
@ -188,6 +198,12 @@ DVIPS = dvips
|
|||||||
.texinfo.dvi:
|
.texinfo.dvi:
|
||||||
TEXINPUTS="$(srcdir);$$TEXINPUTS" MAKEINFO='$(MAKEINFO) -I $(srcdir)' $(TEXI2DVI) $<
|
TEXINPUTS="$(srcdir);$$TEXINPUTS" MAKEINFO='$(MAKEINFO) -I $(srcdir)' $(TEXI2DVI) $<
|
||||||
|
|
||||||
|
.txi.info:
|
||||||
|
$(MAKEINFO) $(srcdir)/$< -o ./$@
|
||||||
|
|
||||||
|
.txi.dvi:
|
||||||
|
TEXINPUTS="$(srcdir);$$TEXINPUTS" MAKEINFO='$(MAKEINFO) -I $(srcdir)' $(TEXI2DVI) $<
|
||||||
|
|
||||||
.dvi.ps:
|
.dvi.ps:
|
||||||
$(DVIPS) $< -o $@
|
$(DVIPS) $< -o $@
|
||||||
|
|
||||||
@ -208,7 +224,7 @@ dist-info: $(INFO_DEPS)
|
|||||||
for base in $(INFO_DEPS); do d=$(srcdir); for file in `cd $$d && eval echo $$base*`; do test -f $(distdir)/$$file || ln $$d/$$file $(distdir)/$$file 2> /dev/null || cp -p $$d/$$file $(distdir)/$$file; done; done
|
for base in $(INFO_DEPS); do d=$(srcdir); for file in `cd $$d && eval echo $$base*`; do test -f $(distdir)/$$file || ln $$d/$$file $(distdir)/$$file 2> /dev/null || cp -p $$d/$$file $(distdir)/$$file; done; done
|
||||||
|
|
||||||
mostlyclean-aminfo:
|
mostlyclean-aminfo:
|
||||||
rm -f make.aux make.cp make.cps make.dvi make.fn make.fns make.ky make.kys make.ps make.log make.pg make.toc make.tp make.tps make.vr make.vrs make.op make.tr make.cv make.cn
|
cd $(srcdir) && for i in $(INFO_DEPS) make.i; do rm -f `eval echo $$i*`; done
|
||||||
|
|
||||||
clean-aminfo:
|
clean-aminfo:
|
||||||
|
|
||||||
|
@ -5,7 +5,7 @@ Builds with DJGPP v2 port of GNU C/C++ compiler and utilities.
|
|||||||
|
|
||||||
New (since 3.74) DOS-specific features:
|
New (since 3.74) DOS-specific features:
|
||||||
|
|
||||||
1. Supports long filenames when run from DOS box on Windows 95.
|
1. Supports long filenames when run from DOS box on Windows 9x.
|
||||||
|
|
||||||
2. Supports both stock DOS COMMAND.COM and Unix-style shells
|
2. Supports both stock DOS COMMAND.COM and Unix-style shells
|
||||||
(details in ``Notes'' below).
|
(details in ``Notes'' below).
|
||||||
@ -48,9 +48,10 @@ To build:
|
|||||||
[Enter]. Otherwise, you need to supply the path to the source
|
[Enter]. Otherwise, you need to supply the path to the source
|
||||||
directory as an argument to the batch file, like this:
|
directory as an argument to the batch file, like this:
|
||||||
|
|
||||||
configure.bat c:/djgpp/gnu/make-%VERSION%
|
c:\djgpp\gnu\make-%VERSION%\configure.bat c:/djgpp/gnu/make-%VERSION%
|
||||||
|
|
||||||
Note the forward slashes: you MUST use them here.
|
Note the forward slashes in the source path argument: you MUST
|
||||||
|
use them here.
|
||||||
|
|
||||||
3. If configure.bat doesn't find a working Make, it will suggest to
|
3. If configure.bat doesn't find a working Make, it will suggest to
|
||||||
use the `dosbuild.bat' batch file to build Make. Either do as it
|
use the `dosbuild.bat' batch file to build Make. Either do as it
|
||||||
@ -228,9 +229,9 @@ Notes:
|
|||||||
|
|
||||||
4. Letter-case in filenames.
|
4. Letter-case in filenames.
|
||||||
|
|
||||||
If you run Make on Windows 95, you should be aware of the
|
If you run Make on Windows 9x, you should be aware of the
|
||||||
letter-case issue. Make is internally case-sensitive, but all
|
letter-case issue. Make is internally case-sensitive, but all
|
||||||
file operations are case-insensitive on Windows 95, so
|
file operations are case-insensitive on Windows 9x, so
|
||||||
e.g. files `FAQ', `faq' and `Faq' all refer to the same file, as
|
e.g. files `FAQ', `faq' and `Faq' all refer to the same file, as
|
||||||
far as Windows is concerned. The underlying DJGPP C library
|
far as Windows is concerned. The underlying DJGPP C library
|
||||||
functions honor the letter-case of the filenames they get from
|
functions honor the letter-case of the filenames they get from
|
||||||
@ -240,8 +241,8 @@ Notes:
|
|||||||
converted to lower case are explained in the DJGPP libc docs,
|
converted to lower case are explained in the DJGPP libc docs,
|
||||||
under the `_preserve_fncase' and `_lfn_gen_short_fname'
|
under the `_preserve_fncase' and `_lfn_gen_short_fname'
|
||||||
functions, but as a thumb rule, any filename that is stored in
|
functions, but as a thumb rule, any filename that is stored in
|
||||||
upper case in the directory, is a legal DOS 8+3 filename and
|
upper case in the directory, is a valid DOS 8+3 filename and
|
||||||
doesn't include characters illegal on MSDOS FAT filesystems,
|
doesn't include characters invalid on MSDOS FAT filesystems,
|
||||||
will be automatically down-cased.) User reports that I have
|
will be automatically down-cased.) User reports that I have
|
||||||
indicate that this default behavior is generally what you'd
|
indicate that this default behavior is generally what you'd
|
||||||
expect; however, your input is most welcome.
|
expect; however, your input is most welcome.
|
||||||
|
@ -33,3 +33,17 @@
|
|||||||
#define HAVE_MEMMOVE 1
|
#define HAVE_MEMMOVE 1
|
||||||
|
|
||||||
#define SCCS_GET "get"
|
#define SCCS_GET "get"
|
||||||
|
|
||||||
|
/* Define to `unsigned long' or `unsigned long long'
|
||||||
|
if <inttypes.h> doesn't define. */
|
||||||
|
#define uintmax_t unsigned long long
|
||||||
|
|
||||||
|
/* Define the type of the first arg to select(). */
|
||||||
|
#define fd_set_size_t int
|
||||||
|
|
||||||
|
/* Define if you have the select function. */
|
||||||
|
#define HAVE_SELECT 1
|
||||||
|
|
||||||
|
/* Define if you have the vprintf library function. */
|
||||||
|
#undef HAVE_VPRINTF
|
||||||
|
#define HAVE_VPRINTF 1
|
||||||
|
23
function.c
23
function.c
@ -1203,15 +1203,11 @@ windows32_openpipe (int *pipedes, int *pid_p, char **command_argv, char **envp)
|
|||||||
|
|
||||||
|
|
||||||
#ifdef __MSDOS__
|
#ifdef __MSDOS__
|
||||||
/*
|
|
||||||
untested
|
|
||||||
*/
|
|
||||||
int
|
int
|
||||||
msdos_openpipe (int* pipedes, int *pidp, char *text)
|
msdos_openpipe (int* pipedes, int *pidp, char *text)
|
||||||
{
|
{
|
||||||
FILE *fpipe=0;
|
FILE *fpipe=0;
|
||||||
/* MSDOS can't fork, but it has `popen'.
|
/* MSDOS can't fork, but it has `popen'. */
|
||||||
(Bwt, why isn't `popen' used in all the versions?) */
|
|
||||||
struct variable *sh = lookup_variable ("SHELL", 5);
|
struct variable *sh = lookup_variable ("SHELL", 5);
|
||||||
int e;
|
int e;
|
||||||
extern int dos_command_running, dos_status;
|
extern int dos_command_running, dos_status;
|
||||||
@ -1235,6 +1231,9 @@ msdos_openpipe (int* pipedes, int *pidp, char *text)
|
|||||||
errno = 0;
|
errno = 0;
|
||||||
dos_command_running = 1;
|
dos_command_running = 1;
|
||||||
dos_status = 0;
|
dos_status = 0;
|
||||||
|
/* If dos_status becomes non-zero, it means the child process
|
||||||
|
was interrupted by a signal, like SIGINT or SIGQUIT. See
|
||||||
|
fatal_error_signal in commands.c. */
|
||||||
fpipe = popen (text, "rt");
|
fpipe = popen (text, "rt");
|
||||||
dos_command_running = 0;
|
dos_command_running = 0;
|
||||||
if (!fpipe || dos_status)
|
if (!fpipe || dos_status)
|
||||||
@ -1250,7 +1249,7 @@ msdos_openpipe (int* pipedes, int *pidp, char *text)
|
|||||||
else
|
else
|
||||||
{
|
{
|
||||||
pipedes[0] = fileno (fpipe);
|
pipedes[0] = fileno (fpipe);
|
||||||
*pidp = 42; /* uh? The meaning of Life?*/
|
*pidp = 42; /* Yes, the Meaning of Life, the Universe, and Everything! */
|
||||||
errno = e;
|
errno = e;
|
||||||
shell_function_completed = 1;
|
shell_function_completed = 1;
|
||||||
}
|
}
|
||||||
@ -1308,11 +1307,9 @@ func_shell (o, argv, funcname)
|
|||||||
/* For error messages. */
|
/* For error messages. */
|
||||||
if (reading_file != 0)
|
if (reading_file != 0)
|
||||||
{
|
{
|
||||||
error_prefix = (char *) alloca (strlen(reading_file->filenm)+100);
|
error_prefix = (char *) alloca (strlen(reading_file->filenm)+100);
|
||||||
|
|
||||||
sprintf (error_prefix,
|
sprintf (error_prefix,
|
||||||
"%s:%lu: ", reading_file->filenm, reading_file->lineno);
|
"%s:%lu: ", reading_file->filenm, reading_file->lineno);
|
||||||
|
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
error_prefix = "";
|
error_prefix = "";
|
||||||
@ -1322,11 +1319,11 @@ func_shell (o, argv, funcname)
|
|||||||
#else /* WINDOWS32 */
|
#else /* WINDOWS32 */
|
||||||
|
|
||||||
# ifdef __MSDOS__
|
# ifdef __MSDOS__
|
||||||
fpipe = msdos_openpipe (pipedes, argv[0], command_argv, envp);
|
fpipe = msdos_openpipe (pipedes, &pid, argv[0]);
|
||||||
if (!fpipe || pipedes[0] < 0)
|
if (pipedes[0] < 0)
|
||||||
{
|
{
|
||||||
perror_with_name (error_prefix, "pipe");
|
perror_with_name (error_prefix, "pipe");
|
||||||
return o;
|
return o;
|
||||||
}
|
}
|
||||||
# else
|
# else
|
||||||
if (pipe (pipedes) < 0)
|
if (pipe (pipedes) < 0)
|
||||||
|
127
job.c
127
job.c
@ -299,21 +299,30 @@ vmsWaitForChildren(int *status)
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
||||||
/* Count the number of dead children we have. If we can use wait3() or
|
/* Handle a dead child. This handler may or may not ever be installed.
|
||||||
waitpid() then we'll never use this count: it's completely unnecessary.
|
|
||||||
But we need the handler installed to interrupt the select() call for
|
If we're using the jobserver blocking read, we need it. First, installing
|
||||||
the jobs pipe, so we might as well keep it. */
|
it ensures the read will interrupt on SIGCHLD. Second, we close the dup'd
|
||||||
|
read side of the pipe to ensure we don't enter another blocking read
|
||||||
|
without reaping all the dead children. In this case we don't need the
|
||||||
|
dead_children count.
|
||||||
|
|
||||||
|
If we don't have either waitpid or wait3, then make is unreliable, but we
|
||||||
|
use the dead_children count to reap children as best we can. In this case
|
||||||
|
job_rfd will never be >= 0. */
|
||||||
|
|
||||||
static unsigned int dead_children = 0;
|
static unsigned int dead_children = 0;
|
||||||
|
|
||||||
/* Notice that a child died.
|
|
||||||
reap_children should be called when convenient. */
|
|
||||||
RETSIGTYPE
|
RETSIGTYPE
|
||||||
child_handler (sig)
|
child_handler (sig)
|
||||||
int sig;
|
int sig;
|
||||||
{
|
{
|
||||||
++dead_children;
|
++dead_children;
|
||||||
|
|
||||||
|
if (job_rfd >= 0)
|
||||||
|
close (job_rfd);
|
||||||
|
job_rfd = -1;
|
||||||
|
|
||||||
if (debug_flag)
|
if (debug_flag)
|
||||||
printf (_("Got a SIGCHLD; %u unreaped children.\n"), dead_children);
|
printf (_("Got a SIGCHLD; %u unreaped children.\n"), dead_children);
|
||||||
}
|
}
|
||||||
@ -927,12 +936,7 @@ start_job_command (child)
|
|||||||
/* Set the descriptor to close on exec, so it does not litter any
|
/* Set the descriptor to close on exec, so it does not litter any
|
||||||
child's descriptor table. When it is dup2'd onto descriptor 0,
|
child's descriptor table. When it is dup2'd onto descriptor 0,
|
||||||
that descriptor will not close on exec. */
|
that descriptor will not close on exec. */
|
||||||
#ifdef F_SETFD
|
CLOSE_ON_EXEC (bad_stdin);
|
||||||
#ifndef FD_CLOEXEC
|
|
||||||
#define FD_CLOEXEC 1
|
|
||||||
#endif
|
|
||||||
(void) fcntl (bad_stdin, F_SETFD, FD_CLOEXEC);
|
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1170,57 +1174,6 @@ start_waiting_job (c)
|
|||||||
/* If not, start it locally. */
|
/* If not, start it locally. */
|
||||||
if (!c->remote)
|
if (!c->remote)
|
||||||
{
|
{
|
||||||
#ifdef MAKE_JOBSERVER
|
|
||||||
/* If we are controlling multiple jobs, and we don't yet have one,
|
|
||||||
* obtain a token before starting the child. */
|
|
||||||
if (job_fds[0] >= 0)
|
|
||||||
{
|
|
||||||
while (c->job_token == '-')
|
|
||||||
/* If the reserved token is available, just use that. */
|
|
||||||
if (my_job_token != '-')
|
|
||||||
{
|
|
||||||
c->job_token = my_job_token;
|
|
||||||
my_job_token = '-';
|
|
||||||
}
|
|
||||||
/* Read a token. We set the non-blocking bit on this earlier, so
|
|
||||||
if there's no token to be read we'll return immediately. */
|
|
||||||
else if (read (job_fds[0], &c->job_token, 1) < 1)
|
|
||||||
{
|
|
||||||
fd_set rfds;
|
|
||||||
int r;
|
|
||||||
|
|
||||||
FD_ZERO(&rfds);
|
|
||||||
FD_SET(job_fds[0], &rfds);
|
|
||||||
|
|
||||||
/* The select blocks until (a) there's data to read, in which
|
|
||||||
case we come back around and try to grab the token before
|
|
||||||
someone else does, or (b) a signal (SIGCHLD), is reported
|
|
||||||
(because we installed a handler for it). If the latter,
|
|
||||||
call reap_children() to try to free up some slots. */
|
|
||||||
|
|
||||||
r = select (job_fds[0]+1, SELECT_FD_SET_CAST &rfds,
|
|
||||||
NULL, NULL, NULL);
|
|
||||||
|
|
||||||
if (r < 0)
|
|
||||||
{
|
|
||||||
#ifdef EINTR
|
|
||||||
if (errno != EINTR)
|
|
||||||
/* We should definitely handle this more gracefully!
|
|
||||||
What kinds of things can happen here? ^C closes the
|
|
||||||
pipe? Something else closes it? */
|
|
||||||
pfatal_with_name (_("read jobs pipe"));
|
|
||||||
#endif
|
|
||||||
/* We were interrupted; handle any dead children. */
|
|
||||||
reap_children (1, 0);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
assert(c->job_token != '-');
|
|
||||||
if (debug_flag)
|
|
||||||
printf (_("Obtained token `%c' for child 0x%08lx (%s).\n"),
|
|
||||||
c->job_token, (unsigned long int) c, c->file->name);
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
/* If we are running at least one job already and the load average
|
/* If we are running at least one job already and the load average
|
||||||
is too high, make this one wait. */
|
is too high, make this one wait. */
|
||||||
if (job_slots_used > 0 && load_too_high ())
|
if (job_slots_used > 0 && load_too_high ())
|
||||||
@ -1291,12 +1244,6 @@ new_job (file)
|
|||||||
/* Chop the commands up into lines if they aren't already. */
|
/* Chop the commands up into lines if they aren't already. */
|
||||||
chop_commands (cmds);
|
chop_commands (cmds);
|
||||||
|
|
||||||
/* Wait for a job slot to be freed up. If we allow an infinite number
|
|
||||||
don't bother; also job_slots will == 0 if we're using the job pipe. */
|
|
||||||
if (job_slots != 0)
|
|
||||||
while (job_slots_used == job_slots)
|
|
||||||
reap_children (1, 0);
|
|
||||||
|
|
||||||
/* Expand the command lines and store the results in LINES. */
|
/* Expand the command lines and store the results in LINES. */
|
||||||
lines = (char **) xmalloc (cmds->ncommand_lines * sizeof (char *));
|
lines = (char **) xmalloc (cmds->ncommand_lines * sizeof (char *));
|
||||||
for (i = 0; i < cmds->ncommand_lines; ++i)
|
for (i = 0; i < cmds->ncommand_lines; ++i)
|
||||||
@ -1413,6 +1360,48 @@ new_job (file)
|
|||||||
/* Fetch the first command line to be run. */
|
/* Fetch the first command line to be run. */
|
||||||
job_next_command (c);
|
job_next_command (c);
|
||||||
|
|
||||||
|
/* Wait for a job slot to be freed up. If we allow an infinite number
|
||||||
|
don't bother; also job_slots will == 0 if we're using the jobserver. */
|
||||||
|
if (job_slots != 0)
|
||||||
|
while (job_slots_used == job_slots)
|
||||||
|
reap_children (1, 0);
|
||||||
|
#ifdef MAKE_JOBSERVER
|
||||||
|
/* If we are controlling multiple jobs, and we don't yet have one,
|
||||||
|
obtain a token before starting the child. */
|
||||||
|
else if (job_fds[0] >= 0)
|
||||||
|
{
|
||||||
|
while (c->job_token == '-')
|
||||||
|
/* If the reserved token is available, just use that. */
|
||||||
|
if (my_job_token == '+')
|
||||||
|
{
|
||||||
|
c->job_token = my_job_token;
|
||||||
|
my_job_token = '-';
|
||||||
|
}
|
||||||
|
/* Read a token. As long as there's no token available we'll block.
|
||||||
|
If we get a SIGCHLD we'll return with EINTR. If one happened
|
||||||
|
before we got here we'll return with EBADF. */
|
||||||
|
else if (read (job_rfd, &c->job_token, 1) < 1)
|
||||||
|
{
|
||||||
|
if (errno == EINTR)
|
||||||
|
;
|
||||||
|
|
||||||
|
/* If EBADF, we got a SIGCHLD before. Otherwise, who knows? */
|
||||||
|
else if (errno != EBADF)
|
||||||
|
pfatal_with_name (_("read jobs pipe"));
|
||||||
|
|
||||||
|
/* Something's done; reap it. We don't force a block here; if
|
||||||
|
something strange happened and nothing's ready, just come back
|
||||||
|
and wait some more. */
|
||||||
|
reap_children (0, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
assert(c->job_token != '-');
|
||||||
|
if (debug_flag)
|
||||||
|
printf (_("Obtained token `%c' for child 0x%08lx (%s).\n"),
|
||||||
|
c->job_token, (unsigned long int) c, c->file->name);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
/* The job is now primed. Start it running.
|
/* The job is now primed. Start it running.
|
||||||
(This will notice if there are in fact no commands.) */
|
(This will notice if there are in fact no commands.) */
|
||||||
(void)start_waiting_job (c);
|
(void)start_waiting_job (c);
|
||||||
|
65
main.c
65
main.c
@ -205,6 +205,7 @@ static unsigned int inf_jobs = 0;
|
|||||||
/* File descriptors for the jobs pipe. */
|
/* File descriptors for the jobs pipe. */
|
||||||
|
|
||||||
int job_fds[2] = { -1, -1 };
|
int job_fds[2] = { -1, -1 };
|
||||||
|
int job_rfd = -1;
|
||||||
|
|
||||||
/* Maximum load average at which multiple jobs will be run.
|
/* Maximum load average at which multiple jobs will be run.
|
||||||
Negative values mean unlimited, while zero means limit to
|
Negative values mean unlimited, while zero means limit to
|
||||||
@ -251,7 +252,7 @@ static const struct command_switch switches[] =
|
|||||||
0, 0,
|
0, 0,
|
||||||
_("Ignored for compatibility") },
|
_("Ignored for compatibility") },
|
||||||
{ 'C', string, (char *) &directories, 0, 0, 0, 0, 0,
|
{ 'C', string, (char *) &directories, 0, 0, 0, 0, 0,
|
||||||
"directory", "DIRECTORY",
|
"directory", _("DIRECTORY"),
|
||||||
_("Change to DIRECTORY before doing anything") },
|
_("Change to DIRECTORY before doing anything") },
|
||||||
{ 'd', flag, (char *) &debug_flag, 1, 1, 0, 0, 0,
|
{ 'd', flag, (char *) &debug_flag, 1, 1, 0, 0, 0,
|
||||||
"debug", 0,
|
"debug", 0,
|
||||||
@ -265,7 +266,7 @@ static const struct command_switch switches[] =
|
|||||||
"environment-overrides", 0,
|
"environment-overrides", 0,
|
||||||
_("Environment variables override makefiles") },
|
_("Environment variables override makefiles") },
|
||||||
{ 'f', string, (char *) &makefiles, 0, 0, 0, 0, 0,
|
{ 'f', string, (char *) &makefiles, 0, 0, 0, 0, 0,
|
||||||
"file", "FILE",
|
"file", _("FILE"),
|
||||||
_("Read FILE as a makefile") },
|
_("Read FILE as a makefile") },
|
||||||
{ 'h', flag, (char *) &print_usage_flag, 0, 0, 0, 0, 0,
|
{ 'h', flag, (char *) &print_usage_flag, 0, 0, 0, 0, 0,
|
||||||
"help", 0,
|
"help", 0,
|
||||||
@ -274,7 +275,7 @@ static const struct command_switch switches[] =
|
|||||||
"ignore-errors", 0,
|
"ignore-errors", 0,
|
||||||
_("Ignore errors from commands") },
|
_("Ignore errors from commands") },
|
||||||
{ 'I', string, (char *) &include_directories, 1, 1, 0, 0, 0,
|
{ 'I', string, (char *) &include_directories, 1, 1, 0, 0, 0,
|
||||||
"include-dir", "DIRECTORY",
|
"include-dir", _("DIRECTORY"),
|
||||||
_("Search DIRECTORY for included makefiles") },
|
_("Search DIRECTORY for included makefiles") },
|
||||||
{ 'j',
|
{ 'j',
|
||||||
#ifndef MAKE_JOBSERVER
|
#ifndef MAKE_JOBSERVER
|
||||||
@ -307,7 +308,7 @@ static const struct command_switch switches[] =
|
|||||||
"just-print", 0,
|
"just-print", 0,
|
||||||
_("Don't actually run any commands; just print them") },
|
_("Don't actually run any commands; just print them") },
|
||||||
{ 'o', string, (char *) &old_files, 0, 0, 0, 0, 0,
|
{ 'o', string, (char *) &old_files, 0, 0, 0, 0, 0,
|
||||||
"old-file", "FILE",
|
"old-file", _("FILE"),
|
||||||
_("Consider FILE to be very old and don't remake it") },
|
_("Consider FILE to be very old and don't remake it") },
|
||||||
{ 'p', flag, (char *) &print_data_base_flag, 1, 1, 0, 0, 0,
|
{ 'p', flag, (char *) &print_data_base_flag, 1, 1, 0, 0, 0,
|
||||||
"print-data-base", 0,
|
"print-data-base", 0,
|
||||||
@ -341,7 +342,7 @@ static const struct command_switch switches[] =
|
|||||||
"no-print-directory", 0,
|
"no-print-directory", 0,
|
||||||
_("Turn off -w, even if it was turned on implicitly") },
|
_("Turn off -w, even if it was turned on implicitly") },
|
||||||
{ 'W', string, (char *) &new_files, 0, 0, 0, 0, 0,
|
{ 'W', string, (char *) &new_files, 0, 0, 0, 0, 0,
|
||||||
"what-if", "FILE",
|
"what-if", _("FILE"),
|
||||||
_("Consider FILE to be infinitely new") },
|
_("Consider FILE to be infinitely new") },
|
||||||
{ 3, flag, (char *) &warn_undefined_variables_flag, 1, 1, 0, 0, 0,
|
{ 3, flag, (char *) &warn_undefined_variables_flag, 1, 1, 0, 0, 0,
|
||||||
"warn-undefined-variables", 0,
|
"warn-undefined-variables", 0,
|
||||||
@ -1168,31 +1169,36 @@ int main (int argc, char ** argv)
|
|||||||
}
|
}
|
||||||
|
|
||||||
#if defined(MAKE_JOBSERVER) || !defined(HAVE_WAIT_NOHANG)
|
#if defined(MAKE_JOBSERVER) || !defined(HAVE_WAIT_NOHANG)
|
||||||
/* If we don't have a hanging wait we have to fall back to old, broken
|
/* Set up to handle children dying. This must be done before
|
||||||
|
reading in the makefiles so that `shell' function calls will work.
|
||||||
|
|
||||||
|
If we don't have a hanging wait we have to fall back to old, broken
|
||||||
functionality here and rely on the signal handler and counting
|
functionality here and rely on the signal handler and counting
|
||||||
children.
|
children.
|
||||||
|
|
||||||
If we're using the jobs pipe we need a signal handler so that
|
If we're using the jobs pipe we need a signal handler so that
|
||||||
SIGCHLD is not ignored; we need it to interrupt select(2) in
|
SIGCHLD is not ignored; we need it to interrupt the read(2) of the
|
||||||
job.c:start_waiting_job() if we're waiting on the pipe for a token.
|
jobserver pipe in job.c if we're waiting for a token.
|
||||||
|
|
||||||
Use sigaction where possible as it's more reliable. */
|
If none of these are true, we don't need a signal handler at all. */
|
||||||
{
|
{
|
||||||
extern RETSIGTYPE child_handler PARAMS ((int sig));
|
extern RETSIGTYPE child_handler PARAMS ((int sig));
|
||||||
|
|
||||||
/* Set up to handle children dying. This must be done before
|
# if defined HAVE_SIGACTION
|
||||||
reading in the makefiles so that `shell' function calls will work. */
|
|
||||||
|
|
||||||
#ifndef HAVE_SIGACTION
|
|
||||||
# define HANDLESIG(s) signal(s, child_handler)
|
|
||||||
#else
|
|
||||||
# define HANDLESIG(s) sigaction(s, &sa, NULL)
|
|
||||||
struct sigaction sa;
|
struct sigaction sa;
|
||||||
|
|
||||||
bzero ((char *)&sa, sizeof (struct sigaction));
|
bzero ((char *)&sa, sizeof (struct sigaction));
|
||||||
sa.sa_handler = child_handler;
|
sa.sa_handler = child_handler;
|
||||||
#endif
|
# if defined SA_INTERRUPT
|
||||||
|
/* This is supposed to be the default, but what the heck... */
|
||||||
|
sa.sa_flags = SA_INTERRUPT;
|
||||||
|
# endif
|
||||||
|
# define HANDLESIG(s) sigaction(s, &sa, NULL)
|
||||||
|
# else
|
||||||
|
# define HANDLESIG(s) signal(s, child_handler)
|
||||||
|
# endif
|
||||||
|
|
||||||
|
/* OK, now actually install the handlers. */
|
||||||
# if defined SIGCHLD
|
# if defined SIGCHLD
|
||||||
(void) HANDLESIG (SIGCHLD);
|
(void) HANDLESIG (SIGCHLD);
|
||||||
# endif
|
# endif
|
||||||
@ -1287,12 +1293,12 @@ int main (int argc, char ** argv)
|
|||||||
and write FDs, respectively, for the pipe. Note this last form is
|
and write FDs, respectively, for the pipe. Note this last form is
|
||||||
undocumented for the user! */
|
undocumented for the user! */
|
||||||
|
|
||||||
sscanf(job_slots_str, "%d", &job_slots);
|
sscanf (job_slots_str, "%d", &job_slots);
|
||||||
{
|
{
|
||||||
char *cp = index(job_slots_str, ',');
|
char *cp = index (job_slots_str, ',');
|
||||||
|
|
||||||
/* In case #4, get the FDs. */
|
/* In case #4, get the FDs. */
|
||||||
if (cp && sscanf(cp+1, "%d", &job_fds[1]) == 1)
|
if (cp && sscanf (cp+1, "%d", &job_fds[1]) == 1)
|
||||||
{
|
{
|
||||||
/* Set up the first FD and set job_slots to 0. The combination of a
|
/* Set up the first FD and set job_slots to 0. The combination of a
|
||||||
pipe + !job_slots means we're using the jobserver. If !job_slots
|
pipe + !job_slots means we're using the jobserver. If !job_slots
|
||||||
@ -1326,10 +1332,6 @@ int main (int argc, char ** argv)
|
|||||||
if (pipe (job_fds) < 0)
|
if (pipe (job_fds) < 0)
|
||||||
pfatal_with_name (_("creating jobs pipe"));
|
pfatal_with_name (_("creating jobs pipe"));
|
||||||
|
|
||||||
/* Set the read FD to nonblocking; we'll use select() to wait
|
|
||||||
for it in job.c. */
|
|
||||||
fcntl (job_fds[0], F_SETFL, O_NONBLOCK);
|
|
||||||
|
|
||||||
/* Every make assumes that it always has one job it can run. For the
|
/* Every make assumes that it always has one job it can run. For the
|
||||||
submakes it's the token they were given by their parent. For the
|
submakes it's the token they were given by their parent. For the
|
||||||
top make, we just subtract one from the number the user wants. */
|
top make, we just subtract one from the number the user wants. */
|
||||||
@ -1350,6 +1352,16 @@ int main (int argc, char ** argv)
|
|||||||
sprintf(buf, "%d,%d", job_fds[0], job_fds[1]);
|
sprintf(buf, "%d,%d", job_fds[0], job_fds[1]);
|
||||||
job_slots_str = xstrdup(buf);
|
job_slots_str = xstrdup(buf);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* If we have a jobserver pipe, dup(2) the read end. We'll use that in
|
||||||
|
the child handler to note a child has died. See job.c. */
|
||||||
|
|
||||||
|
if (job_fds[0] >= 0)
|
||||||
|
{
|
||||||
|
job_rfds = dup (job_fds[0]);
|
||||||
|
CLOSE_ON_EXEC (job_rfds);
|
||||||
|
}
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/* Set up MAKEFLAGS and MFLAGS again, so they will be right. */
|
/* Set up MAKEFLAGS and MFLAGS again, so they will be right. */
|
||||||
@ -1533,7 +1545,8 @@ int main (int argc, char ** argv)
|
|||||||
if (d->changed & RM_INCLUDED)
|
if (d->changed & RM_INCLUDED)
|
||||||
/* An included makefile. We don't need
|
/* An included makefile. We don't need
|
||||||
to die, but we do want to complain. */
|
to die, but we do want to complain. */
|
||||||
error (NILF, _("Included makefile `%s' was not found."),
|
error (NILF,
|
||||||
|
_("Included makefile `%s' was not found."),
|
||||||
dep_name (d));
|
dep_name (d));
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
@ -1877,7 +1890,7 @@ print_usage (bad)
|
|||||||
|
|
||||||
usageto = bad ? stderr : stdout;
|
usageto = bad ? stderr : stdout;
|
||||||
|
|
||||||
fprintf (usageto, "Usage: %s [options] [target] ...\n", program);
|
fprintf (usageto, _("Usage: %s [options] [target] ...\n"), program);
|
||||||
|
|
||||||
fputs (_("Options:\n"), usageto);
|
fputs (_("Options:\n"), usageto);
|
||||||
for (cs = switches; cs->c != '\0'; ++cs)
|
for (cs = switches; cs->c != '\0'; ++cs)
|
||||||
|
14
read.c
14
read.c
@ -658,8 +658,7 @@ read_makefile (filename, flags)
|
|||||||
if (*p == '\0')
|
if (*p == '\0')
|
||||||
{
|
{
|
||||||
error (&fileinfo,
|
error (&fileinfo,
|
||||||
_("no file name for `%sinclude'"),
|
_("no file name for `%sinclude'"), noerror ? "-" : "");
|
||||||
noerror ? "-" : "");
|
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -692,8 +691,7 @@ read_makefile (filename, flags)
|
|||||||
if (! read_makefile (name, (RM_INCLUDED | RM_NO_TILDE
|
if (! read_makefile (name, (RM_INCLUDED | RM_NO_TILDE
|
||||||
| (noerror ? RM_DONTCARE : 0)))
|
| (noerror ? RM_DONTCARE : 0)))
|
||||||
&& ! noerror)
|
&& ! noerror)
|
||||||
error (&fileinfo,
|
error (&fileinfo, "%s: %s", name, strerror (errno));
|
||||||
"%s: %s", name, strerror (errno));
|
|
||||||
free(name);
|
free(name);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1442,7 +1440,7 @@ record_target_var (filenames, defn, two_colon, origin, flocp)
|
|||||||
|
|
||||||
/* Make the new variable context current and define the variable. */
|
/* Make the new variable context current and define the variable. */
|
||||||
current_variable_set_list = vlist;
|
current_variable_set_list = vlist;
|
||||||
v = try_variable_definition(flocp, defn, origin);
|
v = try_variable_definition (flocp, defn, origin);
|
||||||
if (!v)
|
if (!v)
|
||||||
error (flocp, _("Malformed per-target variable definition"));
|
error (flocp, _("Malformed per-target variable definition"));
|
||||||
v->per_target = 1;
|
v->per_target = 1;
|
||||||
@ -1455,10 +1453,10 @@ record_target_var (filenames, defn, two_colon, origin, flocp)
|
|||||||
int len = strlen(v->name);
|
int len = strlen(v->name);
|
||||||
|
|
||||||
current_variable_set_list = global;
|
current_variable_set_list = global;
|
||||||
gv = lookup_variable(v->name, len);
|
gv = lookup_variable (v->name, len);
|
||||||
if (gv && (gv->origin == o_env_override || gv->origin == o_command))
|
if (gv && (gv->origin == o_env_override || gv->origin == o_command))
|
||||||
define_variable_in_set(v->name, len, gv->value, gv->origin,
|
define_variable_in_set (v->name, len, gv->value, gv->origin,
|
||||||
gv->recursive, vlist->set);
|
gv->recursive, vlist->set);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Free name if not needed further. */
|
/* Free name if not needed further. */
|
||||||
|
Loading…
Reference in New Issue
Block a user