failtest: handle 2-argument open()
authorRusty Russell <rusty@rustcorp.com.au>
Tue, 15 Feb 2011 12:33:24 +0000 (23:03 +1030)
committerRusty Russell <rusty@rustcorp.com.au>
Tue, 15 Feb 2011 12:33:24 +0000 (23:03 +1030)
ccan/failtest/failtest.c
ccan/failtest/failtest_override.h
ccan/failtest/failtest_proto.h
ccan/failtest/failtest_undo.h
ccan/failtest/test/run-failpath.c
ccan/failtest/test/run-open.c [new file with mode: 0644]

index 2b78b8e3f8bdc655aaa9234ffa1335fe73c6ac8a..1118466ebc5d963bb78c8a218e73689a37c164bc 100644 (file)
@@ -418,17 +418,17 @@ void *failtest_realloc(void *ptr, size_t size, const char *file, unsigned line)
        return p->u.realloc.ret;
 }
 
-int failtest_open(const char *pathname, int flags,
+int failtest_open(const char *pathname,
                  const char *file, unsigned line, ...)
 {
        struct failtest_call *p;
        struct open_call call;
+       va_list ap;
 
        call.pathname = strdup(pathname);
-       call.flags = flags;
-       if (flags & O_CREAT) {
-               va_list ap;
-               va_start(ap, line);
+       va_start(ap, line);
+       call.flags = va_arg(ap, int);
+       if (call.flags & O_CREAT) {
                call.mode = va_arg(ap, mode_t);
                va_end(ap);
        }
@@ -441,7 +441,7 @@ int failtest_open(const char *pathname, int flags,
                /* FIXME: Play with error codes? */
                p->error = EACCES;
        } else {
-               p->u.open.ret = open(pathname, flags, call.mode);
+               p->u.open.ret = open(pathname, call.flags, call.mode);
        }
        errno = p->error;
        return p->u.open.ret;
index 90d1bfdc48a9f07064e323522b6687d25c24957e..3bd0f8fc2443d43a9459ac96529b6792687c0623 100644 (file)
@@ -24,8 +24,8 @@
 #include <unistd.h>
 
 #undef open
-#define open(pathname, flags, ...) \
-       failtest_open((pathname), (flags), __FILE__, __LINE__, __VA_ARGS__)
+#define open(pathname, ...) \
+       failtest_open((pathname), __FILE__, __LINE__, __VA_ARGS__)
 
 #undef pipe
 #define pipe(pipefd) \
index 66f28c9b32eada2e85855575d5884d88c59c4a39..4d316d441b08ded3cdd052d83b50bbf7148088ca 100644 (file)
@@ -8,7 +8,7 @@ void *failtest_calloc(size_t nmemb, size_t size,
 void *failtest_malloc(size_t size, const char *file, unsigned line);
 void *failtest_realloc(void *ptr, size_t size,
                       const char *file, unsigned line);
-int failtest_open(const char *pathname, int flags,
+int failtest_open(const char *pathname,
                  const char *file, unsigned line, ...);
 int failtest_pipe(int pipefd[2], const char *file, unsigned line);
 ssize_t failtest_read(int fd, void *buf, size_t count,
index 7f29acd5630284ff2fad04f7d488d60a0ee56cea..c44dba47ac9ae611612bc41389c7d8e74cc26929 100644 (file)
@@ -15,8 +15,8 @@
        failtest_realloc((ptr), (size), NULL, 0)
 
 #undef open
-#define open(pathname, flags, ...) \
-       failtest_open((pathname), (flags), NULL, 0, __VA_ARGS__)
+#define open(pathname, ...) \
+       failtest_open((pathname), NULL, 0, __VA_ARGS__)
 
 #undef pipe
 #define pipe(pipefd) \
index c5aca9ef88f6ceb97609855db820cfcf30106834..3c93c2ad988e3f1f12b5c590d53caac6b6eecdb9 100644 (file)
@@ -17,8 +17,8 @@ int main(void)
        ok1((p = failtest_malloc(10, "run-failpath.c", 1)) != NULL);
        ok1(failtest_calloc(10, 5, "run-failpath.c", 1) != NULL);
        ok1((p = failtest_realloc(p, 100, "run-failpath.c", 1)) != NULL);
-       ok1((fd = failtest_open("failpath-scratch", O_RDWR|O_CREAT,
-                               "run-failpath.c", 1, 0600)) >= 0);
+       ok1((fd = failtest_open("failpath-scratch", "run-failpath.c", 1,
+                               O_RDWR|O_CREAT, 0600)) >= 0);
        ok1(failtest_pipe(fds, "run-failpath.c", 1) == 0);
        ok1(failtest_write(fd, "xxxx", 4, "run-failpath.c", 1) == 4);
        lseek(fd, 0, SEEK_SET);
@@ -28,8 +28,8 @@ int main(void)
        ok1(failtest_malloc(10, "run-failpath.c", 1) == NULL);
        ok1(failtest_calloc(10, 5, "run-failpath.c", 1) == NULL);
        ok1(failtest_realloc(p, 100, "run-failpath.c", 1) == NULL);
-       ok1(failtest_open("failpath-scratch", O_RDWR|O_CREAT,
-                         "run-failpath.c", 1, 0600) == -1);
+       ok1(failtest_open("failpath-scratch", "run-failpath.c", 1,
+                         O_RDWR|O_CREAT, 0600) == -1);
        ok1(failtest_pipe(fds, "run-failpath.c", 1) == -1);
        ok1(failtest_write(fd, "xxxx", 4, "run-failpath.c", 1) == -1);
        lseek(fd, 0, SEEK_SET);
diff --git a/ccan/failtest/test/run-open.c b/ccan/failtest/test/run-open.c
new file mode 100644 (file)
index 0000000..dda7ddb
--- /dev/null
@@ -0,0 +1,67 @@
+#include <stdlib.h>
+#include <setjmp.h>
+#include <stdio.h>
+#include <stdarg.h>
+#include <assert.h>
+#include <ccan/tap/tap.h>
+/* Include the C files directly. */
+#include <ccan/failtest/failtest.c>
+
+int main(void)
+{
+       int fd, pfd[2], err;
+       char buf[] = "Hello world!";
+       struct stat st;
+
+       plan_tests(12);
+
+       pipe(pfd);
+       fd = failtest_open("run-open-scratchpad", "run-open.c", 1,
+                          O_RDWR|O_CREAT, 0600);
+       if (fd == -1) {
+               /* We are the child: write error code for parent to check. */
+               err = errno;
+               write(pfd[1], &err, sizeof(err));
+               failtest_exit(0);
+       }
+       /* Check it is read-write. */
+       ok1(write(fd, buf, strlen(buf)) == strlen(buf));
+       lseek(fd, SEEK_SET, 0);
+       ok1(read(fd, buf, strlen("Hello world!")) == strlen("Hello world!"));
+       ok1(strcmp(buf, "Hello world!") == 0);
+
+       /* Check name and perms. */
+       ok1(stat("run-open-scratchpad", &st) == 0);
+       ok1(st.st_size == strlen(buf));
+       ok1(S_ISREG(st.st_mode));
+       ok1((st.st_mode & 0777) == 0600);
+
+       /* Check child got correct errno. */
+       ok1(read(pfd[0], &err, sizeof(err)) == sizeof(err));
+       ok1(err == EACCES);
+
+       /* Clean up. */
+       close(fd);
+       close(pfd[0]);
+       close(pfd[1]);
+
+       /* Two-arg open. */
+       pipe(pfd);
+       fd = failtest_open("run-open-scratchpad", "run-open.c", 1, O_RDONLY);
+       if (fd == -1) {
+               /* We are the child: write error code for parent to check. */
+               err = errno;
+               write(pfd[1], &err, sizeof(err));
+               failtest_exit(0);
+       }
+       /* Check it is read-only. */
+       ok1(write(fd, buf, strlen(buf)) == -1);
+       ok1(read(fd, buf, strlen("Hello world!")) == strlen("Hello world!"));
+       ok1(strcmp(buf, "Hello world!") == 0);
+       /* Clean up. */
+       close(fd);
+       close(pfd[0]);
+       close(pfd[1]);
+
+       return exit_status();
+}