X-Git-Url: https://git.distorted.org.uk/~mdw/sw-tools/blobdiff_plain/3315e8b31a4707ef2c5491d0c9a9c9a09816bcb2..1efab4fe37e9a69e5c34c7d9be478b63928692e2:/src/sw_build.c diff --git a/src/sw_build.c b/src/sw_build.c index 3e8476a..4933363 100644 --- a/src/sw_build.c +++ b/src/sw_build.c @@ -1,6 +1,6 @@ /* -*-c-*- * - * $Id: sw_build.c,v 1.1 1999/06/02 16:53:34 mdw Exp $ + * $Id: sw_build.c,v 1.3 1999/09/10 15:27:33 mdw Exp $ * * Management of build processes * @@ -29,8 +29,14 @@ /*----- Revision history --------------------------------------------------* * * $Log: sw_build.c,v $ - * Revision 1.1 1999/06/02 16:53:34 mdw - * Initial revision + * Revision 1.3 1999/09/10 15:27:33 mdw + * Include `%'-escape substitution. + * + * Revision 1.2 1999/07/16 12:50:24 mdw + * Improve exit status display. New interface from `doto' project. + * + * Revision 1.1.1.1 1999/06/02 16:53:34 mdw + * Initial import. * */ @@ -53,6 +59,7 @@ #include #include #include +#include #ifndef DECL_ENVIRON extern char **environ; @@ -224,13 +231,92 @@ int sw_run(int argc, char *argv[]) { archcons *aa; + dstr d = DSTR_INIT; + char **av; + struct utsname u; + + /* --- Fill in the hostname --- */ + + if (uname(&u)) + strcpy(u.nodename, ""); + + /* --- If necessary, set up the output @argv@ array --- */ + + if (opt_flags & optFlag_percent) + av = xmalloc(argc * sizeof(char *)); + else + av = argv + 1; + + /* --- Run through the target build hosts --- */ FD_ZERO(&fdin); for (aa = a; aa; aa = aa->cdr) { archent *e = aa->car; sw_remote *r = e->r; + + /* --- If necessary, translate `%'-escapes --- */ + + if (opt_flags & optFlag_percent) { + char **pp, **qq; + + for (pp = argv + 1, qq = av; *pp; pp++, qq++) { + if (strchr(*pp, '%') == 0) + *qq = *pp; + else { + char *p; + char *q = *pp; + for (p = *pp; *p; p++) { + if (*p == '%') { + DPUTM(&d, q, p - q); + p++; + switch (*p) { + case 0: + DPUTC(&d, '%'); + goto done_arg; + case '%': + DPUTC(&d, '%'); + break; + case 'a': + dstr_puts(&d, e->arch); + break; + case 'h': + dstr_puts(&d, e->flags & archFlag_home ? + u.nodename : e->host); + break; + case 'P': + dstr_puts(&d, PREFIX); + break; + case 'p': + dstr_puts(&d, sw.package); + break; + case 'v': + dstr_puts(&d, sw.version); + break; + case 'u': + dstr_puts(&d, sw.maintainer); + break; + default: + DPUTC(&d, '%'); + DPUTC(&d, *p); + break; + } + q = p + 1; + } + } + DPUTM(&d, q, p - q); + done_arg: + DPUTZ(&d); + *qq = xstrdup(d.buf); + DRESET(&d); + } + } + *qq++ = 0; + } + + /* --- Start a new process off --- */ + if (swrsh(r, e->flags & archFlag_home ? 0 : e->host, - "build", argv + 1)) { + "build", av)) { dstr d = DSTR_INIT; dstr_putf(&d, "%s: couldn't start build for architecture `%s': %s", QUIS, e->arch, strerror(errno)); @@ -245,7 +331,21 @@ int sw_run(int argc, char *argv[]) active++; FD_SET(fd, &fdin); } + + /* --- Free up the argument array --- */ + + if (opt_flags & optFlag_percent) { + char **pp, **qq; + + for (pp = argv + 1, qq = av; *pp; pp++, qq++) { + if (*pp != *qq) + free(*qq); + } + } } + + if (opt_flags & optFlag_percent) + free(av); } /* --- Watch the builds until they do something interesting --- */ @@ -288,31 +388,29 @@ int sw_run(int argc, char *argv[]) int ok = 1; if (r->sz != 1) { r->buf[r->sz] = 0; - dstr_putf(&d, "\nTerminated by signal: %s.\n", r->buf); + dstr_putf(&d, "failed (%s)", r->buf); ok = 0; rc = 1; } else if (r->buf[0]) { - dstr_putf(&d, "\nExited with status %u.\n", - (unsigned char)r->buf[0]); + dstr_putf(&d, "failed (status %u)", (unsigned char)r->buf[0]); ok = 0; rc = 1; - } else if (opt_flags & optFlag_install) - e->flags |= archFlag_built; - if (d.len) - p->output(e, d.buf, d.len); - dstr_destroy(&d); + } else { + dstr_puts(&d, "finished"); + if (opt_flags & optFlag_install) + e->flags |= archFlag_built; + } if (p->close) - p->close(e, ok); + p->close(e, ok, d.buf); + dstr_destroy(&d); FD_CLR(r->fdin, &fdin); close(r->fdin); active--; } break; case PKTYPE_EOF: { - const static char msg[] = "\nUnexpected exit.\n"; - p->output(e, msg, sizeof(msg) - 1); if (p->close) - p->close(e, 0); + p->close(e, 0, "unexpected exit"); rc = 1; FD_CLR(r->fdin, &fdin); close(r->fdin); @@ -339,7 +437,7 @@ int sw_run(int argc, char *argv[]) p->abort(a); switch (exc_type) { case EXC_ERRNO: - die(1, "unexpected error: %s", exc_i); + die(1, "unexpected error: %s", strerror(exc_i)); break; default: RETHROW; @@ -428,7 +526,7 @@ void swrsh_build(sw_remote *r, char *argv[], char *env[]) int fd[2]; pid_t kid; - /* --- Validate arguments --- */ + /* --- Validate the arguments --- */ if (!argv[0]) swdie(r, 1, "Usage: build COMMAND [ARG...]"); @@ -452,7 +550,10 @@ void swrsh_build(sw_remote *r, char *argv[], char *env[]) struct tm *tm; char buf[64]; char **p; + struct utsname u; + if (uname(&u)) + swdie(r, 1, "couldn't get hostname: %s", strerror(errno)); if (logfd < 0) swdie(r, 1, "couldn't open `.build-log' file: %s", strerror(errno)); if ((logfp = fdopen(logfd, "a")) == 0) { @@ -462,7 +563,8 @@ void swrsh_build(sw_remote *r, char *argv[], char *env[]) t = time(0); tm = localtime(&t); strftime(buf, sizeof(buf), "%Y-%m-%d %H:%M:%S", tm); - fprintf(logfp, "\n\n*** %s: started build: %s", buf, argv[0]); + fprintf(logfp, "\n\n*** %s: %s started build: %s", + buf, u.nodename, argv[0]); for (p = argv + 1; *p; p++) fprintf(logfp, " %s", *p); fputs("\n\n", logfp); @@ -498,7 +600,7 @@ void swrsh_build(sw_remote *r, char *argv[], char *env[]) if (!n) break; if (n < 0) { - putf(r, logfp, "*** error reading from pipe: %s\n", strerror(errno)); + putf(r, logfp, "\n*** error reading from pipe: %s\n", strerror(errno)); kill(kid, SIGTERM); break; } @@ -511,15 +613,16 @@ void swrsh_build(sw_remote *r, char *argv[], char *env[]) { int status; - if (waitpid(kid, &status, 0) < 0) - putf(r, logfp, "*** error reading exit status: %s\n", strerror(errno)); - else { + if (waitpid(kid, &status, 0) < 0) { + putf(r, logfp, "\n*** error reading exit status: %s\n", + strerror(errno)); + } else { if (WIFSIGNALED(status)) - fprintf(logfp, "*** exited on signal %i\n", WTERMSIG(status)); + fprintf(logfp, "\n*** exited on signal %i\n", WTERMSIG(status)); else if (WIFEXITED(status)) - fprintf(logfp, "*** exited with status %i\n", WEXITSTATUS(status)); + fprintf(logfp, "\n*** exited with status %i\n", WEXITSTATUS(status)); else - fprintf(logfp, "*** reaped, but didn't exit. Strange\n"); + fprintf(logfp, "\n*** reaped, but didn't exit. Strange\n"); } fclose(logfp); swwait(r, status);