diff options
author | Marc Espie <espie@cvs.openbsd.org> | 2008-01-29 22:23:11 +0000 |
---|---|---|
committer | Marc Espie <espie@cvs.openbsd.org> | 2008-01-29 22:23:11 +0000 |
commit | 86cd533ac58398837895c92042102f4ffdeeaafe (patch) | |
tree | 96db9fa0407ac8932ac7595c9d8d7e1cbccab68b /usr.bin/make | |
parent | c53044596d693602d2e0fe7be428bfa014289fe8 (diff) |
A few changes:
- expand commands earlier, so that we can eventually scan them to take
smarter decisions.
- clean up the select() mask code and rename variables to sensible things.
- quite a few minor renames for readability
- erecalloc
- clean up wait status handling, do not try to rebuild wait status, but
instead parse it early and deal with the parsed code.
tested by lots of people, thanks guys!
Diffstat (limited to 'usr.bin/make')
-rw-r--r-- | usr.bin/make/compat.c | 8 | ||||
-rw-r--r-- | usr.bin/make/engine.c | 48 | ||||
-rw-r--r-- | usr.bin/make/engine.h | 6 | ||||
-rw-r--r-- | usr.bin/make/gnode.h | 3 | ||||
-rw-r--r-- | usr.bin/make/job.c | 340 | ||||
-rw-r--r-- | usr.bin/make/memory.c | 21 | ||||
-rw-r--r-- | usr.bin/make/memory.h | 3 | ||||
-rw-r--r-- | usr.bin/make/targ.c | 5 |
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++; |