failtest: record close events
authorRusty Russell <rusty@rustcorp.com.au>
Tue, 15 Feb 2011 12:59:13 +0000 (23:29 +1030)
committerRusty Russell <rusty@rustcorp.com.au>
Tue, 15 Feb 2011 12:59:13 +0000 (23:29 +1030)
We trap them, might as well put them in history.  This also makes tracking
open file descriptors more robust.

ccan/failtest/failtest.c
ccan/failtest/failtest.h
ccan/failtest/failtest_override.h
ccan/failtest/failtest_proto.h
ccan/failtest/test/run-open.c

index ccc89b22f344bbdde2b193f6c33cb91c26f75692..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;
@@ -825,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);
index 473f9e7950fa498e5d56a613353b049e69c82084..ec238af0ab6f7d195de07df7e597c45c54a61145 100644 (file)
@@ -36,6 +36,7 @@ enum failtest_call_type {
        FAILTEST_CALLOC,
        FAILTEST_REALLOC,
        FAILTEST_OPEN,
+       FAILTEST_CLOSE,
        FAILTEST_PIPE,
        FAILTEST_READ,
        FAILTEST_WRITE,
@@ -66,6 +67,10 @@ struct open_call {
        mode_t mode;
 };
 
+struct close_call {
+       int fd;
+};
+
 struct pipe_call {
        int ret;
        int fds[2];
@@ -130,6 +135,7 @@ struct failtest_call {
                struct malloc_call malloc;
                struct realloc_call realloc;
                struct open_call open;
+               struct close_call close;
                struct pipe_call pipe;
                struct read_call read;
                struct write_call write;
index d5be2829d5e0dd418ae35eb4dd7b2f26543cccf7..a97d4e1723654fc5c5efa8e3b15491446a3e1c7e 100644 (file)
@@ -52,7 +52,7 @@
        failtest_pwrite((fd), (buf), (count), (off), __FILE__, __LINE__)
 
 #undef close
-#define close(fd) failtest_close(fd)
+#define close(fd) failtest_close(fd, __FILE__, __LINE__)
 
 #undef fcntl
 #define fcntl(fd, ...) failtest_fcntl((fd), __FILE__, __LINE__, __VA_ARGS__)
index 58337301ee223858ba903210ef586cd4c505c832..89a1e77f6e2fd9e024d3ff1831d4bf898ecca847 100644 (file)
@@ -20,6 +20,6 @@ ssize_t failtest_pread(int fd, void *buf, size_t count, off_t offset,
                       const char *file, unsigned line);
 ssize_t failtest_pwrite(int fd, const void *buf, size_t count, off_t offset,
                        const char *file, unsigned line);
-int failtest_close(int fd);
+int failtest_close(int fd, const char *file, unsigned line);
 int failtest_fcntl(int fd, const char *file, unsigned line, int cmd, ...);
 #endif /* CCAN_FAILTEST_PROTO_H */
index 3ac93aebb12af7ebec51fedc0e388c8773bcac40..a81fa259334c70298c0c2ac0ed320e23d556ca72 100644 (file)
@@ -41,7 +41,7 @@ int main(void)
        ok1(err == EACCES);
 
        /* Clean up. */
-       failtest_close(fd);
+       failtest_close(fd, "run-open.c", 1);
        close(pfd[0]);
        close(pfd[1]);
 
@@ -59,7 +59,7 @@ int main(void)
        ok1(read(fd, buf, strlen("Hello world!")) == strlen("Hello world!"));
        ok1(strcmp(buf, "Hello world!") == 0);
        /* Clean up. */
-       failtest_close(fd);
+       failtest_close(fd, "run-open.c", 1);
        close(pfd[0]);
        close(pfd[1]);