We trap them, might as well put them in history. This also makes tracking
open file descriptors more robust.
static struct lock_info *locks = NULL;
static unsigned int lock_num = 0;
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;
/* Dummy call used for failtest_undo wrappers. */
static struct failtest_call unrecorded_call;
}
/* We trap this so we can record it: we don't fail it. */
}
/* 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)
+ 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);
if (fd < 0)
return close(fd);
FAILTEST_CALLOC,
FAILTEST_REALLOC,
FAILTEST_OPEN,
FAILTEST_CALLOC,
FAILTEST_REALLOC,
FAILTEST_OPEN,
FAILTEST_PIPE,
FAILTEST_READ,
FAILTEST_WRITE,
FAILTEST_PIPE,
FAILTEST_READ,
FAILTEST_WRITE,
+struct close_call {
+ int fd;
+};
+
struct pipe_call {
int ret;
int fds[2];
struct pipe_call {
int ret;
int fds[2];
struct malloc_call malloc;
struct realloc_call realloc;
struct open_call open;
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;
struct pipe_call pipe;
struct read_call read;
struct write_call write;
failtest_pwrite((fd), (buf), (count), (off), __FILE__, __LINE__)
#undef close
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__)
#undef fcntl
#define fcntl(fd, ...) failtest_fcntl((fd), __FILE__, __LINE__, __VA_ARGS__)
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);
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 */
int failtest_fcntl(int fd, const char *file, unsigned line, int cmd, ...);
#endif /* CCAN_FAILTEST_PROTO_H */
ok1(err == EACCES);
/* Clean up. */
ok1(err == EACCES);
/* Clean up. */
+ failtest_close(fd, "run-open.c", 1);
close(pfd[0]);
close(pfd[1]);
close(pfd[0]);
close(pfd[1]);
ok1(read(fd, buf, strlen("Hello world!")) == strlen("Hello world!"));
ok1(strcmp(buf, "Hello world!") == 0);
/* Clean up. */
ok1(read(fd, buf, strlen("Hello world!")) == strlen("Hello world!"));
ok1(strcmp(buf, "Hello world!") == 0);
/* Clean up. */
+ failtest_close(fd, "run-open.c", 1);
close(pfd[0]);
close(pfd[1]);
close(pfd[0]);
close(pfd[1]);