From c96ab569e73791eabe62e8d1c88b913e89eddc49 Mon Sep 17 00:00:00 2001 From: Rusty Russell Date: Tue, 15 Feb 2011 23:29:13 +1030 Subject: [PATCH] failtest: record close events We trap them, might as well put them in history. This also makes tracking open file descriptors more robust. --- ccan/failtest/failtest.c | 15 +++++++++++++-- ccan/failtest/failtest.h | 6 ++++++ ccan/failtest/failtest_override.h | 2 +- ccan/failtest/failtest_proto.h | 2 +- ccan/failtest/test/run-open.c | 4 ++-- 5 files changed, 23 insertions(+), 6 deletions(-) diff --git a/ccan/failtest/failtest.c b/ccan/failtest/failtest.c index ccc89b22..9ecc535a 100644 --- a/ccan/failtest/failtest.c +++ b/ccan/failtest/failtest.c @@ -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); diff --git a/ccan/failtest/failtest.h b/ccan/failtest/failtest.h index 473f9e79..ec238af0 100644 --- a/ccan/failtest/failtest.h +++ b/ccan/failtest/failtest.h @@ -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; diff --git a/ccan/failtest/failtest_override.h b/ccan/failtest/failtest_override.h index d5be2829..a97d4e17 100644 --- a/ccan/failtest/failtest_override.h +++ b/ccan/failtest/failtest_override.h @@ -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__) diff --git a/ccan/failtest/failtest_proto.h b/ccan/failtest/failtest_proto.h index 58337301..89a1e77f 100644 --- a/ccan/failtest/failtest_proto.h +++ b/ccan/failtest/failtest_proto.h @@ -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 */ diff --git a/ccan/failtest/test/run-open.c b/ccan/failtest/test/run-open.c index 3ac93aeb..a81fa259 100644 --- a/ccan/failtest/test/run-open.c +++ b/ccan/failtest/test/run-open.c @@ -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]); -- 2.39.2