]> git.ozlabs.org Git - ccan/blobdiff - ccan/failtest/failtest.c
failtest: record close events
[ccan] / ccan / failtest / failtest.c
index ad7e0feac1ec00be4b161c545e3e5c497a8cd8f6..9ecc535a3fb73ac736f7474e88508c950fba1345 100644 (file)
@@ -56,7 +56,7 @@ static pid_t lock_owner;
 static struct lock_info *locks = NULL;
 static unsigned int lock_num = 0;
 
-static const char info_to_arg[] = "mceoprwf";
+static const char info_to_arg[] = "mceoxprwf";
 
 /* Dummy call used for failtest_undo wrappers. */
 static struct failtest_call unrecorded_call;
@@ -455,9 +455,13 @@ static bool should_fail(struct failtest_call *call)
        close(output[0]);
        close(control[0]);
        waitpid(child, &status, 0);
-       if (!WIFEXITED(status))
-               child_fail(out, outlen, "Killed by signal %u: ",
-                          WTERMSIG(status));
+       if (!WIFEXITED(status)) {
+               if (WTERMSIG(status) == SIGUSR1)
+                       child_fail(out, outlen, "Timed out");
+               else
+                       child_fail(out, outlen, "Killed by signal %u: ",
+                                  WTERMSIG(status));
+       }
        /* Child printed failure already, just pass up exit code. */
        if (type == FAILURE) {
                fprintf(stderr, "%.*s", (int)outlen, out);
@@ -821,9 +825,20 @@ add_lock(struct lock_info *locks, int fd, off_t start, off_t end, int type)
 }
 
 /* We trap this so we can record it: we don't fail it. */
-int failtest_close(int fd)
+int failtest_close(int fd, const char *file, unsigned line)
 {
        int i;
+       struct close_call call;
+       struct failtest_call *p;
+
+       call.fd = fd;
+       p = add_history(FAILTEST_CLOSE, file, line, &call);
+       p->fail = false;
+
+       /* Consume close from failpath. */
+       if (failpath)
+               if (should_fail(p))
+                       abort();
 
        if (fd < 0)
                return close(fd);
@@ -976,16 +991,16 @@ void failtest_exit(int status)
 {
        int i;
 
-       if (control_fd == -1) {
-               free_everything();
-               exit(status);
-       }
-
        if (failtest_exit_check) {
                if (!failtest_exit_check(history, history_num))
                        child_fail(NULL, 0, "failtest_exit_check failed\n");
        }
 
+       if (control_fd == -1) {
+               free_everything();
+               exit(status);
+       }
+
        /* Cleanup everything, in reverse order. */
        for (i = history_num - 1; i >= 0; i--)
                if (history[i].cleanup)