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);
}
/* 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;
#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) \
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,
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) \
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);
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);
--- /dev/null
+#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();
+}