diff options
Diffstat (limited to 'tests')
-rw-r--r-- | tests/Makefile.am | 6 | ||||
-rwxr-xr-x | tests/test_bindfs.rb | 12 | ||||
-rw-r--r-- | tests/test_dir_rewind.c | 80 |
3 files changed, 97 insertions, 1 deletions
diff --git a/tests/Makefile.am b/tests/Makefile.am index 66713e2..0a52108 100644 --- a/tests/Makefile.am +++ b/tests/Makefile.am @@ -1,10 +1,14 @@ UNAME_S := $(shell uname -s) -noinst_PROGRAMS = readdir_inode utimens_nofollow fcntl_locker +AM_CPPFLAGS = ${my_CPPFLAGS} +AM_CFLAGS = ${my_CFLAGS} + +noinst_PROGRAMS = readdir_inode utimens_nofollow fcntl_locker test_dir_rewind readdir_inode_SOURCES = readdir_inode.c utimens_nofollow_SOURCES = utimens_nofollow.c fcntl_locker_SOURCES = fcntl_locker.c +test_dir_rewind_SOURCES = test_dir_rewind.c TESTS = test_bindfs.rb SUBDIRS = internals diff --git a/tests/test_bindfs.rb b/tests/test_bindfs.rb index c0ae5dd..e355e2a 100755 --- a/tests/test_bindfs.rb +++ b/tests/test_bindfs.rb @@ -678,6 +678,18 @@ root_testenv("", :title => "ioctl not enabled by default") do assert { `chattr +a mnt/file 2>&1`; !$?.success? } end +# Issue #41 +testenv("", :title => "reading directory with rewind") do + touch('mnt/file1') + touch('mnt/file2') + mkdir('mnt/subdir') + + Dir.chdir 'mnt' do + system("#{$tests_dir}/test_dir_rewind") + assert { $?.success? } + end +end + # FIXME: this stuff around testenv is a hax, and testenv may also exit(), which defeats the 'ensure' below. # the test setup ought to be refactored. It might well use MiniTest or something. if Process.uid == 0 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__ |