From 3a8234d2440a464f5401b3444d454ac913d6b3d6 Mon Sep 17 00:00:00 2001 From: Neal H Walfield Date: Wed, 30 Oct 2019 00:03:13 +0100 Subject: libfshelp-tests: Tests for file record locking 2019-03-04 Svante Signell * test-*.c: Update code, remove test results. * README.new_tests: New file, summarize new test results. 2019-02-12 Svante Signell * test-*.c: Update code, add some test results. * Makefile: Remove extra flags. 2019-02-01 Svante Signell * Update copyright years. 2016-05-23 Svante Signell * Makefile: Add sub-directory libfshelp-tests. 2018-12-07 Svante Signell * Update copyright years. * locks.c(cmd_lock): Call fshelp_rlock_tweak() with new last argument rendezvous = MACH_PORT_NULL. 2017-01-05 Svante Signell * Update copyright years and headers. 2016-12-28 Svante Signell * Makefile: test-flock.c, test-lockf.c and test-fcntl.c * test-lockf.c: New file * Rename set-flock.c, set-fcntl.c to test-flock.c test-fcntl.c * TODO: Update README 2016-05-23 Svante Signell * Makefile: Link with pthread, add build of set-flock.c and set-fcntl.c * define temporary CPP_FLAGS until glibc is updated * set-flock.c, set-fcntl.c: New files. * Fix typos in README 2001-04-11 Neal H Walfield * ChangeLog: New file, mentioning itself in this sentence. * Makefile: New file. * README: Likewise. * fork.c: Likewise. * locks: Likewise. * locks-tests: Likewise. * locks.c: Likewise. * race.c: Likewise. --- libfshelp-tests/locks.c | 328 ++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 328 insertions(+) create mode 100644 libfshelp-tests/locks.c (limited to 'libfshelp-tests/locks.c') diff --git a/libfshelp-tests/locks.c b/libfshelp-tests/locks.c new file mode 100644 index 00000000..d9af78ae --- /dev/null +++ b/libfshelp-tests/locks.c @@ -0,0 +1,328 @@ +/* Test record locking. + + Copyright (C) 2001, 2018-2019 Free Software Foundation, Inc. + + Written by Neal H Walfield + + This program is free software; you can redistribute it and/or + modify it under the terms of the GNU General Public License as + published by the Free Software Foundation; either version 2, or (at + your option) any later version. + + This program is distributed in the hope that it will be useful, but + WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + General Public License for more details. + + You should have received a copy of the GNU General Public License + along with the GNU Hurd. If not, see . */ + +#include "../libfshelp/fshelp.h" +#include "../libfshelp/rlock.h" +#include +#include +#include +#include + +#include "fs_U.h" + +#ifndef PEROPENS +#define PEROPENS 10 +#endif + +struct rlock_box box; +struct rlock_peropen peropens[PEROPENS]; +loff_t pointers[PEROPENS]; +loff_t file_size; + +struct command +{ + char *name; + int (*func)(char *cmds); + char *doc; +}; + +error_t cmd_help (char *); +error_t cmd_comment (char *); +error_t cmd_echo (char *); +error_t cmd_lock (char *); +error_t cmd_list (char *); +error_t cmd_seek (char *); +error_t cmd_exec (char *); + +struct command commands [] = + { + { "help", cmd_help, "Print this screen" }, + { "#", cmd_comment, "Comment (Must _start_ the line)." }, + { "echo", cmd_echo, "Echo the line." }, + { "lock", cmd_lock, + "po start length type\n" + "\ttype = { F_UNLCK=0, F_RDLCK,=1, F_WRLCK=2 }" }, + { "list", cmd_list, "list all locks' status" }, + { "seek", cmd_seek, "PO1 ... Print the position of the given po.\n" + "\tPO1=N ... Seek a given po." }, + { "exec", cmd_exec, "Execute a built in echoing the command."} + }; + +error_t +cmd_help (char *args) +{ + int i; + printf ("Commands:\n"); + for (i = 0; i < sizeof (commands) / sizeof (struct command); i ++) + printf ("%s\t%s\n", commands[i].name, commands[i].doc); + return 0; +} + +error_t +cmd_comment (char *args) +{ + return 0; +} + +error_t +cmd_echo (char *args) +{ + printf ("%s", args); + return 0; +} + +error_t +cmd_lock (char *args) +{ + int po, type; + loff_t start, len; + struct flock64 lock; + mach_port_t rendezvous = MACH_PORT_NULL; + error_t err; + + if (4 != sscanf (args, "%d %ld %ld %d", &po, (long*)&start, (long*)&len, &type)) + { + printf ("Syntax error.\n"); + return 0; + } + + lock.l_type = type; + lock.l_whence = SEEK_CUR; + lock.l_start = (long)start; + lock.l_len = (long)len; + + if (po < 0 || po >= PEROPENS) + { + printf ("Unknown peropen: %d.\n", po); + return 0; + } + + switch (type) + { + case 0: lock.l_type = F_UNLCK; break; + case 1: lock.l_type = F_RDLCK; break; + case 2: lock.l_type = F_WRLCK; break; + default: printf ("Unknown type.\n"); return 0; + } + + err= fshelp_rlock_tweak (&box, NULL, &peropens[po], O_RDWR, + file_size, pointers[po], F_SETLK64, + &lock, rendezvous); + if (! err) + { + char buf[10]; + sprintf (buf, "%d\n", po); + cmd_list (buf); + } + return err; +} + +error_t +cmd_list (char *args) +{ + char *end; + + void dump (int i) + { + struct rlock_list *l; + + printf ("%3d:", i); + for (l = *peropens[i].locks; l; l = l->po.next) + { + printf ("\tStart = %4ld; Length = %4ld; Type = ", (long)l->start, (long)l->len); + switch (l->type) + { + case F_RDLCK: printf ("F_RDLCK"); break; + case F_WRLCK: printf ("F_WRLCK"); break; + case F_UNLCK: printf ("F_UNLCK"); break; + default: printf ("UNKNOWN"); break; + } + printf ("\n"); + } + + if (*peropens[i].locks == NULL) + printf ("\n"); + } + + while (*args == ' ') + args ++; + + if (*args == '\n' || *args == '\0') + { + int i; + + for (i = 0; i < PEROPENS; i ++) + dump (i); + return 0; + } + + while (1) + { + long int p = strtoll (args, &end, 0); + if (end == args) + { + printf ("Syntax error.\n"); + return 0; + } + + if (p < 0 || p > PEROPENS) + printf ("%3ld:\tOut of range.", p); + else + dump (p); + + while (*end == ' ') + end ++; + + if (*end == '\n' || *end == '\0') + return 0; + args = end; + } +} + +error_t +cmd_seek (char *args) +{ + char *end; + int p; + + while (*args == ' ') + args ++; + + if (*args == '\n' || *args == '\0') + { + int i; + for (i = 0; i < PEROPENS; i ++) + printf ("%3d: %ld\n", i, (long)pointers[i]); + return 0; + } + + while (1) + { + int set = 0; + long seek_to = 0; + + p = strtol (args, &end, 0); + if (end == args) + { + printf ("Syntax error.\n"); + return 0; + } + + if (*end == '=') + { + set = 1; + args = end + 1; + seek_to = strtol (args, &end, 0); + if (end == args) + { + printf ("Syntax error.\n"); + return 0; + } + } + + if (p < 0 || p > PEROPENS) + printf ("%3d: unknown peropen\n", p); + else + { + printf ("%3d: %ld", p, (long)pointers[p]); + if (set) + printf (" => %ld\n", (long)(pointers[p] = seek_to)); + else + printf ("\n"); + } + + while (*end == ' ') + end ++; + if (*end == '\0' || *end == '\n') + return 0; + args = end; + } +} + +error_t +interpret (char *buffer) +{ + int i; + + while (*buffer == ' ') + buffer ++; + + if (*buffer == '\n') + return 0; + + for (i = 0; i < sizeof (commands) / sizeof (struct command); i ++) + if (strncmp (commands[i].name, buffer, strlen (commands[i].name)) == 0) + { + error_t err; + err = commands[i].func (buffer + strlen (commands[i].name) + 1); + if (err) + printf ("%s\n", strerror (err)); + return err; + } + + printf ("Unknown command.\n"); + return 0; +} + +error_t +cmd_exec (char *arg) +{ + printf ("%s", arg); + interpret (arg); + return 0; +} + +int main (int argc, char *argv[]) +{ + int i; + + if (argc != 1) + { + printf ("Usage: %s\n" + "\tType `help' at the prompt.\n" + "\tUsed to test the record locking functions in libfshelp\n", + argv[0]); + return 1; + } + + fshelp_rlock_init (&box); + for (i = 0; i < PEROPENS; i ++) + fshelp_rlock_po_init (&peropens[i]); + + while (! feof (stdin)) + { + char b[1024]; + + printf ("> "); + fflush (stdout); + + if (! fgets (b, sizeof (b), stdin)) + { + if (feof (stdin)) + break; + else + continue; + } + + interpret (b); + } + + printf ("\n"); + return 0; +} -- cgit v1.2.3