* Applied some DOS updates.

* Started reworking the jobserver algorithm; not complete yet.
This commit is contained in:
Paul Smith 1999-08-01 06:05:17 +00:00
parent 28ef4c4dac
commit 09f1e4cf83
9 changed files with 171 additions and 132 deletions

View File

@ -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.

View File

@ -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:

View File

@ -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.

View File

@ -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

View File

@ -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
View File

@ -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
View File

@ -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
View File

@ -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. */

View File

@ -32,10 +32,6 @@ Boston, MA 02111-1307, USA. */
#include <sys/file.h> #include <sys/file.h>
#endif #endif
#ifdef __MSDOS__
#include "variable.h"
#endif
#ifdef VMS #ifdef VMS
#include <starlet.h> #include <starlet.h>
#endif #endif