diff options
author | Russ Allbery <eagle@eyrie.org> | 2018-04-22 19:21:42 -0700 |
---|---|---|
committer | Russ Allbery <eagle@eyrie.org> | 2018-04-22 19:21:42 -0700 |
commit | ca1f45155f1cf60e31d0da2bf5f788c5e8448824 (patch) | |
tree | 8dfec4fc243fb3dc4b8ca838ede09b35df59bcaf /tests | |
parent | aafef3f0fd940add7d0ef40b63c4263f9e18b7db (diff) |
Refresh rra-c-util 7.1 and C TAP Harness 4.3
rra-c-util 7.1:
* Support running remctld under valgrind for memory leak testing.
* Update the valgrind suppression file.
C TAP Harness 4.3:
* Add support for valgrind testing via test list options.
Diffstat (limited to 'tests')
-rw-r--r-- | tests/data/valgrind.supp | 11 | ||||
-rw-r--r-- | tests/portable/getnameinfo-t.c | 10 | ||||
-rw-r--r-- | tests/runtests.c | 211 | ||||
-rw-r--r-- | tests/tap/basic.c | 78 | ||||
-rw-r--r-- | tests/tap/basic.h | 25 | ||||
-rw-r--r-- | tests/tap/remctl.c | 18 | ||||
-rw-r--r-- | tests/util/network/client-t.c | 10 |
7 files changed, 277 insertions, 86 deletions
diff --git a/tests/data/valgrind.supp b/tests/data/valgrind.supp index e6b50c0..5c10054 100644 --- a/tests/data/valgrind.supp +++ b/tests/data/valgrind.supp @@ -11,7 +11,7 @@ # which can be found at <https://www.eyrie.org/~eagle/software/rra-c-util/>. # # Written by Russ Allbery <eagle@eyrie.org> -# Copyright 2017 Russ Allbery <eagle@eyrie.org> +# Copyright 2017-2018 Russ Allbery <eagle@eyrie.org> # Copyright 2011-2014 # The Board of Trustees of the Leland Stanford Junior University # @@ -42,6 +42,15 @@ fun:_dlerror_run } { + fakeroot-msgsnd + Memcheck:Param + msgsnd(msgp->mtext) + fun:msgsnd + fun:send_fakem + fun:send_get_fakem + obj:*/libfakeroot-sysv.so +} +{ heimdal-base-once Memcheck:Leak fun:*alloc diff --git a/tests/portable/getnameinfo-t.c b/tests/portable/getnameinfo-t.c index 835c60e..7b72d62 100644 --- a/tests/portable/getnameinfo-t.c +++ b/tests/portable/getnameinfo-t.c @@ -5,7 +5,7 @@ * which can be found at <https://www.eyrie.org/~eagle/software/rra-c-util/>. * * Written by Russ Allbery <eagle@eyrie.org> - * Copyright 2005-2006, 2014 Russ Allbery <eagle@eyrie.org> + * Copyright 2005-2006, 2014, 2018 Russ Allbery <eagle@eyrie.org> * Copyright 2007-2011 * The Board of Trustees of the Leland Stanford Junior University * @@ -120,20 +120,20 @@ main(void) * some well-known host and make sure that getnameinfo returns the same * results. This may need to be skipped. */ - hp = gethostbyname("www.isc.org"); + hp = gethostbyname("a.root-servers.net"); if (hp == NULL) - skip_block(2, "cannot look up www.isc.org"); + skip_block(2, "cannot look up a.root-servers.net"); else { memcpy(&sin.sin_addr, hp->h_addr, sizeof(sin.sin_addr)); hp = gethostbyaddr((const void *) &sin.sin_addr, sizeof(sin.sin_addr), AF_INET); if (hp == NULL || strchr(hp->h_name, '.') == NULL) - skip_block(2, "cannot reverse-lookup www.isc.org"); + skip_block(2, "cannot reverse-lookup a.root-servers.net"); else { name = xstrdup(hp->h_name); status = test_getnameinfo(sa, sizeof(sin), node, sizeof(node), NULL, 0, 0); - is_int(0, status, "lookup of www.isc.org IP address"); + is_int(0, status, "lookup of a.root-servers.net IP address"); is_string(name, node, "...matches gethostbyaddr"); free(name); } diff --git a/tests/runtests.c b/tests/runtests.c index 74900e0..af15a5c 100644 --- a/tests/runtests.c +++ b/tests/runtests.c @@ -39,9 +39,10 @@ * runtests -o [-h] [-b <build-dir>] [-s <source-dir>] <test> * * In the first case, expects a list of executables located in the given file, - * one line per executable. For each one, runs it as part of a test suite, - * reporting results. In the second case, use the same infrastructure, but - * run only the tests listed on the command line. + * one line per executable, possibly followed by a space-separated list of + * options. For each one, runs it as part of a test suite, reporting results. + * In the second case, use the same infrastructure, but run only the tests + * listed on the command line. * * Test output should start with a line containing the number of tests * (numbered from 1 to this number), optionally preceded by "1..", although @@ -185,7 +186,7 @@ enum plan_status { /* Structure to hold data for a set of tests. */ struct testset { char *file; /* The file name of the test. */ - char *path; /* The path to the test program. */ + char **command; /* The argv vector to run the command. */ enum plan_status plan; /* The status of our plan. */ unsigned long count; /* Expected count of tests. */ unsigned long current; /* The last seen test number. */ @@ -196,7 +197,7 @@ struct testset { unsigned long allocated; /* The size of the results table. */ enum test_status *results; /* Table of results by test number. */ unsigned int aborted; /* Whether the set was aborted. */ - int reported; /* Whether the results were reported. */ + unsigned int reported; /* Whether the results were reported. */ int status; /* The exit status of the test. */ unsigned int all_skipped; /* Whether all tests were skipped. */ char *reason; /* Why all tests were skipped. */ @@ -248,6 +249,7 @@ Failed Set Fail/Total (%) Skip Stat Failing Tests\n\ #define xcalloc(n, size) x_calloc((n), (size), __FILE__, __LINE__) #define xmalloc(size) x_malloc((size), __FILE__, __LINE__) #define xstrdup(p) x_strdup((p), __FILE__, __LINE__) +#define xstrndup(p, size) x_strndup((p), (size), __FILE__, __LINE__) #define xreallocarray(p, n, size) \ x_reallocarray((p), (n), (size), __FILE__, __LINE__) @@ -288,6 +290,8 @@ Failed Set Fail/Total (%) Skip Stat Failing Tests\n\ #endif /* Declare internal functions that benefit from compiler attributes. */ +static void die(const char *, ...) + __attribute__((__nonnull__, __noreturn__, __format__(printf, 1, 2))); static void sysdie(const char *, ...) __attribute__((__nonnull__, __noreturn__, __format__(printf, 1, 2))); static void *x_calloc(size_t, size_t, const char *, int) @@ -298,6 +302,26 @@ static void *x_reallocarray(void *, size_t, size_t, const char *, int) __attribute__((__alloc_size__(2, 3), __malloc__, __nonnull__(4))); static char *x_strdup(const char *, const char *, int) __attribute__((__malloc__, __nonnull__)); +static char *x_strndup(const char *, size_t, const char *, int) + __attribute__((__malloc__, __nonnull__)); + + +/* + * Report a fatal error and exit. + */ +static void +die(const char *format, ...) +{ + va_list args; + + fflush(stdout); + fprintf(stderr, "runtests: "); + va_start(args, format); + vfprintf(stderr, format, args); + va_end(args); + fprintf(stderr, "\n"); + exit(1); +} /* @@ -400,6 +424,35 @@ x_strdup(const char *s, const char *file, int line) /* + * Copy the first n characters of a string, reporting a fatal error and + * existing on failure. + * + * Avoid using the system strndup function since it may not exist (on Mac OS + * X, for example), and there's no need to introduce another portability + * requirement. + */ +char * +x_strndup(const char *s, size_t size, const char *file, int line) +{ + const char *p; + size_t len; + char *copy; + + /* Don't assume that the source string is nul-terminated. */ + for (p = s; (size_t) (p - s) < size && *p != '\0'; p++) + ; + len = (size_t) (p - s); + copy = malloc(len + 1); + if (copy == NULL) + sysdie("failed to strndup %lu bytes at %s line %d", + (unsigned long) len, file, line); + memcpy(copy, s, len); + copy[len] = '\0'; + return copy; +} + + +/* * Form a new string by concatenating multiple strings. The arguments must be * terminated by (const char *) 0. * @@ -493,12 +546,25 @@ skip_whitespace(const char *p) /* + * Given a pointer to a string, skip any non-whitespace characters and return + * a pointer to the first whitespace character, or to the end of the string. + */ +static const char * +skip_non_whitespace(const char *p) +{ + while (*p != '\0' && !isspace((unsigned char)(*p))) + p++; + return p; +} + + +/* * Start a program, connecting its stdout to a pipe on our end and its stderr * to /dev/null, and storing the file descriptor to read from in the two * argument. Returns the PID of the new process. Errors are fatal. */ static pid_t -test_start(const char *path, int *fd) +test_start(char *const *command, int *fd) { int fds[2], infd, errfd; pid_t child; @@ -549,7 +615,7 @@ test_start(const char *path, int *fd) } /* Now, exec our process. */ - if (execl(path, path, (char *) 0) == -1) + if (execv(command[0], command) == -1) _exit(CHILDERR_EXEC); break; @@ -1044,7 +1110,7 @@ test_run(struct testset *ts, enum test_verbose verbose) char buffer[BUFSIZ]; /* Run the test program. */ - testpid = test_start(ts->path, &outfd); + testpid = test_start(ts->command, &outfd); output = fdopen(outfd, "r"); if (!output) { puts("ABORTED"); @@ -1214,19 +1280,111 @@ find_test(const char *name, const char *source, const char *build) /* + * Parse a single line of a test list and store the test name and command to + * execute it in the given testset struct. + * + * Normally, each line is just the name of the test, which is located in the + * test directory and turned into a command to run. However, each line may + * have whitespace-separated options, which change the command that's run. + * Current supported options are: + * + * valgrind + * Run the test under valgrind if C_TAP_VALGRIND is set. The contents + * of that environment variable are taken as the valgrind command (with + * options) to run. The command is parsed with a simple split on + * whitespace and no quoting is supported. + * + * libtool + * If running under valgrind, use libtool to invoke valgrind. This avoids + * running valgrind on the wrapper shell script generated by libtool. If + * set, C_TAP_LIBTOOL must be set to the full path to the libtool program + * to use to run valgrind and thus the test. Ignored if the test isn't + * being run under valgrind. + */ +static void +parse_test_list_line(const char *line, struct testset *ts, const char *source, + const char *build) +{ + const char *p, *end, *option, *libtool; + const char *valgrind = NULL; + unsigned int use_libtool = 0; + unsigned int use_valgrind = 0; + size_t len, i; + + /* Determine the name of the test. */ + p = skip_non_whitespace(line); + ts->file = xstrndup(line, p - line); + + /* Check if any test options are set. */ + p = skip_whitespace(p); + while (*p != '\0') { + end = skip_non_whitespace(p); + if (strncmp(p, "libtool", end - p) == 0) { + use_libtool = 1; + p = end; + } else if (strncmp(p, "valgrind", end - p) == 0) { + valgrind = getenv("C_TAP_VALGRIND"); + use_valgrind = (valgrind != NULL); + p = end; + } else { + option = xstrndup(p, end - p); + die("unknown test list option %s", option); + } + p = skip_whitespace(end); + } + + /* Construct the argv to run the test. First, find the length. */ + len = 1; + if (use_valgrind && valgrind != NULL) { + p = skip_whitespace(valgrind); + while (*p != '\0') { + len++; + p = skip_whitespace(skip_non_whitespace(p)); + } + if (use_libtool) + len += 2; + } + + /* Now, build the command. */ + ts->command = xcalloc(len + 1, sizeof(char *)); + i = 0; + if (use_valgrind && valgrind != NULL) { + if (use_libtool) { + libtool = getenv("C_TAP_LIBTOOL"); + if (libtool == NULL) + die("valgrind with libtool requested, but C_TAP_LIBTOOL is not" + " set"); + ts->command[i++] = xstrdup(libtool); + ts->command[i++] = xstrdup("--mode=execute"); + } + p = skip_whitespace(valgrind); + while (*p != '\0') { + end = skip_non_whitespace(p); + ts->command[i++] = xstrndup(p, end - p); + p = skip_whitespace(end); + } + } + if (i != len - 1) + die("internal error while constructing command line"); + ts->command[i++] = find_test(ts->file, source, build); + ts->command[i] = NULL; +} + + +/* * Read a list of tests from a file, returning the list of tests as a struct * testlist, or NULL if there were no tests (such as a file containing only * comments). Reports an error to standard error and exits if the list of * tests cannot be read. */ static struct testlist * -read_test_list(const char *filename) +read_test_list(const char *filename, const char *source, const char *build) { FILE *file; unsigned int line; size_t length; char buffer[BUFSIZ]; - const char *testname; + const char *start; struct testlist *listhead, *current; /* Create the initial container list that will hold our results. */ @@ -1251,10 +1409,10 @@ read_test_list(const char *filename) buffer[length] = '\0'; /* Skip comments, leading spaces, and blank lines. */ - testname = skip_whitespace(buffer); - if (strlen(testname) == 0) + start = skip_whitespace(buffer); + if (strlen(start) == 0) continue; - if (testname[0] == '#') + if (start[0] == '#') continue; /* Allocate the new testset structure. */ @@ -1266,7 +1424,9 @@ read_test_list(const char *filename) } current->ts = xcalloc(1, sizeof(struct testset)); current->ts->plan = PLAN_INIT; - current->ts->file = xstrdup(testname); + + /* Parse the line and store the results in the testset struct. */ + parse_test_list_line(start, current->ts, source, build); } fclose(file); @@ -1288,7 +1448,7 @@ read_test_list(const char *filename) * freeing. */ static struct testlist * -build_test_list(char *argv[], int argc) +build_test_list(char *argv[], int argc, const char *source, const char *build) { int i; struct testlist *listhead, *current; @@ -1308,6 +1468,9 @@ build_test_list(char *argv[], int argc) current->ts = xcalloc(1, sizeof(struct testset)); current->ts->plan = PLAN_INIT; current->ts->file = xstrdup(argv[i]); + current->ts->command = xcalloc(2, sizeof(char *)); + current->ts->command[0] = find_test(current->ts->file, source, build); + current->ts->command[1] = NULL; } /* If there were no tests, current is still NULL. */ @@ -1325,8 +1488,12 @@ build_test_list(char *argv[], int argc) static void free_testset(struct testset *ts) { + size_t i; + free(ts->file); - free(ts->path); + for (i = 0; ts->command[i] != NULL; i++) + free(ts->command[i]); + free(ts->command); free(ts->results); free(ts->reason); free(ts); @@ -1341,8 +1508,7 @@ free_testset(struct testset *ts) * frees the test list that's passed in. */ static int -test_batch(struct testlist *tests, const char *source, const char *build, - enum test_verbose verbose) +test_batch(struct testlist *tests, enum test_verbose verbose) { size_t length, i; size_t longest = 0; @@ -1393,7 +1559,6 @@ test_batch(struct testlist *tests, const char *source, const char *build, fflush(stdout); /* Run the test. */ - ts->path = find_test(ts->file, source, build); succeeded = test_run(ts, verbose); fflush(stdout); if (verbose) @@ -1583,11 +1748,11 @@ main(int argc, char *argv[]) else shortlist++; printf(banner, shortlist); - tests = read_test_list(list); - status = test_batch(tests, source, build, verbose) ? 0 : 1; + tests = read_test_list(list, source, build); + status = test_batch(tests, verbose) ? 0 : 1; } else { - tests = build_test_list(argv, argc); - status = test_batch(tests, source, build, verbose) ? 0 : 1; + tests = build_test_list(argv, argc, source, build); + status = test_batch(tests, verbose) ? 0 : 1; } /* For valgrind cleanliness, free all our memory. */ diff --git a/tests/tap/basic.c b/tests/tap/basic.c index daa1955..8624839 100644 --- a/tests/tap/basic.c +++ b/tests/tap/basic.c @@ -490,22 +490,21 @@ skip_block(unsigned long count, const char *reason, ...) /* - * Takes an expected boolean value and a seen boolean value and assumes the - * test passes if the truth value of both match. + * Takes two boolean values and requires the truth value of both match. */ int -is_bool(int wanted, int seen, const char *format, ...) +is_bool(int left, int right, const char *format, ...) { int success; fflush(stderr); check_diag_files(); - success = (!!wanted == !!seen); + success = (!!left == !!right); if (success) printf("ok %lu", testnum++); else { - diag("wanted: %s", !!wanted ? "true" : "false"); - diag(" seen: %s", !!seen ? "true" : "false"); + diag(" left: %s", !!left ? "true" : "false"); + diag("right: %s", !!right ? "true" : "false"); printf("not ok %lu", testnum++); _failed++; } @@ -516,22 +515,21 @@ is_bool(int wanted, int seen, const char *format, ...) /* - * Takes an expected integer and a seen integer and assumes the test passes - * if those two numbers match. + * Takes two integer values and requires they match. */ int -is_int(long wanted, long seen, const char *format, ...) +is_int(long left, long right, const char *format, ...) { int success; fflush(stderr); check_diag_files(); - success = (wanted == seen); + success = (left == right); if (success) printf("ok %lu", testnum++); else { - diag("wanted: %ld", wanted); - diag(" seen: %ld", seen); + diag(" left: %ld", left); + diag("right: %ld", right); printf("not ok %lu", testnum++); _failed++; } @@ -542,26 +540,31 @@ is_int(long wanted, long seen, const char *format, ...) /* - * Takes a string and what the string should be, and assumes the test passes - * if those strings match (using strcmp). + * Takes two strings and requires they match (using strcmp). NULL arguments + * are permitted and handled correctly. */ int -is_string(const char *wanted, const char *seen, const char *format, ...) +is_string(const char *left, const char *right, const char *format, ...) { int success; - if (wanted == NULL) - wanted = "(null)"; - if (seen == NULL) - seen = "(null)"; fflush(stderr); check_diag_files(); - success = (strcmp(wanted, seen) == 0); + + /* Compare the strings, being careful of NULL. */ + if (left == NULL) + success = (right == NULL); + else if (right == NULL) + success = 0; + else + success = (strcmp(left, right) == 0); + + /* Report the results. */ if (success) printf("ok %lu", testnum++); else { - diag("wanted: %s", wanted); - diag(" seen: %s", seen); + diag(" left: %s", left == NULL ? "(null)" : left); + diag("right: %s", right == NULL ? "(null)" : right); printf("not ok %lu", testnum++); _failed++; } @@ -572,22 +575,22 @@ is_string(const char *wanted, const char *seen, const char *format, ...) /* - * Takes an expected unsigned long and a seen unsigned long and assumes the - * test passes if the two numbers match. Otherwise, reports them in hex. + * Takes two unsigned longs and requires they match. On failure, reports them + * in hex. */ int -is_hex(unsigned long wanted, unsigned long seen, const char *format, ...) +is_hex(unsigned long left, unsigned long right, const char *format, ...) { int success; fflush(stderr); check_diag_files(); - success = (wanted == seen); + success = (left == right); if (success) printf("ok %lu", testnum++); else { - diag("wanted: %lx", (unsigned long) wanted); - diag(" seen: %lx", (unsigned long) seen); + diag(" left: %lx", (unsigned long) left); + diag("right: %lx", (unsigned long) right); printf("not ok %lu", testnum++); _failed++; } @@ -598,12 +601,11 @@ is_hex(unsigned long wanted, unsigned long seen, const char *format, ...) /* - * Takes pointers to an expected region of memory and a seen region of memory - * and assumes the test passes if the len bytes onwards from them match. - * Otherwise reports any bytes which didn't match. + * Takes pointers to a regions of memory and requires that len bytes from each + * match. Otherwise reports any bytes which didn't match. */ int -is_blob(const void *wanted, const void *seen, size_t len, const char *format, +is_blob(const void *left, const void *right, size_t len, const char *format, ...) { int success; @@ -611,17 +613,17 @@ is_blob(const void *wanted, const void *seen, size_t len, const char *format, fflush(stderr); check_diag_files(); - success = (memcmp(wanted, seen, len) == 0); + success = (memcmp(left, right, len) == 0); if (success) printf("ok %lu", testnum++); else { - const unsigned char *wanted_c = wanted; - const unsigned char *seen_c = seen; + const unsigned char *left_c = left; + const unsigned char *right_c = right; for (i = 0; i < len; i++) { - if (wanted_c[i] != seen_c[i]) - diag("offset %lu: wanted %02x, seen %02x", (unsigned long) i, - wanted_c[i], seen_c[i]); + if (left_c[i] != right_c[i]) + diag("offset %lu: left %02x, right %02x", (unsigned long) i, + left_c[i], right_c[i]); } printf("not ok %lu", testnum++); _failed++; diff --git a/tests/tap/basic.h b/tests/tap/basic.h index 678ac7e..3f46e4f 100644 --- a/tests/tap/basic.h +++ b/tests/tap/basic.h @@ -4,9 +4,9 @@ * This file is part of C TAP Harness. The current version plus supporting * documentation is at <https://www.eyrie.org/~eagle/software/c-tap-harness/>. * - * Copyright 2009, 2010, 2011, 2012, 2013, 2014, 2015, 2016, 2017 - * Russ Allbery <eagle@eyrie.org> - * Copyright 2001, 2002, 2004, 2005, 2006, 2007, 2008, 2011, 2012, 2014 + * Written by Russ Allbery <eagle@eyrie.org> + * Copyright 2009-2018 Russ Allbery <eagle@eyrie.org> + * Copyright 2001-2002, 2004-2008, 2011-2012, 2014 * The Board of Trustees of the Leland Stanford Junior University * * Permission is hereby granted, free of charge, to any person obtaining a @@ -90,21 +90,20 @@ void skip_block(unsigned long count, const char *reason, ...) __attribute__((__format__(printf, 2, 3))); /* - * Check an expected value against a seen value. Returns true if the test - * passes and false if it fails. is_bool takes an int since the bool type - * isn't fully portable yet, but interprets both arguments for their truth - * value, not for their numeric value. + * Compare two values. Returns true if the test passes and false if it fails. + * is_bool takes an int since the bool type isn't fully portable yet, but + * interprets both arguments for their truth value, not for their numeric + * value. */ -int is_bool(int wanted, int seen, const char *format, ...) +int is_bool(int, int, const char *format, ...) __attribute__((__format__(printf, 3, 4))); -int is_int(long wanted, long seen, const char *format, ...) +int is_int(long, long, const char *format, ...) __attribute__((__format__(printf, 3, 4))); -int is_string(const char *wanted, const char *seen, const char *format, ...) +int is_string(const char *, const char *, const char *format, ...) __attribute__((__format__(printf, 3, 4))); -int is_hex(unsigned long wanted, unsigned long seen, const char *format, ...) +int is_hex(unsigned long, unsigned long, const char *format, ...) __attribute__((__format__(printf, 3, 4))); -int is_blob(const void *wanted, const void *seen, size_t, const char *format, - ...) +int is_blob(const void *, const void *, size_t, const char *format, ...) __attribute__((__format__(printf, 4, 5))); /* Bail out with an error. sysbail appends strerror(errno). */ diff --git a/tests/tap/remctl.c b/tests/tap/remctl.c index c911dac..3c88eb2 100644 --- a/tests/tap/remctl.c +++ b/tests/tap/remctl.c @@ -8,6 +8,7 @@ * which can be found at <https://www.eyrie.org/~eagle/software/rra-c-util/>. * * Written by Russ Allbery <eagle@eyrie.org> + * Copyright 2018 Russ Allbery <eagle@eyrie.org> * Copyright 2006-2007, 2009, 2011-2014 * The Board of Trustees of the Leland Stanford Junior University * @@ -41,6 +42,7 @@ #include <tests/tap/process.h> #include <tests/tap/remctl.h> #include <tests/tap/string.h> +#include <util/vector.h> /* May be defined by the build system. */ #ifndef PATH_REMCTLD @@ -66,6 +68,8 @@ remctld_start_internal(struct kerberos_config *krbconf, const char *config, { va_list args_copy; char *tmpdir, *pidfile, *confpath; + const char *valgrind; + struct vector *valgrind_args = NULL; size_t i, length; const char *arg, **argv; struct process *process; @@ -81,17 +85,28 @@ remctld_start_internal(struct kerberos_config *krbconf, const char *config, if (access(pidfile, F_OK) == 0) bail("remctld may already be running: %s exists", pidfile); + /* If valgrind testing is configured, get the options to valgrind. */ + length = 0; + valgrind = getenv("C_TAP_VALGRIND"); + if (valgrind != NULL) { + valgrind_args = vector_split_space(valgrind, NULL); + length += valgrind_args->count; + } + /* Build the argv used to run remctld. */ confpath = test_file_path(config); if (confpath == NULL) bail("cannot find remctld config %s", config); - length = 11; + length += 11; va_copy(args_copy, args); while ((arg = va_arg(args_copy, const char *)) != NULL) length++; va_end(args_copy); argv = bcalloc(length, sizeof(const char *)); i = 0; + if (valgrind_args != NULL) + for (i = 0; i < valgrind_args->count; i++) + argv[i] = valgrind_args->strings[i]; argv[i++] = path_remctld; argv[i++] = "-mdSF"; argv[i++] = "-p"; @@ -113,6 +128,7 @@ remctld_start_internal(struct kerberos_config *krbconf, const char *config, process = process_start(argv, pidfile); /* Clean up and return. */ + vector_free(valgrind_args); test_file_path_free(confpath); free(pidfile); test_tmpdir_free(tmpdir); diff --git a/tests/util/network/client-t.c b/tests/util/network/client-t.c index f7fdefb..a2ad7ea 100644 --- a/tests/util/network/client-t.c +++ b/tests/util/network/client-t.c @@ -5,7 +5,7 @@ * which can be found at <https://www.eyrie.org/~eagle/software/rra-c-util/>. * * Written by Russ Allbery <eagle@eyrie.org> - * Copyright 2005, 2013-2014, 2016-2017 Russ Allbery <eagle@eyrie.org> + * Copyright 2005, 2013-2014, 2016-2018 Russ Allbery <eagle@eyrie.org> * Copyright 2009-2013 * The Board of Trustees of the Leland Stanford Junior University * @@ -378,10 +378,6 @@ test_network_write(void) */ const size_t bufsize = 15 * 1024 * 1024; - /* Create the data that we're going to send. */ - buffer = bmalloc(bufsize); - memset(buffer, 'a', bufsize); - /* Create the listening socket. */ fd = network_bind_ipv4(SOCK_STREAM, "127.0.0.1", 11119); if (fd == INVALID_SOCKET) @@ -398,6 +394,10 @@ test_network_write(void) client_delay_reader("127.0.0.1"); } + /* Create the data that we're going to send. */ + buffer = bmalloc(bufsize); + memset(buffer, 'a', bufsize); + /* Set an alarm just in case our timeouts don't work. */ alarm(10); |