1 /*- 2 * Copyright (c) 2008 Peter Holm <pho@FreeBSD.org> 3 * All rights reserved. 4 * 5 * Redistribution and use in source and binary forms, with or without 6 * modification, are permitted provided that the following conditions 7 * are met: 8 * 1. Redistributions of source code must retain the above copyright 9 * notice, this list of conditions and the following disclaimer. 10 * 2. Redistributions in binary form must reproduce the above copyright 11 * notice, this list of conditions and the following disclaimer in the 12 * documentation and/or other materials provided with the distribution. 13 * 14 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND 15 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 16 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 17 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 18 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 19 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 20 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 21 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 22 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 23 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 24 * SUCH DAMAGE. 25 * 26 */ 27 28 /* Test lockf(3) */ 29 30 #include <stdio.h> 31 #include <stdlib.h> 32 #include <unistd.h> 33 #include <fcntl.h> 34 #include <sys/types.h> 35 #include <sys/param.h> 36 #include <sys/wait.h> 37 #include <signal.h> 38 #include <errno.h> 39 #include <err.h> 40 41 #include <stress.h> 42 43 char file[128]; 44 int fd; 45 pid_t pid; 46 47 int 48 get(void) { 49 int sem; 50 if (lockf(fd, F_LOCK, 0) == -1) 51 err(1, "lockf(%s, F_LOCK)", file); 52 if (read(fd, &sem, sizeof(sem)) != sizeof(sem)) 53 err(1, "get: read(%d)", fd); 54 if (lseek(fd, 0, SEEK_SET) == -1) 55 err(1, "lseek"); 56 if (lockf(fd, F_ULOCK, 0) == -1) 57 err(1, "lockf(%s, F_ULOCK)", file); 58 return (sem); 59 } 60 61 void 62 incr(void) { 63 int sem; 64 if (lockf(fd, F_LOCK, 0) == -1) 65 err(1, "lockf(%s, F_LOCK)", file); 66 if (read(fd, &sem, sizeof(sem)) != sizeof(sem)) 67 err(1, "incr: read(%d)", fd); 68 if (lseek(fd, 0, SEEK_SET) == -1) 69 err(1, "lseek"); 70 sem++; 71 if (write(fd, &sem, sizeof(sem)) != sizeof(sem)) 72 err(1, "incr: read"); 73 if (lseek(fd, 0, SEEK_SET) == -1) 74 err(1, "lseek"); 75 if (lockf(fd, F_ULOCK, 0) == -1) 76 err(1, "lockf(%s, F_ULOCK)", file); 77 } 78 int 79 setup(int nb) 80 { 81 return (0); 82 } 83 84 void 85 cleanup(void) 86 { 87 } 88 89 int 90 test(void) 91 { 92 int i; 93 int sem = 0; 94 95 sprintf(file, "lockf.0.%d", getpid()); 96 if ((fd = open(file,O_CREAT | O_TRUNC | O_RDWR, 0600)) == -1) 97 err(1, "creat(%s)", file); 98 if (write(fd, &sem, sizeof(sem)) != sizeof(sem)) 99 err(1, "write"); 100 if (lseek(fd, 0, SEEK_SET) == -1) 101 err(1, "lseek"); 102 103 pid = fork(); 104 if (pid == -1) { 105 perror("fork"); 106 exit(2); 107 } 108 109 if (pid == 0) { /* child */ 110 for (i = 0; i < 100; i++) { 111 while ((get() & 1) == 0) 112 ; 113 if (op->verbose > 2) 114 printf("Child %d, sem = %d\n", i, get()), 115 fflush(stdout); 116 incr(); 117 } 118 exit(0); 119 } else { /* parent */ 120 for (i = 0; i < 100; i++) { 121 while ((get() & 1) == 1) 122 ; 123 if (op->verbose > 2) 124 printf("Parent %d, sem = %d\n", i, get()), 125 fflush(stdout); 126 incr(); 127 } 128 } 129 close(fd); 130 waitpid(pid, &i, 0); 131 unlink(file); 132 133 return (0); 134 } 135