aboutsummaryrefslogtreecommitdiffstats
path: root/tests/fcntl_locker.c
diff options
context:
space:
mode:
authorMartin Pärtel <martin.partel@gmail.com>2016-07-31 19:39:11 +0100
committerMartin Pärtel <martin.partel@gmail.com>2016-07-31 19:39:11 +0100
commitbc7e55aee064c06709dcc3cb329158cb6b75f935 (patch)
tree9b9d05f13f3e39714909014d666a6f8833176037 /tests/fcntl_locker.c
parente8a36fedff1e2836716a2345bd5c6b3565e990a1 (diff)
downloadbindfs-bc7e55aee064c06709dcc3cb329158cb6b75f935.tar.gz
Implemented --enable-lock-forwarding.
This should address #36.
Diffstat (limited to 'tests/fcntl_locker.c')
-rw-r--r--tests/fcntl_locker.c67
1 files changed, 67 insertions, 0 deletions
diff --git a/tests/fcntl_locker.c b/tests/fcntl_locker.c
new file mode 100644
index 0000000..fa2e9dc
--- /dev/null
+++ b/tests/fcntl_locker.c
@@ -0,0 +1,67 @@
+// Takes two files and exits with 0 if fcntl-locking one fcntl-locks the other.
+// If the files don't fcntl-lock each other, returns 1.
+// If any other error occurs, returns 2.
+
+#include <stdio.h>
+#include <string.h>
+#include <errno.h>
+#include <unistd.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <fcntl.h>
+
+int main(int argc, const char* argv[]) {
+ if (argc != 3) {
+ fprintf(stderr, "expecting exactly two arguments\n");
+ return 2;
+ }
+
+ int fd1 = -1;
+ int fd2 = -1;
+ int result = 2;
+
+ fd1 = open(argv[1], O_RDWR);
+ if (fd1 == -1) {
+ perror("failed to open the first file");
+ goto exit;
+ }
+ fd2 = open(argv[2], O_RDWR);
+ if (fd2 == -1) {
+ perror("failed to open the second file");
+ goto exit;
+ }
+
+ struct flock lock;
+ memset(&lock, 0, sizeof(lock));
+ lock.l_type = F_WRLCK;
+ lock.l_whence = SEEK_SET;
+ lock.l_start = 0;
+ lock.l_len = 0;
+ if (fcntl(fd1, F_SETLK, &lock) == -1) {
+ perror("fcntl F_SETLK on the first file failed");
+ goto exit;
+ }
+
+ memset(&lock, 0, sizeof(lock));
+ lock.l_type = F_WRLCK;
+ lock.l_whence = SEEK_SET;
+ lock.l_start = 0;
+ lock.l_len = 0;
+ if (fcntl(fd2, F_SETLK, &lock) == -1) {
+ if (errno == EACCES || errno == EAGAIN) {
+ result = 0;
+ goto exit;
+ } else {
+ perror("fcntl F_SETLK on the second file failed");
+ goto exit;
+ }
+ } else {
+ result = 1;
+ goto exit;
+ }
+
+exit:
+ close(fd1);
+ close(fd2);
+ return result;
+}