-#include "config.h"
+/* Licensed under LGPL - see LICENSE file for details */
+#include <ccan/failtest/failtest.h>
#include <stdarg.h>
#include <string.h>
#include <stdio.h>
#include <sys/time.h>
#include <signal.h>
#include <assert.h>
+#include <ccan/time/time.h>
#include <ccan/read_write_all/read_write_all.h>
#include <ccan/failtest/failtest_proto.h>
-#include <ccan/failtest/failtest.h>
#include <ccan/build_assert/build_assert.h>
enum failtest_result (*failtest_hook)(struct failtest_call *, unsigned);
}
}
+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)
{
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)
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();
}
if (child == 0) {
if (tracefd != -1) {
- struct timeval now;
+ struct timeval diff;
const char *p;
- gettimeofday(&now, NULL);
- if (now.tv_usec < start.tv_usec) {
- now.tv_sec--;
- now.tv_usec += 1000000;
- }
- now.tv_usec -= start.tv_usec;
- now.tv_sec -= start.tv_sec;
+
+ diff = time_sub(time_now(), start);
p = failpath_string();
trace("%u->%u (%u.%02u): %s (", getppid(), getpid(),
- (int)now.tv_sec, (int)now.tv_usec / 10000, p);
+ (int)diff.tv_sec, (int)diff.tv_usec / 10000, p);
free((char *)p);
p = strrchr(history[history_num-1].file, '/');
if (p)
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;
}
free((char *)call.pathname);
p->u.open.ret = open(pathname, call.flags, call.mode);
- if (!failpath && p->u.open.ret == -1) {
+ if (p->u.open.ret == -1) {
p->fail = false;
p->error = errno;
} else if (should_fail(p)) {
debugpath = argv[i] + strlen("--debugpath=");
}
}
- gettimeofday(&start, NULL);
+ start = time_now();
}
bool failtest_has_failed(void)