mirror of
https://github.com/mirror/make.git
synced 2025-01-26 20:30:36 +08:00
Fix for EINTR problems when using jobserver.
New translation files. Fix for @+ inside define macros being applied too widely. Various other bug fixes.
This commit is contained in:
parent
5d582d4ba0
commit
ce2c6eadf1
55
ChangeLog
55
ChangeLog
@ -1,3 +1,45 @@
|
||||
2001-05-06 Paul D. Smith <psmith@gnu.org>
|
||||
|
||||
Modify the EINTR handling.
|
||||
|
||||
* job.c (new_job): Reorganize the jobserver algorithm. Reorder
|
||||
the way in which we manage the file descriptor/signal handler race
|
||||
trap to be more efficient.
|
||||
|
||||
2001-05-06 Paul Eggert <eggert@twinsun.com>
|
||||
|
||||
Restart almost all system calls that are interrupted, instead
|
||||
of worrying about EINTR. The lone exception is the read() for
|
||||
job tokens.
|
||||
|
||||
* configure.in (HAVE_SA_RESTART): New macro.
|
||||
(MAKE_JOBSERVER): Define to 1 only if HAVE_SA_RESTART.
|
||||
* main.c (main): Use SA_RESTART instead of the old,
|
||||
nonstandard SA_INTERRUPT.
|
||||
|
||||
* configure.in (AC_CHECK_FUNCS): Add bsd_signal.
|
||||
* main.c (bsd_signal): New function or macro,
|
||||
if the implementation doesn't supply it.
|
||||
(The bsd_signal function will be in POSIX 1003.1-200x.)
|
||||
(HANDLESIG): Remove.
|
||||
(main, FATAL_SIG): Use bsd_signal instead of signal or HANDLESIG.
|
||||
|
||||
* make.h (EINTR_SET): Remove.
|
||||
(SA_RESTART): New macro.
|
||||
|
||||
* arscan.c (ar_member_touch): Don't worry about EINTR.
|
||||
* function.c (func_shell): Likewise.
|
||||
* job.c (reap_children, free_child, new_job): Likewise.
|
||||
* main.c (main): Likewise.
|
||||
* remake.c (touch_file, name_mtime): Likewise.
|
||||
|
||||
* arscan.c (ar_member_touch): Fix bug uncovered by EINTR removal;
|
||||
if fstat failed with errno!=EINTR, the error was ignored.
|
||||
|
||||
* job.c (set_child_handler_action_flags): New function.
|
||||
(new_job): Use it to temporarily clear the SIGCHLD action flags
|
||||
while reading the token.
|
||||
|
||||
2001-05-02 Paul D. Smith <psmith@gnu.org>
|
||||
|
||||
* job.c (start_job_command): Don't add define/endef per-line flags
|
||||
@ -11,6 +53,19 @@
|
||||
(VMS_get_member_info): Calculate the timezone differences correctly.
|
||||
Reported by John Fowler <jfowler@nyx.net>.
|
||||
|
||||
|
||||
2001-03-14 Paul D. Smith <psmith@gnu.org>
|
||||
|
||||
* variable.c (lookup_variable) [VMS]: Null-terminate the variable
|
||||
value before invoking define_variable().
|
||||
Reported by John Fowler <jfowler@nyx.net>.
|
||||
|
||||
2001-02-07 Paul D. Smith <psmith@gnu.org>
|
||||
|
||||
* read.c (record_target_var): If we reset the variable due to a
|
||||
command-line variable setting overriding it, turn off the "append"
|
||||
flag.
|
||||
|
||||
2001-01-17 Paul D. Smith <psmith@gnu.org>
|
||||
|
||||
* variable.c (lookup_variable) [VMS]: When getting values from the
|
||||
|
9
NEWS
9
NEWS
@ -1,8 +1,8 @@
|
||||
GNU make NEWS -*-indented-text-*-
|
||||
History of user-visible changes.
|
||||
23 Jun 2000
|
||||
30 May 2001
|
||||
|
||||
Copyright (C) 1992,93,94,95,96,97,98,99,2000 Free Software Foundation, Inc.
|
||||
Copyright (C) 1992,93,94,95,96,97,98,99,2000,2001 Free Software Foundation, Inc.
|
||||
See the end for copying conditions.
|
||||
|
||||
All changes mentioned here are more fully described in the GNU make
|
||||
@ -12,12 +12,17 @@ Please send GNU make bug reports to <bug-make@gnu.org>.
|
||||
See the README file and the GNU make manual for details on sending bug
|
||||
reports.
|
||||
|
||||
Version 3.79.2
|
||||
|
||||
* New pseudo-target .LOW_RESOLUTION_TIME, superseding the configure
|
||||
option --disable-nsec-timestamps. You might need this if your build
|
||||
process depends on tools like "cp -p" preserving time stamps, since
|
||||
"cp -p" (right now) doesn't preserve the subsecond portion of a time
|
||||
stamp.
|
||||
|
||||
* Updated translations for Galician, Japanese, and Russian, and a new
|
||||
Turkish translation.
|
||||
|
||||
Version 3.79.1
|
||||
|
||||
* .SECONDARY with no prerequisites now prevents any target from being
|
||||
|
4
arscan.c
4
arscan.c
@ -797,8 +797,8 @@ ar_member_touch (arname, memname)
|
||||
if (AR_HDR_SIZE != write (fd, (char *) &ar_hdr, AR_HDR_SIZE))
|
||||
goto lose;
|
||||
/* The file's mtime is the time we we want. */
|
||||
while (fstat (fd, &statbuf) < 0 && EINTR_SET)
|
||||
;
|
||||
if (fstat (fd, &statbuf) < 0)
|
||||
goto lose;
|
||||
#if defined(ARFMAG) || defined(ARFZMAG) || defined(AIAMAG) || defined(WINDOWS32)
|
||||
/* Advance member's time to that time */
|
||||
for (i = 0; i < sizeof ar_hdr.ar_date; i++)
|
||||
|
26
configure.in
26
configure.in
@ -3,7 +3,7 @@ AC_REVISION([$Id$])
|
||||
AC_PREREQ(2.13)dnl dnl Minimum Autoconf version required.
|
||||
AC_INIT(vpath.c)dnl dnl A distinctive file to look for in srcdir.
|
||||
|
||||
AM_INIT_AUTOMAKE(make, 3.79.1.0)
|
||||
AM_INIT_AUTOMAKE(make, 3.79.1.90)
|
||||
AM_CONFIG_HEADER(config.h)
|
||||
|
||||
dnl Regular configure stuff
|
||||
@ -42,7 +42,7 @@ AC_HEADER_TIME
|
||||
|
||||
dnl Handle internationalization
|
||||
|
||||
ALL_LINGUAS="de es fr gl ja ko nl pl pt_BR ru"
|
||||
ALL_LINGUAS="de es fr gl ja ko nl pl pt_BR ru tr"
|
||||
pds_WITH_GETTEXT
|
||||
|
||||
jm_AC_TYPE_UINTMAX_T
|
||||
@ -113,8 +113,9 @@ if test $ac_cv_func_gettimeofday = yes; then
|
||||
fi
|
||||
|
||||
AC_CHECK_FUNCS( memmove memcpy strchr strdup psignal mkstemp mktemp fdopen \
|
||||
dup2 getcwd sigsetmask sigaction getgroups setlinebuf \
|
||||
seteuid setegid setreuid setregid pipe strerror strsignal)
|
||||
bsd_signal dup2 getcwd sigsetmask sigaction getgroups \
|
||||
setlinebuf seteuid setegid setreuid setregid pipe \
|
||||
strerror strsignal)
|
||||
|
||||
AC_CHECK_SYMBOL(sys_siglist)
|
||||
AC_FUNC_ALLOCA
|
||||
@ -196,9 +197,20 @@ case "$ac_cv_func_waitpid/$ac_cv_func_wait3" in
|
||||
no/no) has_wait_nohang=no ;;
|
||||
esac
|
||||
|
||||
case "$ac_cv_func_pipe/$ac_cv_func_sigaction/$has_wait_nohang/$make_cv_job_server" in
|
||||
yes/yes/yes/yes) AC_DEFINE(MAKE_JOBSERVER, 1,
|
||||
[Define this to enable job server support in GNU make.]);;
|
||||
AC_CACHE_CHECK(for SA_RESTART, make_cv_sa_restart, [
|
||||
AC_TRY_COMPILE([#include <signal.h>],
|
||||
[return SA_RESTART;],
|
||||
make_cv_sa_restart=yes,
|
||||
make_cv_sa_restart=no)])
|
||||
if test "$make_cv_sa_restart" != no; then
|
||||
AC_DEFINE(HAVE_SA_RESTART, 1,
|
||||
[Define if <signal.h> defines the SA_RESTART constant.])
|
||||
fi
|
||||
|
||||
case "$ac_cv_func_pipe/$ac_cv_func_sigaction/$make_cv_sa_restart/$has_wait_nohang/$make_cv_job_server" in
|
||||
yes/yes/yes/yes/yes)
|
||||
AC_DEFINE(MAKE_JOBSERVER, 1,
|
||||
[Define this to enable job server support in GNU make.]);;
|
||||
esac
|
||||
|
||||
dnl Allow building with dmalloc
|
||||
|
10
dir.c
10
dir.c
@ -725,7 +725,7 @@ file_impossible (filename)
|
||||
dir = find_directory ("[]");
|
||||
#else
|
||||
dirend = strrchr (p, '/');
|
||||
#if defined (WINDOWS32) || defined (__MSDOS__)
|
||||
# if defined (WINDOWS32) || defined (__MSDOS__)
|
||||
/* Forward and backslashes might be mixed. We need the rightmost one. */
|
||||
{
|
||||
char *bslash = strrchr(p, '\\');
|
||||
@ -735,13 +735,13 @@ file_impossible (filename)
|
||||
if (!dirend && p[0] && p[1] == ':')
|
||||
dirend = p + 1;
|
||||
}
|
||||
#endif /* WINDOWS32 or __MSDOS__ */
|
||||
# endif /* WINDOWS32 or __MSDOS__ */
|
||||
if (dirend == 0)
|
||||
#ifdef _AMIGA
|
||||
# ifdef _AMIGA
|
||||
dir = find_directory ("");
|
||||
#else /* !VMS && !AMIGA */
|
||||
# else /* !VMS && !AMIGA */
|
||||
dir = find_directory (".");
|
||||
#endif /* AMIGA */
|
||||
# endif /* AMIGA */
|
||||
#endif /* VMS */
|
||||
else
|
||||
{
|
||||
|
@ -1435,8 +1435,7 @@ func_shell (o, argv, funcname)
|
||||
buffer = (char *) xmalloc (maxlen + 1);
|
||||
|
||||
/* Read from the pipe until it gets EOF. */
|
||||
i = 0;
|
||||
do
|
||||
for (i = 0; ; i += cc)
|
||||
{
|
||||
if (i == maxlen)
|
||||
{
|
||||
@ -1444,12 +1443,10 @@ func_shell (o, argv, funcname)
|
||||
buffer = (char *) xrealloc (buffer, maxlen + 1);
|
||||
}
|
||||
|
||||
errno = 0;
|
||||
cc = read (pipedes[0], &buffer[i], maxlen - i);
|
||||
if (cc > 0)
|
||||
i += cc;
|
||||
if (cc <= 0)
|
||||
break;
|
||||
}
|
||||
while (cc > 0 || EINTR_SET);
|
||||
buffer[i] = '\0';
|
||||
|
||||
/* Close the read side of the pipe. */
|
||||
|
458
i18n/gl.po
458
i18n/gl.po
File diff suppressed because it is too large
Load Diff
2437
i18n/ru.po
2437
i18n/ru.po
File diff suppressed because it is too large
Load Diff
104
job.c
104
job.c
@ -436,8 +436,8 @@ reap_children (block, err)
|
||||
|
||||
we'll keep reaping children. */
|
||||
|
||||
while ((children != 0 || shell_function_pid != 0) &&
|
||||
(block || REAP_MORE))
|
||||
while ((children != 0 || shell_function_pid != 0)
|
||||
&& (block || REAP_MORE))
|
||||
{
|
||||
int remote = 0;
|
||||
register int pid;
|
||||
@ -500,9 +500,6 @@ reap_children (block, err)
|
||||
{
|
||||
/* A remote status command failed miserably. Punt. */
|
||||
remote_status_lose:
|
||||
if (EINTR_SET)
|
||||
continue;
|
||||
|
||||
pfatal_with_name ("remote_status");
|
||||
}
|
||||
else
|
||||
@ -511,7 +508,6 @@ reap_children (block, err)
|
||||
#if !defined(__MSDOS__) && !defined(_AMIGA) && !defined(WINDOWS32)
|
||||
if (any_local)
|
||||
{
|
||||
local_wait:
|
||||
#ifdef VMS
|
||||
vmsWaitForChildren (&status);
|
||||
pid = c->pid;
|
||||
@ -529,10 +525,6 @@ reap_children (block, err)
|
||||
|
||||
if (pid < 0)
|
||||
{
|
||||
/* EINTR? Try again. */
|
||||
if (EINTR_SET)
|
||||
goto local_wait;
|
||||
|
||||
/* The wait*() failed miserably. Punt. */
|
||||
pfatal_with_name ("wait");
|
||||
}
|
||||
@ -737,7 +729,7 @@ reap_children (block, err)
|
||||
update_status to its also_make files. */
|
||||
notice_finished_file (c->file);
|
||||
|
||||
DB (DB_JOBS, (_("Removing child 0x%08lx PID %ld %s from chain.\n"),
|
||||
DB (DB_JOBS, (_("Removing child 0x%08lx PID %ld%s from chain.\n"),
|
||||
(unsigned long int) c, (long) c->pid,
|
||||
c->remote ? _(" (remote)") : ""));
|
||||
|
||||
@ -792,9 +784,8 @@ free_child (child)
|
||||
|
||||
/* Write a job token back to the pipe. */
|
||||
|
||||
while (write (job_fds[1], &token, 1) != 1)
|
||||
if (!EINTR_SET)
|
||||
pfatal_with_name (_("write jobserver"));
|
||||
if (write (job_fds[1], &token, 1) != 1)
|
||||
pfatal_with_name (_("write jobserver"));
|
||||
|
||||
DB (DB_JOBS, (_("Released token for child 0x%08lx (%s).\n"),
|
||||
(unsigned long int) child, child->file->name));
|
||||
@ -848,6 +839,26 @@ unblock_sigs ()
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef MAKE_JOBSERVER
|
||||
/* Set the child handler action flags to FLAGS. */
|
||||
static void
|
||||
set_child_handler_action_flags (flags)
|
||||
int flags;
|
||||
{
|
||||
struct sigaction sa;
|
||||
bzero ((char *) &sa, sizeof sa);
|
||||
sa.sa_handler = child_handler;
|
||||
sa.sa_flags = flags;
|
||||
#if defined SIGCHLD
|
||||
sigaction (SIGCHLD, &sa, NULL);
|
||||
#endif
|
||||
#if defined SIGCLD && SIGCLD != SIGCHLD
|
||||
sigaction (SIGCLD, &sa, NULL);
|
||||
#endif
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
/* Start a job to run the commands specified in CHILD.
|
||||
CHILD is updated to reflect the commands and ID of the child process.
|
||||
|
||||
@ -1489,34 +1500,73 @@ new_job (file)
|
||||
while (1)
|
||||
{
|
||||
char token;
|
||||
int got_token;
|
||||
int saved_errno;
|
||||
|
||||
DB (DB_JOBS, ("Need a job token; we %shave children\n",
|
||||
children ? "" : "don't "));
|
||||
|
||||
/* If we don't already have a job started, use our "free" token. */
|
||||
if (!children)
|
||||
break;
|
||||
|
||||
/* 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 immediately with EBADF because
|
||||
the signal handler closes the dup'd file descriptor. */
|
||||
We enable interruptible system calls before the read(2) so that if
|
||||
we get a SIGCHLD while we're waiting, we'll return with EINTR and
|
||||
we can process the death(s) and return tokens to the free pool.
|
||||
|
||||
if (read (job_rfd, &token, 1) == 1)
|
||||
Once we return from the read, we immediately reinstate restartable
|
||||
system calls. This allows us to not worry about checking for
|
||||
EINTR on all the other system calls in the program.
|
||||
|
||||
There is one other twist: there is a span between the time
|
||||
reap_children() does its last check for dead children and the time
|
||||
the read(2) call is entered, below, where if a child dies we won't
|
||||
notice. This is extremely serious as it could cause us to
|
||||
deadlock, given the right set of events.
|
||||
|
||||
To avoid this, we do the following: before we reap_children(), we
|
||||
dup(2) the read FD on the jobserver pipe. The read(2) call below
|
||||
uses that new FD. In the signal handler, we close that FD. That
|
||||
way, if a child dies during the section mentioned above, the
|
||||
read(2) will be invoked with an invalid FD and will return
|
||||
immediately with EBADF. */
|
||||
|
||||
/* Make sure we have a dup'd FD. */
|
||||
if (job_rfd < 0)
|
||||
{
|
||||
DB (DB_JOBS, ("Duplicate the job FD\n"));
|
||||
job_rfd = dup (job_fds[0]);
|
||||
}
|
||||
|
||||
/* Reap anything that's currently waiting. */
|
||||
reap_children (0, 0);
|
||||
|
||||
/* If our "free" token has become available, use it. */
|
||||
if (!children)
|
||||
break;
|
||||
|
||||
/* Set interruptible system calls, and read() for a job token. */
|
||||
set_child_handler_action_flags (0);
|
||||
got_token = read (job_rfd, &token, 1);
|
||||
saved_errno = errno;
|
||||
set_child_handler_action_flags (SA_RESTART);
|
||||
|
||||
/* If we got one, we're done here. */
|
||||
if (got_token == 1)
|
||||
{
|
||||
DB (DB_JOBS, (_("Obtained token for child 0x%08lx (%s).\n"),
|
||||
(unsigned long int) c, c->file->name));
|
||||
break;
|
||||
}
|
||||
|
||||
/* If the error _wasn't_ expected (EINTR or EBADF), punt. Otherwise,
|
||||
go back and reap_children(), and try again. */
|
||||
errno = saved_errno;
|
||||
if (errno != EINTR && errno != EBADF)
|
||||
pfatal_with_name (_("read jobs pipe"));
|
||||
|
||||
/* Re-dup the read side of the pipe, so the signal handler can
|
||||
notify us if we miss a child. */
|
||||
if (job_rfd < 0)
|
||||
job_rfd = dup (job_fds[0]);
|
||||
|
||||
/* Something's done. We don't want to block for a whole child,
|
||||
just reap whatever's there. */
|
||||
reap_children (0, 0);
|
||||
if (errno == EBADF)
|
||||
DB (DB_JOBS, ("Read returned EBADF.\n"));
|
||||
}
|
||||
#endif
|
||||
|
||||
|
56
main.c
56
main.c
@ -448,6 +448,27 @@ int fatal_signal_mask;
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#if !defined HAVE_BSD_SIGNAL && !defined bsd_signal
|
||||
# if !defined HAVE_SIGACTION
|
||||
# define bsd_signal signal
|
||||
# else
|
||||
static RETSIGTYPE
|
||||
(*bsd_signal) PARAMS ((int)) (sig, func)
|
||||
int sig;
|
||||
RETSIGTYPE (*func) PARAMS ((int));
|
||||
{
|
||||
struct sigaction act, oact;
|
||||
act.sa_handler = func;
|
||||
act.sa_flags = SA_RESTART;
|
||||
sigemptyset (&act.sa_mask);
|
||||
sigaddset (&act.sa_mask, sig);
|
||||
if (sigaction (sig, &act, &oact) != 0)
|
||||
return SIG_ERR;
|
||||
return oact.sa_handler;
|
||||
}
|
||||
# endif
|
||||
#endif
|
||||
|
||||
static struct file *
|
||||
enter_command_line_file (name)
|
||||
char *name;
|
||||
@ -839,8 +860,8 @@ int main (int argc, char ** argv)
|
||||
#endif
|
||||
|
||||
#define FATAL_SIG(sig) \
|
||||
if (signal ((sig), fatal_error_signal) == SIG_IGN) \
|
||||
(void) signal ((sig), SIG_IGN); \
|
||||
if (bsd_signal (sig, fatal_error_signal) == SIG_IGN) \
|
||||
bsd_signal (sig, SIG_IGN); \
|
||||
else \
|
||||
ADD_SIG (sig);
|
||||
|
||||
@ -879,10 +900,10 @@ int main (int argc, char ** argv)
|
||||
|
||||
#ifdef HAVE_WAIT_NOHANG
|
||||
# if defined SIGCHLD
|
||||
(void) signal (SIGCHLD, SIG_DFL);
|
||||
(void) bsd_signal (SIGCHLD, SIG_DFL);
|
||||
# endif
|
||||
# if defined SIGCLD && SIGCLD != SIGCHLD
|
||||
(void) signal (SIGCLD, SIG_DFL);
|
||||
(void) bsd_signal (SIGCLD, SIG_DFL);
|
||||
# endif
|
||||
#endif
|
||||
|
||||
@ -1345,34 +1366,18 @@ int main (int argc, char ** argv)
|
||||
If none of these are true, we don't need a signal handler at all. */
|
||||
{
|
||||
extern RETSIGTYPE child_handler PARAMS ((int sig));
|
||||
|
||||
# if defined HAVE_SIGACTION
|
||||
struct sigaction sa;
|
||||
|
||||
bzero ((char *)&sa, sizeof (struct sigaction));
|
||||
sa.sa_handler = child_handler;
|
||||
# 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
|
||||
(void) HANDLESIG (SIGCHLD);
|
||||
bsd_signal (SIGCHLD, child_handler);
|
||||
# endif
|
||||
# if defined SIGCLD && SIGCLD != SIGCHLD
|
||||
(void) HANDLESIG (SIGCLD);
|
||||
bsd_signal (SIGCLD, child_handler);
|
||||
# endif
|
||||
}
|
||||
#endif
|
||||
|
||||
/* Let the user send us SIGUSR1 to toggle the -d flag during the run. */
|
||||
#ifdef SIGUSR1
|
||||
(void) signal (SIGUSR1, debug_signal_handler);
|
||||
bsd_signal (SIGUSR1, debug_signal_handler);
|
||||
#endif
|
||||
|
||||
/* Define the initial list of suffixes for old-style rules. */
|
||||
@ -1527,9 +1532,8 @@ int main (int argc, char ** argv)
|
||||
want job_slots to be 0 to indicate we're using the jobserver. */
|
||||
|
||||
while (--job_slots)
|
||||
while (write (job_fds[1], &c, 1) != 1)
|
||||
if (!EINTR_SET)
|
||||
pfatal_with_name (_("init jobserver pipe"));
|
||||
if (write (job_fds[1], &c, 1) != 1)
|
||||
pfatal_with_name (_("init jobserver pipe"));
|
||||
|
||||
/* Fill in the jobserver_fds struct for our children. */
|
||||
|
||||
|
12
make.h
12
make.h
@ -111,14 +111,6 @@ Boston, MA 02111-1307, USA. */
|
||||
extern int errno;
|
||||
#endif
|
||||
|
||||
/* A shortcut for EINTR checking. Note you should be careful when negating
|
||||
this! That might not mean what you want if EINTR is not available. */
|
||||
#ifdef EINTR
|
||||
# define EINTR_SET (errno == EINTR)
|
||||
#else
|
||||
# define EINTR_SET (0)
|
||||
#endif
|
||||
|
||||
#ifndef isblank
|
||||
# define isblank(c) ((c) == ' ' || (c) == '\t')
|
||||
#endif
|
||||
@ -149,6 +141,10 @@ extern int errno;
|
||||
# define sigmask(sig) (1 << ((sig) - 1))
|
||||
#endif
|
||||
|
||||
#ifndef HAVE_SA_RESTART
|
||||
# define SA_RESTART 0
|
||||
#endif
|
||||
|
||||
#ifdef HAVE_LIMITS_H
|
||||
# include <limits.h>
|
||||
#endif
|
||||
|
@ -2223,7 +2223,7 @@ SUBDIRS = foo bar baz
|
||||
subdirs: $(SUBDIRS)
|
||||
|
||||
$(SUBDIRS):
|
||||
$(MAKE) -C $@
|
||||
$(MAKE) -C $@@
|
||||
|
||||
foo: baz
|
||||
@end group
|
||||
|
7
read.c
7
read.c
@ -1490,8 +1490,11 @@ record_target_var (filenames, defn, two_colon, origin, flocp)
|
||||
current_variable_set_list = global;
|
||||
gv = lookup_variable (v->name, len);
|
||||
if (gv && (gv->origin == o_env_override || gv->origin == o_command))
|
||||
define_variable_in_set (v->name, len, gv->value, gv->origin,
|
||||
gv->recursive, vlist->set, flocp);
|
||||
{
|
||||
v = define_variable_in_set (v->name, len, gv->value, gv->origin,
|
||||
gv->recursive, vlist->set, flocp);
|
||||
v->append = 0;
|
||||
}
|
||||
}
|
||||
|
||||
/* Free name if not needed further. */
|
||||
|
20
remake.c
20
remake.c
@ -933,13 +933,8 @@ touch_file (file)
|
||||
{
|
||||
struct stat statbuf;
|
||||
char buf;
|
||||
int status;
|
||||
|
||||
do
|
||||
status = fstat (fd, &statbuf);
|
||||
while (status < 0 && EINTR_SET);
|
||||
|
||||
if (status < 0)
|
||||
if (fstat (fd, &statbuf) < 0)
|
||||
TOUCH_ERROR ("touch: fstat: ");
|
||||
/* Rewrite character 0 same as it already is. */
|
||||
if (read (fd, &buf, 1) < 0)
|
||||
@ -1239,13 +1234,12 @@ name_mtime (name)
|
||||
{
|
||||
struct stat st;
|
||||
|
||||
while (stat (name, &st) != 0)
|
||||
if (!EINTR_SET)
|
||||
{
|
||||
if (errno != ENOENT && errno != ENOTDIR)
|
||||
perror_with_name ("stat:", name);
|
||||
return NONEXISTENT_MTIME;
|
||||
}
|
||||
if (stat (name, &st) != 0)
|
||||
{
|
||||
if (errno != ENOENT && errno != ENOTDIR)
|
||||
perror_with_name ("stat:", name);
|
||||
return NONEXISTENT_MTIME;
|
||||
}
|
||||
|
||||
return FILE_TIMESTAMP_STAT_MODTIME (name, st);
|
||||
}
|
||||
|
@ -207,6 +207,7 @@ lookup_variable (name, length)
|
||||
sptr++;
|
||||
}
|
||||
|
||||
*nptr = '\0';
|
||||
return define_variable (vname, length, nvalue, o_env, 1);
|
||||
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user