X-Git-Url: https://git.ozlabs.org/?p=ccan;a=blobdiff_plain;f=ccan%2Ffailtest%2Ffailtest.c;h=224898f9cb75ad8ad782c0dc983ade12c544cc06;hp=e9f837364a84b55ed9853a287ab69884b5f92c0a;hb=0a379f773681c7b3e53866b9a6e9cd0006012c1a;hpb=371a31d946c1055e8b7f7d9cec2b7f617206aeaf diff --git a/ccan/failtest/failtest.c b/ccan/failtest/failtest.c index e9f83736..224898f9 100644 --- a/ccan/failtest/failtest.c +++ b/ccan/failtest/failtest.c @@ -1,4 +1,5 @@ -#include "config.h" +/* Licensed under LGPL - see LICENSE file for details */ +#include #include #include #include @@ -16,7 +17,6 @@ #include #include #include -#include #include enum failtest_result (*failtest_hook)(struct failtest_call *, unsigned); @@ -309,6 +309,16 @@ static void restore_files(struct saved_file *s) } } +static void free_files(struct saved_file *s) +{ + while (s) { + struct saved_file *next = s->next; + free(s->contents); + free(s); + s = next; + } +} + /* Free up memory, so valgrind doesn't report leaks. */ static void free_everything(void) { @@ -361,7 +371,7 @@ static bool should_fail(struct failtest_call *call) struct saved_file *files; /* Are we probing? */ - if (probe_count && --probe_count == 0) + if (probe_count && --probe_count == 0 && control_fd != -1) failtest_cleanup(true, 0); if (call == &unrecorded_call) @@ -411,17 +421,22 @@ static bool should_fail(struct failtest_call *call) switch (failtest_hook(history, history_num)) { case FAIL_OK: break; + case FAIL_PROBE: + /* Already down probe path? Stop now. */ + if (!probe_count) { + /* FIXME: We should run *parent* and + * run probe until calls match up again. */ + probe_count = 3; + break; + } else { + /* Child should give up now. */ + if (control_fd != -1) + failtest_cleanup(true, 0); + /* Parent, don't fail again. */ + } case FAIL_DONT_FAIL: call->fail = false; return false; - case FAIL_PROBE: - /* Already down probe path? Stop now. */ - if (probe_count) - failtest_cleanup(true, 0); - /* FIXME: We should run *parent* and run probe until - * calls match up again. */ - probe_count = 3; - break; default: abort(); } @@ -469,6 +484,8 @@ static bool should_fail(struct failtest_call *call) if (output[1] != STDOUT_FILENO && output[1] != STDERR_FILENO) close(output[1]); control_fd = control[1]; + /* Valgrind spots the leak if we don't free these. */ + free_files(files); return true; } @@ -1053,6 +1070,11 @@ void failtest_init(int argc, char *argv[]) gettimeofday(&start, NULL); } +bool failtest_has_failed(void) +{ + return control_fd != -1; +} + void failtest_exit(int status) { if (failtest_exit_check) {