1 /* $OpenBSD: lockf.c,v 1.1 2018/11/06 18:11:11 anton Exp $ */ 2 3 /* 4 * Copyright (c) 2018 Anton Lindqvist <anton@openbsd.org> 5 * 6 * Permission to use, copy, modify, and distribute this software for any 7 * purpose with or without fee is hereby granted, provided that the above 8 * copyright notice and this permission notice appear in all copies. 9 * 10 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES 11 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF 12 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR 13 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES 14 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN 15 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF 16 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. 17 */ 18 19 #include <err.h> 20 #include <fcntl.h> 21 #include <stdio.h> 22 #include <stdlib.h> 23 #include <unistd.h> 24 25 #include "util.h" 26 27 int verbose = 0; 28 29 /* 30 * Test 1 - F_LOCK positive length 31 */ 32 static int 33 test1(int fd) 34 { 35 struct flock fl; 36 pid_t pid; 37 int res; 38 39 fl.l_start = 0; 40 fl.l_len = 16; 41 fl.l_type = F_WRLCK; 42 fl.l_whence = SEEK_CUR; 43 res = fcntl(fd, F_SETLK, &fl); 44 FAIL(res != 0); 45 46 pid = fork(); 47 if (pid == -1) 48 err(1, "fork"); 49 if (pid == 0) { 50 res = fcntl(fd, F_SETLK, &fl); 51 FAIL(res != -1); 52 FAIL(fl.l_type != F_WRLCK); 53 _exit(0); 54 } 55 res = safe_waitpid(pid); 56 FAIL(res != 0); 57 58 SUCCEED; 59 } 60 61 /* 62 * Test 2 - F_LOCK negative length 63 */ 64 static int 65 test2(int fd) 66 { 67 struct flock fl; 68 pid_t pid; 69 off_t len = 16; 70 int res; 71 72 if (lseek(fd, len, SEEK_SET) == -1) 73 err(1, "lseek"); 74 75 fl.l_start = 0; 76 fl.l_len = -len; 77 fl.l_type = F_WRLCK; 78 fl.l_whence = SEEK_CUR; 79 res = fcntl(fd, F_SETLK, &fl); 80 FAIL(res != 0); 81 82 pid = fork(); 83 if (pid == -1) 84 err(1, "fork"); 85 if (pid == 0) { 86 if (lseek(fd, 0, SEEK_SET) == -1) 87 err(1, "lseek"); 88 89 fl.l_start = 0; 90 fl.l_len = len; 91 fl.l_whence = SEEK_SET; 92 res = fcntl(fd, F_GETLK, &fl); 93 FAIL(res != 0); 94 FAIL(fl.l_type != F_WRLCK); 95 _exit(0); 96 } 97 res = safe_waitpid(pid); 98 FAIL(res != 0); 99 100 SUCCEED; 101 } 102 103 static struct test tests[] = { 104 { test1, 0 }, 105 { test2, 0 }, 106 }; 107 108 static int test_count = sizeof(tests) / sizeof(tests[0]); 109 110 int 111 main(int argc, char *argv[]) 112 { 113 const char *errstr; 114 int c, error, fd, i; 115 int testnum = 0; 116 117 while ((c = getopt(argc, argv, "v")) != -1) 118 switch (c) { 119 case 'v': 120 verbose = 1; 121 break; 122 default: 123 usage(); 124 } 125 argc -= optind; 126 argv += optind; 127 if (argc > 1) 128 usage(); 129 if (argc == 1) { 130 testnum = strtonum(argv[0], 1, test_count, &errstr); 131 if (testnum == 0) 132 errx(1, "test number %s", errstr); 133 } 134 135 fd = make_file(1024); 136 137 error = 0; 138 for (i = 0; i < test_count; i++) { 139 if (testnum == 0 || i + 1 == testnum) 140 error |= tests[i].testfn(fd); 141 } 142 143 return (error ? 1 : 0); 144 } 145