Browse Source

failtest: handle 2-argument open()

Rusty Russell 15 years ago
parent
commit
f070b47bc6

+ 6 - 6
ccan/failtest/failtest.c

@@ -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;

+ 2 - 2
ccan/failtest/failtest_override.h

@@ -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) \

+ 1 - 1
ccan/failtest/failtest_proto.h

@@ -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,

+ 2 - 2
ccan/failtest/failtest_undo.h

@@ -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) \

+ 4 - 4
ccan/failtest/test/run-failpath.c

@@ -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);

+ 67 - 0
ccan/failtest/test/run-open.c

@@ -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();
+}