X-Git-Url: http://www.chiark.greenend.org.uk/ucgi/~mdw/git/sw-tools/blobdiff_plain/fef14233a620e44984fa88dfddf403e6cd2d4f20..1efab4fe37e9a69e5c34c7d9be478b63928692e2:/src/sw_build.c diff --git a/src/sw_build.c b/src/sw_build.c index cfa765b..4933363 100644 --- a/src/sw_build.c +++ b/src/sw_build.c @@ -1,6 +1,6 @@ /* -*-c-*- * - * $Id: sw_build.c,v 1.2 1999/07/16 12:50:24 mdw Exp $ + * $Id: sw_build.c,v 1.3 1999/09/10 15:27:33 mdw Exp $ * * Management of build processes * @@ -29,6 +29,9 @@ /*----- Revision history --------------------------------------------------* * * $Log: sw_build.c,v $ + * 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. * @@ -56,6 +59,7 @@ #include #include #include +#include #ifndef DECL_ENVIRON extern char **environ; @@ -227,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)); @@ -248,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 --- */ @@ -429,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...]"); @@ -453,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) { @@ -463,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); @@ -499,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; } @@ -512,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);