X-Git-Url: https://git.ozlabs.org/?p=ccan;a=blobdiff_plain;f=ccan%2Ffailtest%2Ffailtest.c;h=5d7a54f187f1f627ed6c950e9c7f06dfef82b1e1;hp=092d2091b137bf3ea8b4e193931c1b239019c7ad;hb=020f8ef45a751b9fc9f3739e8e8f8f9ddae69be8;hpb=f0002cb9e4f6f403a25ad50252c06694439900f0 diff --git a/ccan/failtest/failtest.c b/ccan/failtest/failtest.c index 092d2091..5d7a54f1 100644 --- a/ccan/failtest/failtest.c +++ b/ccan/failtest/failtest.c @@ -66,12 +66,19 @@ static unsigned int fd_orig_num = 0; static const char info_to_arg[] = "mceoprw"; +/* Dummy call used for failtest_undo wrappers. */ +static struct failtest_call unrecorded_call; + static struct failtest_call *add_history_(enum failtest_call_type type, const char *file, unsigned int line, const void *elem, size_t elem_size) { + /* NULL file is how we suppress failure. */ + if (!file) + return &unrecorded_call; + history = realloc(history, (history_num + 1) * sizeof(*history)); history[history_num].type = type; history[history_num].file = file; @@ -172,6 +179,9 @@ static bool should_fail(struct failtest_call *call) char *out = NULL; size_t outlen = 0; + if (call == &unrecorded_call) + return false; + if (failpath) { if (tolower(*failpath) != info_to_arg[call->type]) errx(1, "Failpath expected '%c' got '%c'\n", @@ -341,6 +351,9 @@ int failtest_open(const char *pathname, int flags, va_end(ap); } p = add_history(FAILTEST_OPEN, file, line, &call); + /* Avoid memory leak! */ + if (p == &unrecorded_call) + free((char *)call.pathname); if (should_fail(p)) { p->u.open.ret = -1; /* FIXME: Play with error codes? */ @@ -509,12 +522,33 @@ void failtest_init(int argc, char *argv[]) } } +/* Free up memory, so valgrind doesn't report leaks. */ +static void free_everything(void) +{ + unsigned int i; + + for (i = 0; i < writes_num; i++) { + free(writes[i].data); + if (writes[i].hdr.offset != (off_t)-1) + free(writes[i].olddata); + } + free(writes); + free(fd_orig); + for (i = 0; i < history_num; i++) { + if (history[i].type == FAILTEST_OPEN) + free((char *)history[i].u.open.pathname); + } + free(history); +} + void failtest_exit(int status) { unsigned int i; - if (control_fd == -1) + if (control_fd == -1) { + free_everything(); exit(status); + } if (failtest_exit_check) { if (!failtest_exit_check(history, history_num)) @@ -542,6 +576,7 @@ void failtest_exit(int status) close(fd_orig[i].fd); } + free_everything(); tell_parent(SUCCESS); exit(0); }