1 /* 2 * 3 * Copyright (c) Matthew Wilcox for Hewlett Packard 2003 4 * 5 * This program is free software; you can redistribute it and/or modify 6 * it under the terms of the GNU General Public License as published by 7 * the Free Software Foundation; either version 2 of the License, or 8 * (at your option) any later version. 9 * 10 * This program is distributed in the hope that it will be useful, 11 * but WITHOUT ANY WARRANTY; without even the implied warranty of 12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See 13 * the GNU General Public License for more details. 14 * 15 * You should have received a copy of the GNU General Public License 16 * along with this program; if not, write to the Free Software 17 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA 18 */ 19 20 /********************************************************** 21 * 22 * TEST IDENTIFIER : flock06 23 * 24 * EXECUTED BY : anyone 25 * 26 * TEST TITLE : Error condition test for flock(2) 27 * 28 * TEST CASE TOTAL : 1 29 * 30 * AUTHOR : Matthew Wilcox <willy (at) debian.org> 31 * 32 * SIGNALS 33 * Uses SIGUSR1 to pause before test if option set. 34 * (See the parse_opts(3) man page). 35 * 36 * DESCRIPTION 37 * This test verifies that flock locks held on one fd conflict with 38 * flock locks held on a different fd. 39 * 40 * Test: 41 * The process opens two file descriptors on the same file. 42 * It acquires an exclusive flock on the first descriptor, 43 * checks that attempting to acquire an flock on the second 44 * descriptor fails. Then it removes the first descriptor's 45 * lock and attempts to acquire an exclusive lock on the 46 * second descriptor. 47 * 48 * USAGE: <for command-line> 49 * flock06 [-c n] [-e] [-i n] [-I x] [-P x] [-t] [-h] [-f] [-p] 50 * where, -c n : Run n copies concurrently 51 * -f : Turn off functional testing 52 * -e : Turn on errno logging 53 * -h : Show help screen 54 * -i n : Execute test n times 55 * -I x : Execute test for x seconds 56 * -p : Pause for SIGUSR1 before starting 57 * -P x : Pause for x seconds between iterations 58 * -t : Turn on syscall timing 59 * 60 ****************************************************************/ 61 62 #include <stdio.h> 63 #include <errno.h> 64 #include <fcntl.h> 65 #include <sys/types.h> 66 #include <sys/stat.h> 67 #include <sys/file.h> 68 #include <sys/wait.h> 69 #include "test.h" 70 71 void setup(void); 72 void cleanup(void); 73 74 char *TCID = "flock06"; 75 int TST_TOTAL = 3; 76 char filename[100]; 77 78 int main(int argc, char **argv) 79 { 80 int lc; 81 82 tst_parse_opts(argc, argv, NULL, NULL); 83 84 setup(); 85 86 /* The following loop checks looping state if -i option given */ 87 88 for (lc = 0; TEST_LOOPING(lc); lc++) { 89 int fd1, fd2; 90 91 /* reset tst_count in case we are looping */ 92 tst_count = 0; 93 94 fd1 = open(filename, O_RDWR); 95 if (fd1 == -1) 96 tst_brkm(TFAIL | TERRNO, cleanup, 97 "failed to open the file"); 98 99 TEST(flock(fd1, LOCK_EX | LOCK_NB)); 100 if (TEST_RETURN != 0) 101 tst_resm(TFAIL | TTERRNO, 102 "First attempt to flock() failed"); 103 else 104 tst_resm(TPASS, "First attempt to flock() passed"); 105 106 fd2 = open(filename, O_RDWR); 107 if (fd2 == -1) 108 tst_brkm(TFAIL | TERRNO, cleanup, 109 "failed to open the file"); 110 111 TEST(flock(fd2, LOCK_EX | LOCK_NB)); 112 if (TEST_RETURN == -1) 113 tst_resm(TPASS, "Second attempt to flock() denied"); 114 else 115 tst_resm(TFAIL, "Second attempt to flock() succeeded!"); 116 117 TEST(flock(fd1, LOCK_UN)); 118 if (TEST_RETURN == -1) 119 tst_resm(TFAIL | TTERRNO, "Failed to unlock fd1"); 120 else 121 tst_resm(TPASS, "Unlocked fd1"); 122 123 TEST(flock(fd2, LOCK_EX | LOCK_NB)); 124 if (TEST_RETURN == -1) 125 tst_resm(TFAIL, "Third attempt to flock() denied!"); 126 else 127 tst_resm(TPASS, "Third attempt to flock() succeeded"); 128 close(fd1); 129 close(fd2); 130 131 } 132 133 cleanup(); 134 tst_exit(); 135 136 } 137 138 /* 139 * setup() 140 * performs all ONE TIME setup for this test 141 */ 142 void setup(void) 143 { 144 int fd; 145 146 tst_sig(FORK, DEF_HANDLER, cleanup); 147 148 /* Pause if that option was specified 149 * TEST_PAUSE contains the code to fork the test with the -i option. 150 * You want to make sure you do this before you create your temporary 151 * directory. 152 */ 153 TEST_PAUSE; 154 155 /* Create a unique temporary directory and chdir() to it. */ 156 tst_tmpdir(); 157 158 sprintf(filename, "flock06.%d", getpid()); 159 160 /* creating temporary file */ 161 fd = creat(filename, 0666); 162 if (fd < 0) 163 tst_brkm(TBROK, tst_rmdir, "creating a new file failed"); 164 close(fd); 165 } 166 167 /* 168 * cleanup() 169 * performs all ONE TIME cleanup for this test at 170 * completion or premature exit 171 */ 172 void cleanup(void) 173 { 174 175 unlink(filename); 176 tst_rmdir(); 177 178 } 179