1 /* 2 * Copyright (c) 2015 Fujitsu Ltd. 3 * Author: Guangwen Feng <fenggw-fnst (at) cn.fujitsu.com> 4 * 5 * This program is free software; you can redistribute it and/or modify it 6 * under the terms of version 2 of the GNU General Public License as 7 * published by the Free Software Foundation. 8 * 9 * This program is distributed in the hope that it would be useful, but 10 * WITHOUT ANY WARRANTY; without even the implied warranty of 11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. 12 * 13 * You should have received a copy of the GNU General Public License 14 * alone with this program. 15 */ 16 17 /* 18 * DESCRIPTION 19 * Basic test for fcntl(2) using F_SETLEASE & F_WRLCK argument. 20 * "A write lease may be placed on a file only if there are 21 * no other open file descriptors for the file." 22 */ 23 24 #include <errno.h> 25 26 #include "test.h" 27 #include "safe_macros.h" 28 29 static void setup(void); 30 static void verify_fcntl(int); 31 static void cleanup(void); 32 33 #define FILE_MODE (S_IRWXU | S_IRWXG | S_IRWXO | S_ISUID | S_ISGID) 34 35 static int fd1; 36 static int fd2; 37 static long type; 38 39 static struct test_case_t { 40 int fd1_flag; 41 int fd2_flag; 42 } test_cases[] = { 43 {O_RDONLY, O_RDONLY}, 44 {O_RDONLY, O_WRONLY}, 45 {O_RDONLY, O_RDWR}, 46 {O_WRONLY, O_RDONLY}, 47 {O_WRONLY, O_WRONLY}, 48 {O_WRONLY, O_RDWR}, 49 {O_RDWR, O_RDONLY}, 50 {O_RDWR, O_WRONLY}, 51 {O_RDWR, O_RDWR}, 52 }; 53 54 char *TCID = "fcntl32"; 55 int TST_TOTAL = ARRAY_SIZE(test_cases); 56 57 int main(int ac, char **av) 58 { 59 int lc; 60 int tc; 61 62 tst_parse_opts(ac, av, NULL, NULL); 63 64 setup(); 65 66 for (lc = 0; TEST_LOOPING(lc); lc++) { 67 tst_count = 0; 68 69 for (tc = 0; tc < TST_TOTAL; tc++) 70 verify_fcntl(tc); 71 } 72 73 cleanup(); 74 tst_exit(); 75 } 76 77 static void setup(void) 78 { 79 tst_sig(NOFORK, DEF_HANDLER, cleanup); 80 TEST_PAUSE; 81 82 tst_tmpdir(); 83 84 switch ((type = tst_fs_type(cleanup, "."))) { 85 case TST_NFS_MAGIC: 86 case TST_RAMFS_MAGIC: 87 case TST_TMPFS_MAGIC: 88 tst_brkm(TCONF, cleanup, 89 "Cannot do fcntl(F_SETLEASE, F_WRLCK) " 90 "on %s filesystem", 91 tst_fs_type_name(type)); 92 default: 93 break; 94 } 95 96 SAFE_TOUCH(cleanup, "file", FILE_MODE, NULL); 97 } 98 99 static void verify_fcntl(int i) 100 { 101 fd1 = SAFE_OPEN(cleanup, "file", test_cases[i].fd1_flag); 102 fd2 = SAFE_OPEN(cleanup, "file", test_cases[i].fd2_flag); 103 104 TEST(fcntl(fd1, F_SETLEASE, F_WRLCK)); 105 106 if (TEST_RETURN == 0) { 107 tst_resm(TFAIL, "fcntl(F_SETLEASE, F_WRLCK) " 108 "succeeded unexpectedly"); 109 } else { 110 if (TEST_ERRNO == EBUSY || TEST_ERRNO == EAGAIN) { 111 tst_resm(TPASS | TTERRNO, 112 "fcntl(F_SETLEASE, F_WRLCK) " 113 "failed as expected"); 114 } else { 115 tst_resm(TFAIL | TTERRNO, 116 "fcntl(F_SETLEASE, F_WRLCK) " 117 "failed unexpectedly, " 118 "expected errno is EBUSY or EAGAIN"); 119 } 120 } 121 122 SAFE_CLOSE(cleanup, fd1); 123 fd1 = 0; 124 SAFE_CLOSE(cleanup, fd2); 125 fd2 = 0; 126 } 127 128 static void cleanup(void) 129 { 130 if (fd1 > 0 && close(fd1)) 131 tst_resm(TWARN | TERRNO, "Failed to close file"); 132 133 if (fd2 > 0 && close(fd2)) 134 tst_resm(TWARN | TERRNO, "Failed to close file"); 135 136 tst_rmdir(); 137 } 138