aboutsummaryrefslogtreecommitdiffstats
path: root/tests
diff options
context:
space:
mode:
Diffstat (limited to 'tests')
-rw-r--r--tests/Makefile.am6
-rwxr-xr-xtests/test_bindfs.rb12
-rw-r--r--tests/test_dir_rewind.c80
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__