void Log(int priority, const char *s, ...) { va_list ap; char *datetime = NULL; if (!log) { return; } #if !DEBUG if (priority == LOG_DEBUG) { return; } #endif va_start(ap, s); LOCK(log_mutex); datetime = timefmt(datetime, STRLEN); fprintf(log, "[%s] %-8s : ", datetime, logPriorityDescp(priority)); vfprintf(log, s, ap); free(datetime); END_LOCK va_end(ap); }
/** * Log a message to monits logfile or syslog. * @param priority A message priority * @param s A formated (printf-style) string to log */ static void log_log(int priority, const char *s, va_list ap) { #ifdef HAVE_VA_COPY va_list ap_copy; #endif ASSERT(s); LOCK(log_mutex) { FILE *output = priority < LOG_INFO ? stderr : stdout; #ifdef HAVE_VA_COPY va_copy(ap_copy, ap); vfprintf(output, s, ap_copy); va_end(ap_copy); #else vfprintf(output, s, ap); #endif fflush(output); if (Run.flags & Run_Log) { if (Run.flags & Run_UseSyslog) { #ifdef HAVE_VA_COPY va_copy(ap_copy, ap); vsyslog(priority, s, ap_copy); va_end(ap_copy); #else vsyslog(priority, s, ap); #endif } else if (LOG) { char datetime[STRLEN]; fprintf(LOG, "[%s] %-8s : ", timefmt(datetime, STRLEN), logPriorityDescription(priority)); #ifdef HAVE_VA_COPY va_copy(ap_copy, ap); vfprintf(LOG, s, ap_copy); va_end(ap_copy); #else vfprintf(LOG, s, ap); #endif } } } END_LOCK; }
void ar_summary(int n) { time_t secs; int len; char buf[BUFSIZ]; char tbuf[MAXPATHLEN/4]; /* XXX silly size! */ char s1buf[MAXPATHLEN/8]; /* XXX very silly size! */ char s2buf[MAXPATHLEN/8]; /* XXX very silly size! */ FILE *outf; if (act == LIST) outf = stdout; else outf = stderr; /* * If we are called from a signal (n != 0), use snprintf(3) so that we * don't reenter stdio(3). */ (void)time(&secs); if ((secs -= starttime) == 0) secs = 1; /* * If we have not determined the format yet, we just say how many bytes * we have skipped over looking for a header to id. there is no way we * could have written anything yet. */ if (frmt == NULL && act != COPY) { len = snprintf(buf, sizeof(buf), "unknown format, %s skipped in %s\n", sizefmt(s1buf, sizeof(s1buf), rdcnt), timefmt(tbuf, sizeof(tbuf), rdcnt, secs, "bytes")); if (n == 0) (void)fprintf(outf, "%s: %s", argv0, buf); else (void)write(STDERR_FILENO, buf, len); return; } if (n != 0 && *archd.name) { len = snprintf(buf, sizeof(buf), "Working on `%s' (%s)\n", archd.name, sizefmt(s1buf, sizeof(s1buf), archd.sb.st_size)); (void)write(STDERR_FILENO, buf, len); len = 0; } if (act == COPY) { len = snprintf(buf, sizeof(buf), "%lu files in %s\n", (unsigned long)flcnt, timefmt(tbuf, sizeof(tbuf), flcnt, secs, "files")); } else { len = snprintf(buf, sizeof(buf), "%s vol %d, %lu files, %s read, %s written in %s\n", frmt->name, arvol-1, (unsigned long)flcnt, sizefmt(s1buf, sizeof(s1buf), rdcnt), sizefmt(s2buf, sizeof(s2buf), wrcnt), timefmt(tbuf, sizeof(tbuf), rdcnt + wrcnt, secs, "bytes")); } if (n == 0) (void)fprintf(outf, "%s: %s", argv0, buf); else (void)write(STDERR_FILENO, buf, strlen(buf)); }
static int done(register Joblist_t* job, int clear, Cojob_t* cojob) { register List_t* p; register Rule_t* a; Time_t tm; int n; int semaphore; Rule_t* jammed; Rule_t* waiting; if (clear && jobs.triggered && (((a = jobs.triggered)->property & P_state) || (a = staterule(RULE, a, NiL, 0))) && (a->property & P_force)) { a->time = 0; state.savestate = 1; } another: jobstatus(); if (job->status == INTERMEDIATE) state.intermediate--; else if (!clear && job->status == RUNNING && (job->target->dynamic & D_hasafter) && hasafter(job->target, (job->flags & CO_ERRORS) ? P_failure : P_after)) { job->status = BEFORE; for (p = job->target->prereqs; p; p = p->next) { if ((a = p->rule)->dynamic & D_alias) a = makerule(a->name); if (a->status == MAKING && !a->semaphore || !(a->property & P_make) && a->status == UPDATE) return 0; } after: #if __GNUC__ == 3 && ( sparc || _sparc || __sparc ) && !_HUH_2008_10_25 /* gcc code generation bug -- first hit on solaris -- not sure if for all gcc 3.* */ #ifndef __GNUC_MINOR__ #define __GNUC_MINOR__ 0 #endif #ifndef __GNUC_PATCHLEVEL__ #define __GNUC_PATCHLEVEL__ 1 #endif if (!jobs.firstjob) { static int warned = 0; if (!warned) { warned = 1; error(state.mam.regress || state.regress ? -1 : 1, "command.c:%d: gcc %d.%d.%d code generation bug workaround -- pass this on to the vendor", __LINE__, __GNUC__, __GNUC_MINOR__, __GNUC_PATCHLEVEL__); } return !clear; } #endif push(job); n = makeafter(job->target, (job->flags & CO_ERRORS) ? P_failure : P_after); pop(job); if (n) job->flags |= CO_ERRORS; else { job->flags &= ~CO_ERRORS; for (p = job->prereqs; p; p = p->next) { if ((a = p->rule)->dynamic & D_alias) a = makerule(a->name); if (!a->semaphore && a->status == MAKING) { job->status = AFTER; return !state.coshell || cojobs(state.coshell) < state.jobs; } } } } /* * update rule times and status */ if (job->target->status != TOUCH) job->target->status = (job->flags & CO_ERRORS) ? ((job->target->property & P_dontcare) ? IGNORE : FAILED) : EXISTS; tm = statetime(job->target, 0); if (n = cojob && (state.mam.dynamic || state.mam.regress) && state.user && !(job->target->property & (P_after|P_before|P_dontcare|P_make|P_state|P_virtual))) sfprintf(state.mam.out, "%scode %s %d %s %s%s%s\n", state.mam.label, (job->target != state.frame->target || (job->target->property & P_after)) ? mamname(job->target) : "-", EXIT_CODE(cojob->status), timefmt(NiL, tm), timefmt(NiL, CURTIME), (job->target->dynamic & D_same) ? " same" : null, cojob->status && (job->flags & CO_IGNORE) ? " ignore" : null); if ((job->target->property & (P_joint|P_target)) == (P_joint|P_target)) for (p = job->target->prereqs->rule->prereqs; p; p = p->next) if (p->rule != job->target) { if (p->rule->status != TOUCH) p->rule->status = (job->flags & CO_ERRORS) ? ((p->rule->property & P_dontcare) ? IGNORE : FAILED) : EXISTS; tm = statetime(p->rule, 0); if (n) sfprintf(state.mam.out, "%scode %s %d %s%s%s\n", state.mam.label, mamname(p->rule), EXIT_CODE(cojob->status), timefmt(NiL, tm), (p->rule->dynamic & D_same) ? " same" : null, cojob->status && (job->flags & CO_IGNORE) ? " ignore" : null); } /* * update the job list */ discard(job); again: jammed = 0; if (job = jobs.firstjob) for (;;) { switch (job->status) { case AFTER: case BEFORE: case BLOCKED: case READY: n = READY; semaphore = 1; waiting = 0; for (p = job->prereqs; p; p = p->next) { if ((a = p->rule)->dynamic & D_alias) a = makerule(a->name); if ((a->property & P_after) && job->status != BEFORE && job->status != AFTER) continue; switch (a->status) { case FAILED: if (a->property & P_repeat) continue; job->flags |= CO_ERRORS; goto another; case MAKING: if (!jammed && (a->mark & M_waiting) && !(a->property & P_archive)) { waiting = a; continue; } waiting = 0; n = BLOCKED; if (!a->semaphore) semaphore = 0; break; default: continue; } break; } if (waiting) jammed = waiting; else if (!clear && job->status == AFTER) { if (n == READY || semaphore) goto another; } else if (!clear && job->status == BEFORE) { if (n == READY || semaphore) goto after; } else if ((job->status = n) == READY) { unjam: if (clear || cancel(job->target, job->prereqs)) goto another; if ((job->target->dynamic & D_intermediate) && job->target->must == 1) { job->status = INTERMEDIATE; jobs.intermediate++; } else if ((job->target->dynamic & (D_hasbefore|D_triggered)) == (D_hasbefore|D_triggered)) { push(job); n = makebefore(job->target); pop(job); if (n) { job->flags |= CO_ERRORS; goto another; } } else if (!state.coshell || cojobs(state.coshell) < state.jobs) { execute(job); goto again; } } break; case RUNNING: if (clear && job->cojob && (job->cojob->flags & CO_SERVICE)) { job->status = FAILED; job->flags |= CO_ERRORS; cokill(state.coshell, job->cojob, 0); } break; } if (!(job = job->next)) { /* * jammed is the first discovered member * of a possible deadlock and we arbitrarily * break it here */ if (jammed) { if (error_info.trace || state.explain) error(state.explain ? 0 : -1, "breaking possible job deadlock at %s", jammed->name); for (job = jobs.firstjob; job; job = job->next) #if __GNUC__ >= 4 && !_HUH_2006_01_11 /* gcc code generation bug -- first hit on macos -- not sure if for all gcc 4.* */ #ifndef __GNUC_MINOR__ #define __GNUC_MINOR__ 0 #endif #ifndef __GNUC_PATCHLEVEL__ #define __GNUC_PATCHLEVEL__ 1 #endif if (!job) { static int warned = 0; if (!warned) { warned = 1; error(state.mam.regress || state.regress ? -1 : 1, "command.c:%d: gcc %d.%d.%d code generation bug workaround -- pass this on to the vendor", __LINE__, __GNUC__, __GNUC_MINOR__, __GNUC_PATCHLEVEL__); } break; } else #endif if (job->target == jammed) { if (job->status == AFTER) goto another; if (job->status != RUNNING) { jammed = 0; job->status = READY; state.jobs++; goto unjam; } } } break; } } return !clear; }
static void execute(register Joblist_t* job) { register List_t* p; char* s; char* t; int flags; Rule_t* r; Var_t* v; Sfio_t* tmp; Sfio_t* att; Sfio_t* sp; att = sfstropen(); tmp = sfstropen(); restore(job, tmp, att); job->status = RUNNING; job->target->mark &= ~M_waiting; if (state.targetcontext || state.maxview && !state.fsview && *job->target->name != '/' && (!(job->target->dynamic & D_regular) || job->target->view)) commit(job, job->target->name); if ((state.mam.dynamic || state.mam.regress) && state.user && !(job->target->property & (P_after|P_before|P_dontcare|P_make|P_state|P_virtual))) sfprintf(state.mam.out, "%sinit %s %s\n", state.mam.label, mamname(job->target), timefmt(NiL, CURTIME)); t = sfstruse(tmp); if (!(job->flags & CO_ALWAYS)) { if (state.touch) { if (state.virtualdot) { state.virtualdot = 0; lockstate(1); } if (!(job->target->property & (P_attribute|P_virtual))) { acceptrule(job->target); if ((job->target->property & (P_joint|P_target)) == (P_joint|P_target)) for (p = job->target->prereqs->rule->prereqs; p; p = p->next) if (p->rule != job->target) acceptrule(p->rule); } } else if (*t && (!state.silent || state.mam.regress)) dumpaction(state.mam.out ? state.mam.out : sfstdout, NiL, t, NiL); done(job, 0, NiL); } else { if (state.virtualdot && !notfile(job->target)) { state.virtualdot = 0; lockstate(1); } if (!state.coshell) { sp = sfstropen(); sfprintf(sp, "label=%s", idname); expand(sp, " $(" CO_ENV_OPTIONS ")"); flags = CO_ANY; if (state.cross) flags |= CO_CROSS; if (state.serialize && state.jobs > 1) flags |= CO_SERIALIZE; if (!(state.coshell = coopen(getval(CO_ENV_SHELL, VAL_PRIMARY), flags, sfstruse(sp)))) error(ERROR_SYSTEM|3, "coshell open error"); sfstrclose(sp); } if (p = internal.exports->prereqs) { Sfio_t* exp; exp = sfstropen(); do { if (v = getvar(p->rule->name)) { expand(exp, v->value); coexport(state.coshell, p->rule->name, sfstruse(exp)); } else if (s = strchr(p->rule->name, '=')) { *s = 0; expand(exp, s + 1); coexport(state.coshell, p->rule->name, sfstruse(exp)); *s = '='; } } while (p = p->next); sfstrclose(exp); #if 0 freelist(internal.exports->prereqs); #endif internal.exports->prereqs = 0; } if (job->flags & CO_DATAFILE) { static char* dot; static char* tmp; if (job->target->property & P_read) { if (!dot) dot = pathtemp(NiL, 0, null, idname, NiL); state.tmpfile = dot; } else { if (!tmp) tmp = pathtemp(NiL, 0, NiL, idname, NiL); state.tmpfile = tmp; } } #if !_HUH_1992_02_29 /* i386 and ftx m68k dump without this statement -- help */ message((-99, "execute: %s: t=0x%08x &t=0x%08x", job->target->name, t, &t)); #endif if (state.mam.out) dumpaction(state.mam.out, MAMNAME(job->target), t, NiL); if (r = getrule(external.makerun)) maketop(r, P_dontcare|P_foreground, NiL); if (!(job->cojob = coexec(state.coshell, t, job->flags, state.tmpfile, NiL, sfstruse(att)))) error(3, "%s: cannot send action to coshell", job->target->name); job->cojob->local = (void*)job; /* * grab semaphores */ if (job->target->dynamic & D_hassemaphore) { job->flags |= CO_SEMAPHORES; for (p = job->prereqs; p; p = p->next) if (p->rule->semaphore && --p->rule->semaphore == 1) p->rule->status = MAKING; } /* * check status and sync */ if (job->target->dynamic & D_hasafter) save(job); if (job->flags & (CO_DATAFILE|CO_FOREGROUND)) { complete(job->target, NiL, NiL, 0); if (job->target->property & (P_functional|P_read)) { if (sp = sfopen(NiL, state.tmpfile, "r")) { remove(state.tmpfile); if (job->target->property & P_read) parse(sp, NiL, job->target->name, NiL); else { char* e; sfmove(sp, tmp, SF_UNBOUND, -1); t = sfstrbase(tmp); e = sfstrseek(tmp, 0, SEEK_CUR); while (e > t && *(e - 1) == '\n') e--; sfstrseek(tmp, e - t, SEEK_SET); setvar(job->target->name, sfstruse(tmp), 0); } sfclose(sp); } else error(2, "%s: cannot read temporary data output file %s", job->target->name, state.tmpfile); state.tmpfile = 0; } } } sfstrclose(att); sfstrclose(tmp); }