diff options
author | anton <anton@cvs.openbsd.org> | 2018-11-06 18:11:12 +0000 |
---|---|---|
committer | anton <anton@cvs.openbsd.org> | 2018-11-06 18:11:12 +0000 |
commit | 09ae7e8bf32aa590fdf4641e0edf56a003af99f4 (patch) | |
tree | 1ee8e70bfe4ae2e0b04a3baed211cc75f871f5cf /regress/sys | |
parent | 719529dd297fd5ece95adb4d1fd2d0e33a4b03ab (diff) |
add lockf(3) tests
Diffstat (limited to 'regress/sys')
-rw-r--r-- | regress/sys/kern/flock/Makefile | 26 | ||||
-rw-r--r-- | regress/sys/kern/flock/flock.c | 99 | ||||
-rw-r--r-- | regress/sys/kern/flock/lockf.c | 144 | ||||
-rw-r--r-- | regress/sys/kern/flock/util.c | 104 | ||||
-rw-r--r-- | regress/sys/kern/flock/util.h | 43 |
5 files changed, 314 insertions, 102 deletions
diff --git a/regress/sys/kern/flock/Makefile b/regress/sys/kern/flock/Makefile index e050f532b58..900cf0426b5 100644 --- a/regress/sys/kern/flock/Makefile +++ b/regress/sys/kern/flock/Makefile @@ -1,18 +1,28 @@ -# $OpenBSD: Makefile,v 1.6 2018/11/03 09:21:25 anton Exp $ +# $OpenBSD: Makefile,v 1.7 2018/11/06 18:11:11 anton Exp $ -PROG= flock +PROGS+= flock +SRCS_flock= flock.c util.c + +PROGS+= lockf +SRCS_lockf= lockf.c util.c WARNINGS= yes -TESTS!=jot 22 1 +TESTS_FLOCK!= jot 22 1 +.for t in ${TESTS_FLOCK} +flock-$t: flock + ./flock ${LOCKFLAGS} $t +REGRESS_TARGETS+=flock-$t +.endfor # XXX known failures (talk to art) -REGRESS_SKIP_TARGETS = t-5 t-6 +REGRESS_SKIP_TARGETS= flock-5 flock-6 -.for a in ${TESTS} -t-${a}: flock - ./flock ${a} -REGRESS_TARGETS+=t-${a} +TESTS_LOCKF!= jot 2 1 +.for t in ${TESTS_LOCKF} +lockf-$t: lockf + ./lockf ${LOCKFLAGS} $t +REGRESS_TARGETS+=lockf-$t .endfor .include <bsd.regress.mk> diff --git a/regress/sys/kern/flock/flock.c b/regress/sys/kern/flock/flock.c index 7cdb185e92b..257f9932107 100644 --- a/regress/sys/kern/flock/flock.c +++ b/regress/sys/kern/flock/flock.c @@ -29,67 +29,19 @@ #include <sys/time.h> #include <sys/stat.h> -#include <sys/wait.h> #include <err.h> #include <errno.h> #include <fcntl.h> -#include <limits.h> -#include <paths.h> #include <signal.h> #include <stdio.h> #include <stdlib.h> #include <string.h> #include <unistd.h> -static int verbose; +#include "util.h" -static const char * -tmpdir(void) -{ - static char path[PATH_MAX]; - const char *p; - size_t len; - int n; - int nosuffix = 1; - - p = getenv("TMPDIR"); - if (p == NULL || *p == '\0') - p = _PATH_TMP; - len = strlen(p); - if (len == 0) - errx(1, "%s: empty path", __func__); - if (p[len - 1] == '/') - nosuffix = 0; - n = snprintf(path, sizeof(path), "%s%s", p, nosuffix ? "/" : ""); - if (n == -1 || n >= (int)sizeof(path)) - errc(1, ENAMETOOLONG, "%s", __func__); - - return (path); -} - -static int -make_file(off_t sz) -{ - char template[PATH_MAX]; - const char *dir; - int fd, n; - - dir = tmpdir(); - n = snprintf(template, sizeof(template), "%sflock.XXXXXX", dir); - if (n == -1 || n >= (int)sizeof(template)) - errc(1, ENAMETOOLONG, "%s", __func__); - - fd = mkstemp(template); - if (fd == -1) - err(1, "mkstemp"); - if (ftruncate(fd, sz) == -1) - err(1, "ftruncate"); - if (unlink(template) == -1) - err(1, "unlink"); - - return (fd); -} +int verbose = 0; static void ignore_alarm(int __unused sig) @@ -97,24 +49,6 @@ ignore_alarm(int __unused sig) } static int -safe_waitpid(pid_t pid) -{ - int save_errno; - int status; - - save_errno = errno; - errno = 0; - while (waitpid(pid, &status, 0) != pid) { - if (errno == EINTR) - continue; - err(1, "waitpid"); - } - errno = save_errno; - - return (status); -} - -static int safe_kill(pid_t pid, int sig) { int save_errno; @@ -128,18 +62,6 @@ safe_kill(pid_t pid, int sig) return (status); } -#define FAIL(test) \ - do { \ - if (test) { \ - if (verbose) printf("%s: %d: FAIL (%s)\n", \ - __func__, __LINE__, #test); \ - return -1; \ - } \ - } while (0) - -#define SUCCEED \ - do { if (verbose) printf("SUCCEED\n"); return 0; } while (0) - /* * Test 1 - F_GETLK on unlocked region * @@ -1732,19 +1654,7 @@ test22(int fd) SUCCEED; } -static __dead void -usage(void) -{ - fprintf(stderr, "usage: flock [-v] [test number]\n"); - exit(1); -} - -struct test { - int (*testfn)(int); /* function to perform the test */ - int intr; /* non-zero if the test interrupts a lock */ -}; - -struct test tests[] = { +static struct test tests[] = { { test1, 0 }, { test2, 0 }, { test3, 1 }, @@ -1768,7 +1678,8 @@ struct test tests[] = { { test21, 0 }, { test22, 0 }, }; -int test_count = sizeof(tests) / sizeof(tests[0]); + +static int test_count = sizeof(tests) / sizeof(tests[0]); int main(int argc, char *argv[]) diff --git a/regress/sys/kern/flock/lockf.c b/regress/sys/kern/flock/lockf.c new file mode 100644 index 00000000000..95a311f8510 --- /dev/null +++ b/regress/sys/kern/flock/lockf.c @@ -0,0 +1,144 @@ +/* $OpenBSD: lockf.c,v 1.1 2018/11/06 18:11:11 anton Exp $ */ + +/* + * Copyright (c) 2018 Anton Lindqvist <anton@openbsd.org> + * + * Permission to use, copy, modify, and distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +#include <err.h> +#include <fcntl.h> +#include <stdio.h> +#include <stdlib.h> +#include <unistd.h> + +#include "util.h" + +int verbose = 0; + +/* + * Test 1 - F_LOCK positive length + */ +static int +test1(int fd) +{ + struct flock fl; + pid_t pid; + int res; + + fl.l_start = 0; + fl.l_len = 16; + fl.l_type = F_WRLCK; + fl.l_whence = SEEK_CUR; + res = fcntl(fd, F_SETLK, &fl); + FAIL(res != 0); + + pid = fork(); + if (pid == -1) + err(1, "fork"); + if (pid == 0) { + res = fcntl(fd, F_SETLK, &fl); + FAIL(res != -1); + FAIL(fl.l_type != F_WRLCK); + _exit(0); + } + res = safe_waitpid(pid); + FAIL(res != 0); + + SUCCEED; +} + +/* + * Test 2 - F_LOCK negative length + */ +static int +test2(int fd) +{ + struct flock fl; + pid_t pid; + off_t len = 16; + int res; + + if (lseek(fd, len, SEEK_SET) == -1) + err(1, "lseek"); + + fl.l_start = 0; + fl.l_len = -len; + fl.l_type = F_WRLCK; + fl.l_whence = SEEK_CUR; + res = fcntl(fd, F_SETLK, &fl); + FAIL(res != 0); + + pid = fork(); + if (pid == -1) + err(1, "fork"); + if (pid == 0) { + if (lseek(fd, 0, SEEK_SET) == -1) + err(1, "lseek"); + + fl.l_start = 0; + fl.l_len = len; + fl.l_whence = SEEK_SET; + res = fcntl(fd, F_GETLK, &fl); + FAIL(res != 0); + FAIL(fl.l_type != F_WRLCK); + _exit(0); + } + res = safe_waitpid(pid); + FAIL(res != 0); + + SUCCEED; +} + +static struct test tests[] = { + { test1, 0 }, + { test2, 0 }, +}; + +static int test_count = sizeof(tests) / sizeof(tests[0]); + +int +main(int argc, char *argv[]) +{ + const char *errstr; + int c, error, fd, i; + int testnum = 0; + + while ((c = getopt(argc, argv, "v")) != -1) + switch (c) { + case 'v': + verbose = 1; + break; + default: + usage(); + } + argc -= optind; + argv += optind; + if (argc > 1) + usage(); + if (argc == 1) { + testnum = strtonum(argv[0], 1, test_count, &errstr); + if (testnum == 0) + errx(1, "test number %s", errstr); + } + + fd = make_file(1024); + + error = 0; + for (i = 0; i < test_count; i++) { + if (testnum == 0 || i + 1 == testnum) + error |= tests[i].testfn(fd); + } + + return (error ? 1 : 0); +} diff --git a/regress/sys/kern/flock/util.c b/regress/sys/kern/flock/util.c new file mode 100644 index 00000000000..751a53ed5a8 --- /dev/null +++ b/regress/sys/kern/flock/util.c @@ -0,0 +1,104 @@ +/* $OpenBSD: util.c,v 1.1 2018/11/06 18:11:11 anton Exp $ */ + +/* + * Copyright (c) 2018 Anton Lindqvist <anton@openbsd.org> + * + * Permission to use, copy, modify, and distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +#include <sys/wait.h> + +#include <err.h> +#include <errno.h> +#include <limits.h> +#include <paths.h> +#include <stdio.h> +#include <stdlib.h> +#include <string.h> +#include <unistd.h> + +#include "util.h" + +static const char *tmpdir(void); + +int +make_file(off_t size) +{ + char template[PATH_MAX]; + const char *dir; + int fd, n; + + dir = tmpdir(); + n = snprintf(template, sizeof(template), "%sflock.XXXXXX", dir); + if (n == -1 || n >= (int)sizeof(template)) + errc(1, ENAMETOOLONG, "%s", __func__); + + fd = mkstemp(template); + if (fd == -1) + err(1, "mkstemp"); + if (ftruncate(fd, size) == -1) + err(1, "ftruncate"); + if (unlink(template) == -1) + err(1, "unlink"); + + return (fd); +} + +int +safe_waitpid(pid_t pid) +{ + int save_errno; + int status; + + save_errno = errno; + errno = 0; + while (waitpid(pid, &status, 0) != pid) { + if (errno == EINTR) + continue; + err(1, "waitpid"); + } + errno = save_errno; + + return (status); +} + +__dead void +usage(void) +{ + fprintf(stderr, "usage: %s [-v] testnum\n", getprogname()); + exit(1); +} + +static const char * +tmpdir(void) +{ + static char path[PATH_MAX]; + const char *p; + size_t len; + int n; + int nosuffix = 1; + + p = getenv("TMPDIR"); + if (p == NULL || *p == '\0') + p = _PATH_TMP; + len = strlen(p); + if (len == 0) + errx(1, "%s: empty path", __func__); + if (p[len - 1] == '/') + nosuffix = 0; + n = snprintf(path, sizeof(path), "%s%s", p, nosuffix ? "/" : ""); + if (n == -1 || n >= (int)sizeof(path)) + errc(1, ENAMETOOLONG, "%s", __func__); + + return (path); +} diff --git a/regress/sys/kern/flock/util.h b/regress/sys/kern/flock/util.h new file mode 100644 index 00000000000..210eb1b01f3 --- /dev/null +++ b/regress/sys/kern/flock/util.h @@ -0,0 +1,43 @@ +/* $OpenBSD: util.h,v 1.1 2018/11/06 18:11:11 anton Exp $ */ + +/* + * Copyright (c) 2018 Anton Lindqvist <anton@openbsd.org> + * + * Permission to use, copy, modify, and distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +#define FAIL(test) do { \ + if (test) { \ + if (verbose) \ + printf("%s: %d: FAIL (%s)\n", \ + __func__, __LINE__, #test); \ + return -1; \ + } \ +} while (0) + +#define SUCCEED do { \ + if (verbose) \ + printf("SUCCEED\n"); \ + return 0; \ +} while (0) + +struct test { + int (*testfn)(int); /* function to perform the test */ + int intr; /* non-zero if the test interrupts a lock */ +}; + +int make_file(off_t size); +int safe_waitpid(pid_t pid); +__dead void usage(void); + +extern int verbose; |