1 /*
2 *
3 * Copyright (c) International Business Machines Corp., 2004
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 : fcntl24
23 *
24 * EXECUTED BY : anyone
25 *
26 * TEST TITLE : Basic test for fcntl(2) using F_SETLEASE & F_WRLCK argument.
27 *
28 * TEST CASE TOTAL : 1
29 *
30 * WALL CLOCK TIME : 1
31 *
32 * CPU TYPES : ALL
33 *
34 * AUTHOR : Robbie Williamson
35 *
36 * TEST CASES
37 *
38 * 1.) fcntl(2) returns...(See Description)
39 *
40 * INPUT SPECIFICATIONS
41 * The standard options for system call tests are accepted.
42 * (See the parse_opts(3) man page).
43 *
44 * OUTPUT SPECIFICATIONS
45 *
46 * DURATION
47 * Terminates - with frequency and infinite modes.
48 *
49 * SIGNALS
50 * Uses SIGUSR1 to pause before test if option set.
51 * (See the parse_opts(3) man page).
52 *
53 * RESOURCES
54 * None
55 *
56 * ENVIRONMENTAL NEEDS
57 * No run-time environmental needs.
58 *
59 * SPECIAL PROCEDURAL REQUIREMENTS
60 * None
61 *
62 * INTERCASE DEPENDENCIES
63 * None
64 *
65 * DETAILED DESCRIPTION
66 * This is a Phase I test for the fcntl(2) system call. It is intended
67 * to provide a limited exposure of the system call, for now. It
68 * should/will be extended when full functional tests are written for
69 * fcntl(2).
70 *
71 * Setup:
72 * Setup signal handling.
73 * Pause for SIGUSR1 if option specified.
74 *
75 * Test:
76 * Loop if the proper options are given.
77 * Execute system call
78 * Check return code, if system call failed (return=-1)
79 * Log the errno and Issue a FAIL message.
80 * Otherwise, Issue a PASS message.
81 *
82 * Cleanup:
83 * Print errno log and/or timing stats if options given
84 *
85 *
86 *#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#**/
87
88 #include <sys/types.h>
89 #include <sys/stat.h>
90 #include <fcntl.h>
91 #include <unistd.h>
92 #include <errno.h>
93 #include <string.h>
94 #include <signal.h>
95 #include "test.h"
96
97 void setup();
98 void cleanup();
99
100 char *TCID = "fcntl24";
101 int TST_TOTAL = 1;
102
103 char fname[255];
104 int fd;
105
main(int ac,char ** av)106 int main(int ac, char **av)
107 {
108 int lc;
109 long type;
110
111 /***************************************************************
112 * parse standard options
113 ***************************************************************/
114 tst_parse_opts(ac, av, NULL, NULL);
115
116 /***************************************************************
117 * perform global setup for test
118 ***************************************************************/
119 setup();
120
121 switch ((type = tst_fs_type(cleanup, "."))) {
122 case TST_NFS_MAGIC:
123 case TST_RAMFS_MAGIC:
124 case TST_TMPFS_MAGIC:
125 tst_brkm(TCONF, cleanup,
126 "Cannot do fcntl on a file on %s filesystem",
127 tst_fs_type_name(type));
128 break;
129 }
130
131 /***************************************************************
132 * check looping state if -c option given
133 ***************************************************************/
134 for (lc = 0; TEST_LOOPING(lc); lc++) {
135
136 tst_count = 0;
137
138 #ifdef F_SETLEASE
139 /*
140 * Call fcntl(2) with F_SETLEASE & F_WRLCK argument on fname
141 */
142 TEST(fcntl(fd, F_SETLEASE, F_WRLCK));
143
144 /* check return code */
145 if (TEST_RETURN == -1) {
146 if (type == TST_OVERLAYFS_MAGIC && TEST_ERRNO == EAGAIN) {
147 tst_resm(TINFO | TTERRNO,
148 "fcntl(F_SETLEASE, F_WRLCK) failed on overlayfs as expected");
149 } else {
150 tst_resm(TFAIL,
151 "fcntl(%s, F_SETLEASE, F_WRLCK) Failed, errno=%d : %s",
152 fname, TEST_ERRNO, strerror(TEST_ERRNO));
153 }
154 } else {
155 TEST(fcntl(fd, F_GETLEASE));
156 if (TEST_RETURN != F_WRLCK)
157 tst_resm(TFAIL,
158 "fcntl(%s, F_GETLEASE) did not return F_WRLCK, returned %ld",
159 fname, TEST_RETURN);
160 else {
161 TEST(fcntl(fd, F_SETLEASE, F_UNLCK));
162 if (TEST_RETURN != 0)
163 tst_resm(TFAIL,
164 "fcntl(%s, F_SETLEASE, F_UNLCK) did not return 0, returned %ld",
165 fname, TEST_RETURN);
166 else
167 tst_resm(TPASS,
168 "fcntl(%s, F_SETLEASE, F_WRLCK)",
169 fname);
170 }
171 }
172 #else
173 tst_resm(TINFO, "F_SETLEASE not defined, skipping test");
174 #endif
175 }
176
177 cleanup();
178 tst_exit();
179 }
180
181 /***************************************************************
182 * setup() - performs all ONE TIME setup for this test.
183 ***************************************************************/
setup(void)184 void setup(void)
185 {
186
187 tst_sig(NOFORK, DEF_HANDLER, cleanup);
188
189 TEST_PAUSE;
190
191 tst_tmpdir();
192
193 sprintf(fname, "tfile_%d", getpid());
194 if ((fd = open(fname, O_RDWR | O_CREAT, 0777)) == -1) {
195 tst_brkm(TBROK, cleanup,
196 "open(%s, O_RDWR|O_CREAT,0777) Failed, errno=%d : %s",
197 fname, errno, strerror(errno));
198 }
199 }
200
201 /***************************************************************
202 * cleanup() - performs all ONE TIME cleanup for this test at
203 * completion or premature exit.
204 ***************************************************************/
cleanup(void)205 void cleanup(void)
206 {
207
208 /* close the file we've had open */
209 if (close(fd) == -1) {
210 tst_resm(TWARN, "close(%s) Failed, errno=%d : %s", fname, errno,
211 strerror(errno));
212 }
213
214 tst_rmdir();
215
216 }
217