diff options
Diffstat (limited to 'tests/test_dir_rewind.c')
-rw-r--r-- | tests/test_dir_rewind.c | 80 |
1 files changed, 80 insertions, 0 deletions
diff --git a/tests/test_dir_rewind.c b/tests/test_dir_rewind.c new file mode 100644 index 0000000..d4050f9 --- /dev/null +++ b/tests/test_dir_rewind.c @@ -0,0 +1,80 @@ +// Tests that opening the current directory, reading its entries +// rewinding and reading its entries again gives the same entries both times. +// +// https://github.com/mpartel/bindfs/issues/41 + +#ifdef __linux__ + +#define _GNU_SOURCE +#include <fcntl.h> +#include <stdio.h> +#include <stdlib.h> +#include <string.h> +#include <sys/stat.h> +#include <sys/types.h> +#include <sys/syscall.h> +#include <unistd.h> + +#define BUF_SIZE 4096 + +int main() +{ + int fd = open(".", O_RDONLY | O_DIRECTORY); + if (fd == -1) { + perror("failed to open '.'"); + return 1; + } + + char buf1[BUF_SIZE]; + char buf2[BUF_SIZE]; + memset(buf1, 0, BUF_SIZE); + memset(buf2, 0, BUF_SIZE); + + int amt_read1 = syscall(SYS_getdents, fd, buf1, BUF_SIZE); + if (amt_read1 <= 0) { + fprintf(stderr, "amt_read1=%d\n", amt_read1); + close(fd); + return 1; + } + + off_t seek_res = lseek(fd, 0, SEEK_SET); + if (seek_res == (off_t)-1) { + perror("failed to lseek to 0"); + close(fd); + return 1; + } + + int amt_read2 = syscall(SYS_getdents, fd, buf2, BUF_SIZE); + if (amt_read2 <= 0) { + fprintf(stderr, "amt_read2=%d\n", amt_read2); + close(fd); + return 1; + } + + if (amt_read1 != amt_read2) { + fprintf(stderr, + "First read gave %d bytes, second read gave %d bytes.\n", + amt_read1, amt_read2); + close(fd); + return 1; + } + if (memcmp(buf1, buf2, BUF_SIZE) != 0) { + fprintf(stderr, "First and second read results differ.\n"); + close(fd); + return 1; + } + + close(fd); + return 0; +} + +#else // #ifdef __linux__ + +int main() +{ + printf("This test (probably) only compiles on Linux.\n"); + printf("Skipping by just returning successfully.\n"); + return 0; +} + +#endif // #ifdef __linux__ |