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