diff --git a/src/tests/kernel/libroot/posix/Jamfile b/src/tests/kernel/libroot/posix/Jamfile index 48c8dcd091..717d23a5c1 100644 --- a/src/tests/kernel/libroot/posix/Jamfile +++ b/src/tests/kernel/libroot/posix/Jamfile @@ -4,6 +4,12 @@ UsePrivateHeaders syslog_daemon ; SimpleTest SyslogTest : SyslogTest.cpp syslog.cpp + : libroot.so + ; + +SimpleTest flock_test + : flock_test.cpp + : libroot.so ; # Tell Jam where to find these sources diff --git a/src/tests/kernel/libroot/posix/flock_test.cpp b/src/tests/kernel/libroot/posix/flock_test.cpp new file mode 100644 index 0000000000..e5d71ce021 --- /dev/null +++ b/src/tests/kernel/libroot/posix/flock_test.cpp @@ -0,0 +1,169 @@ +/* + * Copyright 2005, Axel Dörfler, axeld@pinc-software.de. + * Distributed under the terms of the MIT License. + */ + + +#include + +#include +#include +#include +#include +#include + + +bool gDone = false; + + +static int32 +try_to_lock(void *_fd) +{ + int fd = (int)_fd; + + struct flock flock = { + F_RDLCK, // shared lock + SEEK_SET, + 200, + 0, // until the end of the file + 0 + }; + + if (fcntl(fd, F_SETLK, &flock) == 0) { + fprintf(stderr, "a. Could lock file!\n"); + return -1; + } else + puts("test a passed."); + + gDone = true; + + // wait for lock to become free + + if (fcntl(fd, F_SETLKW, &flock) == -1) { + fprintf(stderr, "b. Could not lock file: %s\n", strerror(errno)); + return -1; + } else + puts("test b passed."); + + flock.l_type = F_UNLCK; + + if (fcntl(fd, F_SETLK, &flock) == -1) { + fprintf(stderr, "c. Could not unlock file: %s\n", strerror(errno)); + return -1; + } else + puts("test c passed."); + + return 0; +} + + +int +main(int argc, char **argv) +{ + int fd = open("/bin/sh", O_RDONLY); + if (fd < 0) { + fprintf(stderr, "could not open file: %s\n", strerror(errno)); + return -1; + } + + struct flock flock = { + F_WRLCK, // exclusive lock + SEEK_SET, // lock whole file + 0, + 0, + 0 + }; + + if (fcntl(fd, F_SETLK, &flock) == 0) { + fprintf(stderr, "0. Could lock file exclusively without write access!\n"); + return -1; + } else + puts("test 0 passed."); + + flock.l_type = F_RDLCK; + // shared locks should be allowed + + if (fcntl(fd, F_SETLK, &flock) == -1) { + fprintf(stderr, "1. Could not lock file: %s\n", strerror(errno)); + return -1; + } else + puts("test 1 passed."); + + close(fd); + + fd = open("/bin/sh", O_RDWR); + if (fd < 0) { + fprintf(stderr, "could not open file: %s\n", strerror(errno)); + return -1; + } + + flock.l_type = F_WRLCK; + flock.l_start = 100; + flock.l_len = 42; + + if (fcntl(fd, F_SETLK, &flock) == -1) { + fprintf(stderr, "2. Could not lock file: %s\n", strerror(errno)); + return -1; + } else + puts("test 2 passed."); + + flock.l_start = 200; + + if (fcntl(fd, F_SETLK, &flock) == -1) { + fprintf(stderr, "3. Could not lock file: %s\n", strerror(errno)); + return -1; + } else + puts("test 3 passed."); + + flock.l_start = 80; + + if (fcntl(fd, F_SETLK, &flock) == 0) { + fprintf(stderr, "4. Could lock file exclusively on locked region!\n"); + return -1; + } else + puts("test 4 passed."); + + flock.l_type = F_UNLCK; + flock.l_start = 100; + + if (fcntl(fd, F_SETLK, &flock) == -1) { + fprintf(stderr, "5. Could not unlock file: %s\n", strerror(errno)); + return -1; + } else + puts("test 5 passed."); + + flock.l_type = F_WRLCK; + flock.l_start = 80; + + if (fcntl(fd, F_SETLK, &flock) == -1) { + fprintf(stderr, "6. Could not lock file: %s\n", strerror(errno)); + return -1; + } else + puts("test 6 passed."); + + thread_id thread = spawn_thread(try_to_lock, "try", B_NORMAL_PRIORITY, (void *)fd); + if (thread < B_OK) { + fprintf(stderr, "Could not spawn thread: %s\n", strerror(thread)); + return -1; + } + resume_thread(thread); + + while (!gDone) { + snooze(100000); // 0.1s + } + + flock.l_type = F_UNLCK; + flock.l_start = 200; + + if (fcntl(fd, F_SETLK, &flock) == -1) { + fprintf(stderr, "7. Could not unlock file: %s\n", strerror(errno)); + return -1; + } else + puts("test 7 passed."); + + status_t returnCode; + wait_for_thread(thread, &returnCode); + + close(fd); + return 0; +}