X-Git-Url: http://git.ozlabs.org/?p=ccan;a=blobdiff_plain;f=tools%2Ftools.c;h=0a29ddf8e64cce7875a8a9d8c8fe37a0c6d90a13;hp=2983cfca663bc730130899ae96cb16a75e62baa2;hb=6bc8ea012391198bc3898ae2937558b60dd55906;hpb=0939b69164c65329fa8f6b2c4ab5e9c7d9162678 diff --git a/tools/tools.c b/tools/tools.c index 2983cfca..0a29ddf8 100644 --- a/tools/tools.c +++ b/tools/tools.c @@ -3,6 +3,7 @@ #include #include #include +#include #include #include #include @@ -14,10 +15,11 @@ #include #include #include +#include +#include #include "tools.h" -static char *tmpdir = NULL; -static unsigned int count; +static const char *tmpdir = NULL; bool tools_verbose = false; /* Ten minutes. */ @@ -71,7 +73,7 @@ char *run_with_timeout(const void *ctx, const char *cmd, int p[2]; char *ret; int status, ms; - struct timeval start, end; + struct timeval start; *ok = false; if (pipe(p) != 0) @@ -81,7 +83,9 @@ char *run_with_timeout(const void *ctx, const char *cmd, if (tools_verbose) printf("Running: %s\n", cmd); - gettimeofday(&start, NULL); + /* Always flush buffers before fork! */ + fflush(stdout); + start = time_now(); pid = fork(); if (pid == -1) { close_noerr(p[0]); @@ -103,8 +107,7 @@ char *run_with_timeout(const void *ctx, const char *cmd, signal(SIGALRM, killme); itim.it_interval.tv_sec = itim.it_interval.tv_usec = 0; - itim.it_value.tv_sec = *timeout_ms / 1000; - itim.it_value.tv_usec = (*timeout_ms % 1000) * 1000; + itim.it_value = time_from_msec(*timeout_ms); setitimer(ITIMER_REAL, &itim, NULL); status = system(cmd); @@ -120,18 +123,12 @@ char *run_with_timeout(const void *ctx, const char *cmd, if (waitpid(pid, &status, 0) != pid) err(1, "Failed to wait for child"); - gettimeofday(&end, NULL); - if (end.tv_usec < start.tv_usec) { - end.tv_usec += 1000000; - end.tv_sec--; - } - ms = (end.tv_sec - start.tv_sec) * 1000 - + (end.tv_usec - start.tv_usec) / 1000; + ms = time_to_msec(time_sub(time_now(), start)); if (ms > *timeout_ms) *timeout_ms = 0; else *timeout_ms -= ms; - + close(p[0]); if (tools_verbose) { printf("%s", ret); printf("Finished: %u ms, %s %u\n", ms, @@ -143,38 +140,38 @@ char *run_with_timeout(const void *ctx, const char *cmd, return ret; } -/* Returns output if command fails. */ -char *run_command(const void *ctx, unsigned int *time_ms, const char *fmt, ...) +/* Tallocs *output off ctx; return false if command fails. */ +bool run_command(const void *ctx, unsigned int *time_ms, char **output, + const char *fmt, ...) { va_list ap; - char *cmd, *contents; + char *cmd; bool ok; unsigned int default_time = default_timeout_ms; if (!time_ms) time_ms = &default_time; - else if (*time_ms == 0) - return talloc_strdup(ctx, "\n== TIMED OUT ==\n"); + else if (*time_ms == 0) { + *output = talloc_strdup(ctx, "\n== TIMED OUT ==\n"); + return false; + } va_start(ap, fmt); cmd = talloc_vasprintf(ctx, fmt, ap); va_end(ap); - contents = run_with_timeout(ctx, cmd, &ok, time_ms); - if (ok) { - talloc_free(contents); - return NULL; - } - - if (!contents) + *output = run_with_timeout(ctx, cmd, &ok, time_ms); + if (ok) + return true; + if (!*output) err(1, "Problem running child"); if (*time_ms == 0) - contents = talloc_asprintf_append(contents, - "\n== TIMED OUT ==\n"); - return contents; + *output = talloc_asprintf_append(*output, + "\n== TIMED OUT ==\n"); + return false; } -static int unlink_all(char *dir) +static int unlink_all(const char *dir) { char cmd[strlen(dir) + sizeof("rm -rf ")]; sprintf(cmd, "rm -rf %s", dir); @@ -185,7 +182,7 @@ static int unlink_all(char *dir) return 0; } -char *temp_dir(const void *ctx) +const char *temp_dir(const void *ctx) { /* For first call, create dir. */ while (!tmpdir) { @@ -204,34 +201,48 @@ char *temp_dir(const void *ctx) err(1, "mkdir %s failed", tmpdir); } talloc_set_destructor(tmpdir, unlink_all); + if (tools_verbose) + printf("Created temporary directory %s\n", tmpdir); } - if (tools_verbose) - printf("Created temporary directory %s\n", tmpdir); return tmpdir; } -char *temp_file(const void *ctx, const char *extension) +int unlink_file_destructor(char *filename) { - char *f = talloc_asprintf(ctx, "%s/%u%s", - temp_dir(ctx), count++, extension); - if (tools_verbose) - printf("Created temporary file %s\n", f); - return f; + unlink(filename); + return 0; } char *maybe_temp_file(const void *ctx, const char *extension, bool keep, const char *srcname) { - size_t baselen; - char *f; + unsigned baselen; + char *f, *suffix = talloc_strdup(ctx, ""); + struct stat st; + unsigned int count = 0; + + srcname = talloc_basename(ctx, srcname); + if (strrchr(srcname, '.')) + baselen = strrchr(srcname, '.') - srcname; + else + baselen = strlen(srcname); - if (!keep) - return temp_file(ctx, extension); + do { + f = talloc_asprintf(ctx, "%s/%.*s%s%s", + temp_dir(ctx), + baselen, srcname, + suffix, extension); + talloc_free(suffix); + suffix = talloc_asprintf(ctx, "-%u", ++count); + } while (lstat(f, &st) == 0); - baselen = strrchr(srcname, '.') - srcname; - f = talloc_asprintf(ctx, "%.*s%s", baselen, srcname, extension); if (tools_verbose) - printf("Creating file %s\n", f); + printf("Creating %sfile %s\n", keep ? "" : "temporary ", f); + + if (!keep) + talloc_set_destructor(f, unlink_file_destructor); + + talloc_free(suffix); return f; }