From b4c82732fbd3022e7bcbd374741c18ccd91fc204 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Axel=20D=C3=B6rfler?= Date: Tue, 19 Feb 2008 16:00:11 +0000 Subject: [PATCH] Added test program for our advisory locking implementation - looks like it has several issues, and a F_UNLCK semantic different from other OSs, causing bug #1791. git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@24017 a95241bf-73f2-0310-859d-f6bbb57e9c96 --- src/tests/system/kernel/Jamfile | 2 + .../system/kernel/advisory_locking_test.cpp | 139 ++++++++++++++++++ 2 files changed, 141 insertions(+) create mode 100644 src/tests/system/kernel/advisory_locking_test.cpp diff --git a/src/tests/system/kernel/Jamfile b/src/tests/system/kernel/Jamfile index d93c666c19..3f6b4342cd 100644 --- a/src/tests/system/kernel/Jamfile +++ b/src/tests/system/kernel/Jamfile @@ -3,6 +3,8 @@ SubDir HAIKU_TOP src tests system kernel ; UsePrivateHeaders kernel ; UseHeaders $(TARGET_PRIVATE_KERNEL_HEADERS) : true ; +SimpleTest advisory_locking_test : advisory_locking_test.cpp ; + SimpleTest cow_bug113_test : cow_bug113_test.cpp ; SimpleTest fibo_load_image : fibo_load_image.cpp ; diff --git a/src/tests/system/kernel/advisory_locking_test.cpp b/src/tests/system/kernel/advisory_locking_test.cpp new file mode 100644 index 0000000000..bea79922a5 --- /dev/null +++ b/src/tests/system/kernel/advisory_locking_test.cpp @@ -0,0 +1,139 @@ +/* + * Copyright 2008, Axel Dörfler, axeld@pinc-software.de. All rights reserved. + * Distributed under the terms of the MIT License. + */ + + +#include +#include +#include +#include +#include +#include + + +extern const char *__progname; + +const char* kTemporaryFile = "/tmp/axels-lock-test"; + + +const char* +type_name(int type) +{ + return type == F_RDLCK ? "shared" : type == F_WRLCK + ? "exclusive" : "remove"; +} + + +int +do_lock(int fd, int type, off_t start, off_t length) +{ + printf("%s lock %Ld:%Ld\n", type_name(type), start, length); + + struct flock flock; + flock.l_type = type; + flock.l_whence = SEEK_SET; + flock.l_start = start; + flock.l_len = length; + if (fcntl(fd, F_SETLK, &flock) != 0) { + fprintf(stderr, "ERROR: %s lock %Ld:%Ld failed: %s\n", type_name(type), + start, length, strerror(errno)); + return -1; + } + + return 0; +} + + +int +shared_lock(int fd, off_t start, off_t length) +{ + return do_lock(fd, F_RDLCK, start, length); +} + + +int +exclusive_lock(int fd, off_t start, off_t length) +{ + return do_lock(fd, F_WRLCK, start, length); +} + + +int +remove_lock(int fd, off_t start, off_t length) +{ + return do_lock(fd, F_UNLCK, start, length); +} + + +void +wait_for_enter() +{ + puts("wait for ..."); + char buffer[64]; + fgets(buffer, sizeof(buffer), stdin); +} + + +void +usage() +{ + fprintf(stderr, "usage: %s [shared|exclusive|unlock ] " + "[wait] [...]\n", __progname); + exit(1); +} + + +bool +is_command(const char* op, const char* command1, const char* command2) +{ + int length = strlen(op); + if (length == 0) + return false; + + return command1 != NULL && !strncmp(op, command1, length) + || command2 != NULL && !strncmp(op, command2, length); +} + + +int +main(int argc, char** argv) +{ + int fd = open(kTemporaryFile, O_CREAT | O_RDWR, 0644); + if (fd < 0) { + fprintf(stderr, "Could not create lock file: %s\n", strerror(errno)); + return 1; + } + + while (argc > 1) { + const char* op = argv[1]; + if (is_command(op, "wait", NULL)) { + wait_for_enter(); + argv++; + argc--; + continue; + } + if (argc < 3) + usage(); + + off_t start = strtoll(argv[2], NULL, 0); + off_t length = strtoll(argv[3], NULL, 0); + int type = 0; + if (is_command(op, "read", "shared")) + type = F_RDLCK; + else if (is_command(op, "write", "exclusive")) + type = F_WRLCK; + else if (is_command(op, "unlock", "remove")) + type = F_UNLCK; + else + usage(); + + do_lock(fd, type, start, length); + argc -= 3; + argv += 3; + } + + close(fd); + return 0; +} +