summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--usr.bin/make/compat.c8
-rw-r--r--usr.bin/make/engine.c48
-rw-r--r--usr.bin/make/engine.h6
-rw-r--r--usr.bin/make/gnode.h3
-rw-r--r--usr.bin/make/job.c340
-rw-r--r--usr.bin/make/memory.c21
-rw-r--r--usr.bin/make/memory.h3
-rw-r--r--usr.bin/make/targ.c5
8 files changed, 250 insertions, 184 deletions
diff --git a/usr.bin/make/compat.c b/usr.bin/make/compat.c
index 92d34b1a313..614cba7c566 100644
--- a/usr.bin/make/compat.c
+++ b/usr.bin/make/compat.c
@@ -1,5 +1,5 @@
/* $OpenPackages$ */
-/* $OpenBSD: compat.c,v 1.68 2007/11/10 13:59:48 espie Exp $ */
+/* $OpenBSD: compat.c,v 1.69 2008/01/29 22:23:10 espie Exp $ */
/* $NetBSD: compat.c,v 1.14 1996/11/06 17:59:01 christos Exp $ */
/*
@@ -127,7 +127,7 @@ CompatMake(void *gnp, /* The node to make */
/* Our commands are ok, but we still have to worry
* about the -t flag... */
if (!touchFlag)
- run_gnode(gn, 0);
+ run_gnode(gn);
else
Job_Touch(gn);
} else
@@ -216,7 +216,7 @@ Compat_Run(Lst targs) /* List of target nodes to re-create */
/* If the user has defined a .BEGIN target, execute the commands
* attached to it. */
if (!queryFlag) {
- if (run_gnode(begin_node, 0) == ERROR) {
+ if (run_gnode(begin_node) == ERROR) {
printf("\n\nStop.\n");
exit(1);
}
@@ -247,5 +247,5 @@ Compat_Run(Lst targs) /* List of target nodes to re-create */
/* If the user has defined a .END target, run its commands. */
if (errors == 0)
- run_gnode(end_node, 0);
+ run_gnode(end_node);
}
diff --git a/usr.bin/make/engine.c b/usr.bin/make/engine.c
index 221bac932ac..0c6e123fd25 100644
--- a/usr.bin/make/engine.c
+++ b/usr.bin/make/engine.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: engine.c,v 1.18 2008/01/02 15:37:22 espie Exp $ */
+/* $OpenBSD: engine.c,v 1.19 2008/01/29 22:23:10 espie Exp $ */
/*
* Copyright (c) 1988, 1989, 1990 The Regents of the University of California.
* Copyright (c) 1988, 1989 by Adam de Boor
@@ -619,7 +619,6 @@ run_command(const char *cmd, bool errCheck)
static int
setup_and_run_command(char *cmd, GNode *gn, int dont_fork)
{
- char *cmdStart; /* Start of expanded command */
bool silent; /* Don't print command */
bool doExecute; /* Execute the command */
bool errCheck; /* Check errors */
@@ -632,16 +631,12 @@ setup_and_run_command(char *cmd, GNode *gn, int dont_fork)
errCheck = !(gn->type & OP_IGNORE);
doExecute = !noExecute;
- cmdStart = Var_Subst(cmd, &gn->context, false);
-
/* How can we execute a null command ? we warn the user that the
* command expanded to nothing (is this the right thing to do?). */
- if (*cmdStart == '\0') {
- free(cmdStart);
+ if (*cmd == '\0') {
Error("%s expands to empty string", cmd);
return 1;
- } else
- cmd = cmdStart;
+ }
for (;; cmd++) {
if (*cmd == '@')
@@ -686,7 +681,6 @@ setup_and_run_command(char *cmd, GNode *gn, int dont_fork)
default:
break;
}
- free(cmdStart);
/* The child is off and running. Now all we can do is wait... */
while (1) {
@@ -751,25 +745,47 @@ handle_compat_interrupts(GNode *gn)
signal(SIGQUIT, SIG_IGN);
got_signal = 0;
got_SIGINT = 0;
- run_gnode(interrupt_node, 0);
+ run_gnode(interrupt_node);
exit(255);
}
exit(255);
}
+void
+expand_commands(GNode *gn)
+{
+ LstNode ln;
+ char *cmd;
+
+ for (ln = Lst_First(&gn->commands); ln != NULL; ln = Lst_Adv(ln)) {
+ cmd = Var_Subst(Lst_Datum(ln), &gn->context, false);
+ Lst_AtEnd(&gn->expanded, cmd);
+ }
+}
+
+int
+run_gnode(GNode *gn)
+{
+ if (gn != NULL && (gn->type & OP_DUMMY) == 0) {
+ expand_commands(gn);
+ }
+ return run_prepared_gnode(gn, 0);
+}
+
int
-run_gnode(GNode *gn, int parallel)
+run_prepared_gnode(GNode *gn, int parallel)
{
- LstNode ln, nln;
+ char *cmd;
if (gn != NULL && (gn->type & OP_DUMMY) == 0) {
gn->built_status = MADE;
- for (ln = Lst_First(&gn->commands); ln != NULL; ln = nln) {
- nln = Lst_Adv(ln);
- if (setup_and_run_command(Lst_Datum(ln), gn,
- parallel && nln == NULL) == 0)
+ while ((cmd = Lst_DeQueue(&gn->expanded)) != NULL) {
+ if (setup_and_run_command(cmd, gn,
+ parallel && Lst_IsEmpty(&gn->expanded)) == 0)
break;
+ free(cmd);
}
+ free(cmd);
if (got_signal && !parallel)
handle_compat_interrupts(gn);
return gn->built_status;
diff --git a/usr.bin/make/engine.h b/usr.bin/make/engine.h
index ce05ec844d1..7c0a7eaf3c8 100644
--- a/usr.bin/make/engine.h
+++ b/usr.bin/make/engine.h
@@ -1,6 +1,6 @@
#ifndef ENGINE_H
#define ENGINE_H
-/* $OpenBSD: engine.h,v 1.4 2007/11/03 14:05:39 espie Exp $ */
+/* $OpenBSD: engine.h,v 1.5 2008/01/29 22:23:10 espie Exp $ */
/*
* Copyright (c) 1988, 1989, 1990 The Regents of the University of California.
@@ -71,7 +71,9 @@ extern volatile sig_atomic_t got_SIGINT, got_SIGHUP, got_SIGQUIT,
got_SIGTERM, got_SIGTSTP, got_SIGTTOU, got_SIGTTIN, got_SIGWINCH;
extern void SigHandler(int);
-extern int run_gnode(GNode *, int);
+extern int run_gnode(GNode *);
+extern int run_prepared_gnode(GNode *, int);
+extern void expand_commands(GNode *);
extern void setup_engine(void);
diff --git a/usr.bin/make/gnode.h b/usr.bin/make/gnode.h
index 8eeccfa4312..122963b8e39 100644
--- a/usr.bin/make/gnode.h
+++ b/usr.bin/make/gnode.h
@@ -1,7 +1,7 @@
#ifndef GNODE_H
#define GNODE_H
/* $OpenPackages$ */
-/* $OpenBSD: gnode.h,v 1.12 2007/12/10 17:44:06 espie Exp $ */
+/* $OpenBSD: gnode.h,v 1.13 2008/01/29 22:23:10 espie Exp $ */
/*
* Copyright (c) 2001 Marc Espie.
@@ -130,6 +130,7 @@ struct GNode_ {
unsigned long lineno;/* First line number of commands. */
const char *fname; /* File name of commands. */
LIST commands; /* Creation commands */
+ LIST expanded; /* Expanded commands */
struct Suff_ *suffix;/* Suffix for the node (determined by
* Suff_FindDeps and opaque to everyone
* but the Suff module) */
diff --git a/usr.bin/make/job.c b/usr.bin/make/job.c
index b841397731f..2f9016f3646 100644
--- a/usr.bin/make/job.c
+++ b/usr.bin/make/job.c
@@ -1,5 +1,5 @@
/* $OpenPackages$ */
-/* $OpenBSD: job.c,v 1.111 2008/01/12 13:08:59 espie Exp $ */
+/* $OpenBSD: job.c,v 1.112 2008/01/29 22:23:10 espie Exp $ */
/* $NetBSD: job.c,v 1.16 1996/11/06 17:59:08 christos Exp $ */
/*
@@ -161,11 +161,16 @@ static int nJobs; /* The number of children currently running */
static LIST runningJobs; /* The structures that describe them */
static bool jobFull; /* Flag to tell when the job table is full. It
* is set true when nJobs equals maxJobs */
-static fd_set *outputsp; /* Set of descriptors of pipes connected to
- * the output channels of children */
-static int outputsn;
static GNode *lastNode; /* The node for which output was most recently
* produced. */
+
+/* data structure linked to job handling through select */
+static fd_set *output_mask = NULL; /* File descriptors to look for */
+
+static fd_set *actual_mask = NULL; /* actual select argument */
+static int largest_fd = -1;
+static size_t mask_size = 0;
+
/*
* When JobStart attempts to run a job but isn't allowed to,
* the job is placed on the queuedJobs queue to be run
@@ -173,15 +178,23 @@ static GNode *lastNode; /* The node for which output was most recently
*/
static LIST stoppedJobs;
static LIST queuedJobs;
+
+/* wait possibilities */
+#define JOB_EXITED 0
+#define JOB_SIGNALED 1
+#define JOB_CONTINUED 2
+#define JOB_STOPPED 3
+#define JOB_UNKNOWN 4
+
static LIST errorsList;
static int errors;
struct error_info {
- int status;
+ int reason;
+ int code;
GNode *n;
};
-
#if defined(USE_PGRP) && defined(SYSV)
# define KILL(pid, sig) killpg(-(pid), (sig))
#else
@@ -192,32 +205,12 @@ struct error_info {
# endif
#endif
-/*
- * Grmpf... There is no way to set bits of the wait structure
- * anymore with the stupid W*() macros. I liked the union wait
- * stuff much more. So, we devise our own macros... This is
- * really ugly, use dramamine sparingly. You have been warned.
- */
-#define W_SETMASKED(st, val, fun) \
- { \
- int sh = (int) ~0; \
- int mask = fun(sh); \
- \
- for (sh = 0; ((mask >> sh) & 1) == 0; sh++) \
- continue; \
- *(st) = (*(st) & ~mask) | ((val) << sh); \
- }
-
-#define W_SETTERMSIG(st, val) W_SETMASKED(st, val, WTERMSIG)
-#define W_SETEXITSTATUS(st, val) W_SETMASKED(st, val, WEXITSTATUS)
-
-
static void pass_signal_to_job(void *, void *);
static void handle_all_signals(void);
static void handle_signal(int);
static int JobCmpPid(void *, void *);
-static void JobClose(Job *);
static void JobFinish(Job *, int);
+static void finish_job(Job *, int, int);
static void JobExec(Job *);
static void JobRestart(Job *);
static void JobStart(GNode *, int);
@@ -227,25 +220,49 @@ static void debug_printf(const char *, ...);
static Job *prepare_job(GNode *, int);
static void start_queued_job(Job *);
static void banner(Job *, FILE *);
+
+/***
+ *** Input/output from jobs
+ ***/
+
+/* prepare_pipe(jp, &fd):
+ * set up pipe data structure (buffer and pos) corresponding to
+ * pointed fd, and prepare to watch for it.
+ */
+static void prepare_pipe(struct job_pipe *, int *);
+
+/* close_job_pipes(j):
+ * handle final output from job, and close pipes properly
+ */
+static void close_job_pipes(Job *);
+
+
+static void handle_all_jobs_output(void);
+
+/* handle_job_output(job, n, finish):
+ * n = 0 or 1 (stdout/stderr), set finish to retrieve everything.
+ */
+static void handle_job_output(Job *, int, bool);
+
static void print_partial_buffer(struct job_pipe *, Job *, FILE *, size_t);
static void print_partial_buffer_and_shift(struct job_pipe *, Job *, FILE *,
size_t);
static bool print_complete_lines(struct job_pipe *, Job *, FILE *, size_t);
-static void prepare_pipe(struct job_pipe *, int *);
-static void handle_job_output(Job *, int, bool);
-static void register_error(int, Job *);
+
+
+static void register_error(int, int, Job *);
static void loop_handle_running_jobs(void);
static void Job_CatchChildren(void);
-static void Job_CatchOutput(void);
static void
-register_error(int status, Job *job)
+register_error(int reason, int code, Job *job)
{
struct error_info *p;
errors++;
p = emalloc(sizeof(struct error_info));
- p->status = status;
+ p->reason = reason;
+ p->code = code;
p->n = job->node;
Lst_AtEnd(&errorsList, p);
}
@@ -256,25 +273,31 @@ print_errors()
LstNode ln;
struct error_info *p;
const char *type;
- int r;
for (ln = Lst_First(&errorsList); ln != NULL; ln = Lst_Adv(ln)) {
p = (struct error_info *)Lst_Datum(ln);
- if (WIFEXITED(p->status)) {
+ switch(p->reason) {
+ case JOB_EXITED:
type = "Exit status";
- r = WEXITSTATUS(p->status);
- } else if (WIFSIGNALED(p->status)) {
+ break;
+ case JOB_SIGNALED:
type = "Received signal";
- r = WTERMSIG(p->status);
- } else {
- type = "Status";
- r = p->status;
+ break;
+ case JOB_STOPPED:
+ type = "Stopped";
+ break;
+ case JOB_CONTINUED:
+ type = "Continued";
+ break;
+ default:
+ type = "Should not happen";
+ break;
}
if (p->n->lineno)
Error(" %s %d (%s, line %lu of %s)",
- type, r, p->n->name, p->n->lineno, p->n->fname);
+ type, p->code, p->n->name, p->n->lineno, p->n->fname);
else
- Error(" %s %d (%s)", type, r, p->n->name);
+ Error(" %s %d (%s)", type, p->code, p->n->name);
}
}
@@ -461,22 +484,13 @@ debug_printf(const char *fmt, ...)
}
}
-/*-
- *-----------------------------------------------------------------------
- * JobClose --
- * Called to close both input and output pipes when a job is finished.
- *
- * Side Effects:
- * The file descriptors associated with the job are closed.
- *-----------------------------------------------------------------------
- */
static void
-JobClose(Job *job)
+close_job_pipes(Job *job)
{
int i;
- for (i = 0; i < 2; i++) {
- FD_CLR(job->in[i].fd, outputsp);
+ for (i = 1; i >= 0; i--) {
+ FD_CLR(job->in[i].fd, output_mask);
handle_job_output(job, i, true);
(void)close(job->in[i].fd);
}
@@ -499,14 +513,41 @@ JobClose(Job *job)
*-----------------------------------------------------------------------
*/
/*ARGSUSED*/
+
static void
JobFinish(Job *job, int status)
{
+ int reason, code;
+ /* parse status */
+ if (WIFEXITED(status)) {
+ reason = JOB_EXITED;
+ code = WEXITSTATUS(status);
+ } else if (WIFSIGNALED(status)) {
+ reason = JOB_SIGNALED;
+ code = WTERMSIG(status);
+ } else if (WIFCONTINUED(status)) {
+ reason = JOB_CONTINUED;
+ code = 0;
+ } else if (WIFSTOPPED(status)) {
+ reason = JOB_STOPPED;
+ code = WSTOPSIG(status);
+ } else {
+ /* can't happen, set things to be bad. */
+ reason = UNKNOWN;
+ code = status;
+ }
+ finish_job(job, reason, code);
+}
+
+
+static void
+finish_job(Job *job, int reason, int code)
+{
bool done;
- if ((WIFEXITED(status) &&
- WEXITSTATUS(status) != 0 && !(job->node->type & OP_IGNORE)) ||
- (WIFSIGNALED(status) && WTERMSIG(status) != SIGCONT)) {
+ if ((reason == JOB_EXITED &&
+ code != 0 && !(job->node->type & OP_IGNORE)) ||
+ (reason == JOB_SIGNALED && code != SIGCONT)) {
/*
* If it exited non-zero and either we're doing things our
* way or we're not ignoring errors, the job is finished.
@@ -515,9 +556,9 @@ JobFinish(Job *job, int status)
* cases, finish out the job's output before printing the exit
* status...
*/
- JobClose(job);
+ close_job_pipes(job);
done = true;
- } else if (WIFEXITED(status)) {
+ } else if (reason == JOB_EXITED) {
/*
* Deal with ignored errors in -B mode. We need to print a
* message telling of the ignored error as well as setting
@@ -525,13 +566,13 @@ JobFinish(Job *job, int status)
* this, we set done to be true if in -B mode and the job
* exited non-zero.
*/
- done = WEXITSTATUS(status) != 0;
+ done = code != 0;
/*
* Old comment said: "Note we don't want to close down any of
* the streams until we know we're at the end." But we do.
* Otherwise when are we going to print the rest of the stuff?
*/
- JobClose(job);
+ close_job_pipes(job);
} else {
/*
* No need to close things down or anything.
@@ -539,78 +580,78 @@ JobFinish(Job *job, int status)
done = false;
}
- if (done ||
- WIFSTOPPED(status) ||
- (WIFSIGNALED(status) && WTERMSIG(status) == SIGCONT) ||
- DEBUG(JOB)) {
- if (WIFEXITED(status)) {
+ if (reason == JOB_STOPPED) {
+ debug_printf("Process %ld stopped.\n", (long)job->pid);
+ banner(job, stdout);
+ (void)fprintf(stdout, "*** Stopped -- signal %d\n",
+ code);
+ job->flags |= JOB_RESUME;
+ Lst_AtEnd(&stoppedJobs, job);
+ (void)fflush(stdout);
+ return;
+ }
+ if (reason == JOB_SIGNALED && code == SIGCONT) {
+ /*
+ * If the beastie has continued, shift the Job from the
+ * stopped list to the running one (or re-stop it if
+ * concurrency is exceeded) and go and get another
+ * child.
+ */
+ if (job->flags & (JOB_RESUME|JOB_RESTART)) {
+ banner(job, stdout);
+ (void)fprintf(stdout, "*** Continued\n");
+ }
+ if (!(job->flags & JOB_CONTINUING)) {
+ debug_printf(
+ "Warning: "
+ "process %ld was not continuing.\n",
+ (long)job->pid);
+#if 0
+ /*
+ * We don't really want to restart a job from
+ * scratch just because it continued,
+ * especially not without killing the
+ * continuing process! That's why this is
+ * ifdef'ed out. FD - 9/17/90
+ */
+ JobRestart(job);
+#endif
+ }
+ job->flags &= ~JOB_CONTINUING;
+ Lst_AtEnd(&runningJobs, job);
+ nJobs++;
+ debug_printf("Process %ld is continuing locally.\n",
+ (long)job->pid);
+ if (nJobs == maxJobs) {
+ jobFull = true;
+ debug_printf("Job queue is full.\n");
+ }
+ (void)fflush(stdout);
+ return;
+ }
+
+ if (done || DEBUG(JOB)) {
+ if (reason == JOB_EXITED) {
debug_printf("Process %ld exited.\n", (long)job->pid);
- if (WEXITSTATUS(status) != 0) {
+ if (code != 0) {
banner(job, stdout);
(void)fprintf(stdout, "*** Error code %d %s\n",
- WEXITSTATUS(status),
+ code,
(job->node->type & OP_IGNORE) ?
"(ignored)" : "");
if (job->node->type & OP_IGNORE) {
- status = 0;
+ reason = JOB_EXITED;
+ code = 0;
}
} else if (DEBUG(JOB)) {
banner(job, stdout);
(void)fprintf(stdout,
"*** Completed successfully\n");
}
- } else if (WIFSTOPPED(status)) {
- debug_printf("Process %ld stopped.\n", (long)job->pid);
- banner(job, stdout);
- (void)fprintf(stdout, "*** Stopped -- signal %d\n",
- WSTOPSIG(status));
- job->flags |= JOB_RESUME;
- Lst_AtEnd(&stoppedJobs, job);
- (void)fflush(stdout);
- return;
- } else if (WTERMSIG(status) == SIGCONT) {
- /*
- * If the beastie has continued, shift the Job from the
- * stopped list to the running one (or re-stop it if
- * concurrency is exceeded) and go and get another
- * child.
- */
- if (job->flags & (JOB_RESUME|JOB_RESTART)) {
- banner(job, stdout);
- (void)fprintf(stdout, "*** Continued\n");
- }
- if (!(job->flags & JOB_CONTINUING)) {
- debug_printf(
- "Warning: "
- "process %ld was not continuing.\n",
- (long)job->pid);
-#if 0
- /*
- * We don't really want to restart a job from
- * scratch just because it continued,
- * especially not without killing the
- * continuing process! That's why this is
- * ifdef'ed out. FD - 9/17/90
- */
- JobRestart(job);
-#endif
- }
- job->flags &= ~JOB_CONTINUING;
- Lst_AtEnd(&runningJobs, job);
- nJobs++;
- debug_printf("Process %ld is continuing locally.\n",
- (long)job->pid);
- if (nJobs == maxJobs) {
- jobFull = true;
- debug_printf("Job queue is full.\n");
- }
- (void)fflush(stdout);
- return;
} else {
banner(job, stdout);
- (void)fprintf(stdout, "*** Signal %d\n",
- WTERMSIG(status));
+ (void)fprintf(stdout, "*** Signal %d\n", code);
}
(void)fflush(stdout);
@@ -621,15 +662,15 @@ JobFinish(Job *job, int status)
if (done &&
aborting != ABORT_ERROR &&
aborting != ABORT_INTERRUPT &&
- status == 0) {
+ reason == JOB_EXITED && code == 0) {
/* As long as we aren't aborting and the job didn't return a
* non-zero status that we shouldn't ignore, we call
* Make_Update to update the parents. */
job->node->built_status = MADE;
Make_Update(job->node);
free(job);
- } else if (status != 0) {
- register_error(status, job);
+ } else if (!(reason == JOB_EXITED && code == 0)) {
+ register_error(reason, code, job);
free(job);
}
@@ -665,23 +706,23 @@ prepare_pipe(struct job_pipe *p, int *fd)
p->fd = fd[0];
close(fd[1]);
- if (outputsp == NULL || p->fd > outputsn) {
+ if (output_mask == NULL || p->fd > largest_fd) {
int fdn, ofdn;
- fd_set *tmp;
fdn = howmany(p->fd+1, NFDBITS);
- ofdn = outputsn ? howmany(outputsn+1, NFDBITS) : 0;
+ ofdn = howmany(largest_fd+1, NFDBITS);
if (fdn != ofdn) {
- tmp = recalloc(outputsp, fdn, sizeof(fd_mask));
- if (tmp == NULL)
- return;
- outputsp = tmp;
+ output_mask = erecalloc(output_mask, fdn,
+ sizeof(fd_mask));
+ actual_mask = erecalloc(actual_mask, fdn,
+ sizeof(fd_mask));
+ mask_size = fdn * sizeof(fd_mask);
}
- outputsn = p->fd;
+ largest_fd = p->fd;
}
fcntl(p->fd, F_SETFL, O_NONBLOCK);
- FD_SET(p->fd, outputsp);
+ FD_SET(p->fd, output_mask);
}
/*-
@@ -767,7 +808,7 @@ JobExec(Job *job)
usleep(random() % random_delay);
/* most cases won't return, but will exit directly */
- result = run_gnode(job->node, 1);
+ result = run_prepared_gnode(job->node, 1);
switch(result) {
case MADE:
exit(0);
@@ -854,7 +895,6 @@ JobRestart(Job *job)
* (or maxJobs is 0), it's ok to resume the job.
*/
bool error;
- int status = 0;
error = KILL(job->pid, SIGCONT) != 0;
@@ -865,16 +905,14 @@ JobRestart(Job *job)
* table.
*/
job->flags |= JOB_CONTINUING;
- W_SETTERMSIG(&status, SIGCONT);
- JobFinish(job, status);
+ finish_job(job, JOB_SIGNALED, SIGCONT);
job->flags &= ~(JOB_RESUME|JOB_CONTINUING);
debug_printf("done\n");
} else {
Error("couldn't resume %s: %s",
job->node->name, strerror(errno));
- W_SETEXITSTATUS(&status, 1);
- JobFinish(job, status);
+ finish_job(job, JOB_EXITED, 1);
}
} else {
/*
@@ -915,6 +953,7 @@ prepare_job(GNode *gn, int flags)
* to migrate to the node
*/
cmdsOK = Job_CheckCommands(gn, Error);
+ expand_commands(gn);
if ((gn->type & OP_MAKE) || (!noExecute && !touchFlag)) {
/*
@@ -1146,9 +1185,8 @@ Job_CatchChildren()
/*
* Don't even bother if we know there's no one around.
*/
- if (nJobs == 0) {
+ if (nJobs == 0)
return;
- }
while ((pid = waitpid((pid_t) -1, &status, WNOHANG|WUNTRACED)) > 0) {
handle_all_signals();
@@ -1183,14 +1221,8 @@ Job_CatchChildren()
}
}
-/*-
- *-----------------------------------------------------------------------
- * Job_CatchOutput --
- * Catch the output from our children.
- * -----------------------------------------------------------------------
- */
void
-Job_CatchOutput(void)
+handle_all_jobs_output(void)
{
int nfds;
struct timeval timeout;
@@ -1199,18 +1231,17 @@ Job_CatchOutput(void)
int i;
int status;
- int count = howmany(outputsn+1, NFDBITS) * sizeof(fd_mask);
- fd_set *readfdsp = malloc(count);
+ /* no jobs */
+ if (Lst_IsEmpty(&runningJobs))
+ return;
(void)fflush(stdout);
- if (readfdsp == NULL)
- return;
- memcpy(readfdsp, outputsp, count);
+ memcpy(actual_mask, output_mask, mask_size);
timeout.tv_sec = SEL_SEC;
timeout.tv_usec = SEL_USEC;
- nfds = select(outputsn+1, readfdsp, NULL, NULL, &timeout);
+ nfds = select(largest_fd+1, actual_mask, NULL, NULL, &timeout);
handle_all_signals();
for (ln = Lst_First(&runningJobs); nfds && ln != NULL;
ln = ln2) {
@@ -1218,7 +1249,7 @@ Job_CatchOutput(void)
job = (Job *)Lst_Datum(ln);
job->flags &= ~JOB_DIDOUTPUT;
for (i = 1; i >= 0; i--) {
- if (FD_ISSET(job->in[i].fd, readfdsp)) {
+ if (FD_ISSET(job->in[i].fd, actual_mask)) {
nfds--;
handle_job_output(job, i, false);
}
@@ -1235,13 +1266,12 @@ Job_CatchOutput(void)
}
}
}
- free(readfdsp);
}
void
handle_running_jobs()
{
- Job_CatchOutput();
+ handle_all_jobs_output();
Job_CatchChildren();
}
diff --git a/usr.bin/make/memory.c b/usr.bin/make/memory.c
index 2fea8517078..66a2ee0781f 100644
--- a/usr.bin/make/memory.c
+++ b/usr.bin/make/memory.c
@@ -1,5 +1,5 @@
/* $OpenPackages$ */
-/* $OpenBSD: memory.c,v 1.4 2007/09/16 10:43:53 espie Exp $ */
+/* $OpenBSD: memory.c,v 1.5 2008/01/29 22:23:10 espie Exp $ */
/*
* Copyright (c) 1988, 1989, 1990, 1993
@@ -49,6 +49,7 @@
#include "memory.h"
static void enomem(size_t);
+static void enocmem(size_t, size_t);
/*
* emalloc --
@@ -99,10 +100,18 @@ ecalloc(size_t s1, size_t s2)
void *p;
if ((p = calloc(s1, s2)) == NULL)
- enomem(s1 * s2);
+ enocmem(s1, s2);
return p;
}
+void *
+erecalloc(void *ptr, size_t s1, size_t s2)
+{
+ if ((ptr = recalloc(ptr, s1, s2)) == NULL)
+ enocmem(s1, s2);
+ return ptr;
+}
+
/* Support routines for hash tables. */
void *
hash_alloc(size_t s, void *u UNUSED)
@@ -131,10 +140,16 @@ element_alloc(size_t s, void *u UNUSED)
void
enomem(size_t size)
{
- fprintf(stderr, "make: %s (%lu)\n", strerror(errno), (u_long)size);
+ fprintf(stderr, "make: %s (%zu)\n", strerror(errno), size);
exit(2);
}
+void
+enocmem(size_t sz1, size_t sz2)
+{
+ fprintf(stderr, "make: %s (%zu * %zu)\n", strerror(errno), sz1, sz2);
+ exit(2);
+}
/*
* esetenv --
* change environment, die on error.
diff --git a/usr.bin/make/memory.h b/usr.bin/make/memory.h
index 40d75649b14..6339a969b43 100644
--- a/usr.bin/make/memory.h
+++ b/usr.bin/make/memory.h
@@ -2,7 +2,7 @@
#define MEMORY_H
/* $OpenPackages$ */
-/* $OpenBSD: memory.h,v 1.3 2007/09/16 10:43:53 espie Exp $ */
+/* $OpenBSD: memory.h,v 1.4 2008/01/29 22:23:10 espie Exp $ */
/*-
* Copyright (c) 1988, 1989, 1990, 1993
@@ -43,6 +43,7 @@ extern void *emalloc(size_t);
extern char *estrdup(const char *);
extern void *erealloc(void *, size_t);
extern void *ecalloc(size_t, size_t);
+extern void *erecalloc(void *, size_t, size_t);
extern int eunlink(const char *);
extern void esetenv(const char *, const char *);
diff --git a/usr.bin/make/targ.c b/usr.bin/make/targ.c
index 946949bc201..d0f69171d7a 100644
--- a/usr.bin/make/targ.c
+++ b/usr.bin/make/targ.c
@@ -1,5 +1,5 @@
/* $OpenPackages$ */
-/* $OpenBSD: targ.c,v 1.55 2007/11/28 09:39:01 espie Exp $ */
+/* $OpenBSD: targ.c,v 1.56 2008/01/29 22:23:10 espie Exp $ */
/* $NetBSD: targ.c,v 1.11 1997/02/20 16:51:50 christos Exp $ */
/*
@@ -196,7 +196,8 @@ Targ_NewGNi(const char *name, const char *ename)
gn->fname = NULL;
gn->impliedsrc = NULL;
Lst_Init(&gn->commands);
- gn->suffix = NULL;
+ Lst_Init(&gn->expanded);
+ gn->suffix = NULL;
#ifdef STATS_GN_CREATION
STAT_GN_COUNT++;