xref: /aosp_15_r20/external/ltp/testcases/kernel/syscalls/fcntl/fcntl16.c (revision 49cdfc7efb34551c7342be41a7384b9c40d7cab7)
1*49cdfc7eSAndroid Build Coastguard Worker /*
2*49cdfc7eSAndroid Build Coastguard Worker  *
3*49cdfc7eSAndroid Build Coastguard Worker  *   Copyright (c) International Business Machines  Corp., 2001
4*49cdfc7eSAndroid Build Coastguard Worker  *
5*49cdfc7eSAndroid Build Coastguard Worker  *   This program is free software;  you can redistribute it and/or modify
6*49cdfc7eSAndroid Build Coastguard Worker  *   it under the terms of the GNU General Public License as published by
7*49cdfc7eSAndroid Build Coastguard Worker  *   the Free Software Foundation; either version 2 of the License, or
8*49cdfc7eSAndroid Build Coastguard Worker  *   (at your option) any later version.
9*49cdfc7eSAndroid Build Coastguard Worker  *
10*49cdfc7eSAndroid Build Coastguard Worker  *   This program is distributed in the hope that it will be useful,
11*49cdfc7eSAndroid Build Coastguard Worker  *   but WITHOUT ANY WARRANTY;  without even the implied warranty of
12*49cdfc7eSAndroid Build Coastguard Worker  *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See
13*49cdfc7eSAndroid Build Coastguard Worker  *   the GNU General Public License for more details.
14*49cdfc7eSAndroid Build Coastguard Worker  *
15*49cdfc7eSAndroid Build Coastguard Worker  *   You should have received a copy of the GNU General Public License
16*49cdfc7eSAndroid Build Coastguard Worker  *   along with this program;  if not, write to the Free Software
17*49cdfc7eSAndroid Build Coastguard Worker  *   Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
18*49cdfc7eSAndroid Build Coastguard Worker  */
19*49cdfc7eSAndroid Build Coastguard Worker 
20*49cdfc7eSAndroid Build Coastguard Worker /*
21*49cdfc7eSAndroid Build Coastguard Worker  * NAME
22*49cdfc7eSAndroid Build Coastguard Worker  *	fcntl16.c
23*49cdfc7eSAndroid Build Coastguard Worker  *
24*49cdfc7eSAndroid Build Coastguard Worker  * DESCRIPTION
25*49cdfc7eSAndroid Build Coastguard Worker  *	Additional file locking test cases for checking proper notifictaion
26*49cdfc7eSAndroid Build Coastguard Worker  *	of processes on lock change
27*49cdfc7eSAndroid Build Coastguard Worker  *
28*49cdfc7eSAndroid Build Coastguard Worker  * ALGORITHM
29*49cdfc7eSAndroid Build Coastguard Worker  *	Various test cases are used to lock a file opened without mandatory
30*49cdfc7eSAndroid Build Coastguard Worker  *	locking, with madatory locking and mandatory locking with NOBLOCK.
31*49cdfc7eSAndroid Build Coastguard Worker  *	Checking that processes waiting on lock boundaries are notified
32*49cdfc7eSAndroid Build Coastguard Worker  *	properly when boundaries change
33*49cdfc7eSAndroid Build Coastguard Worker  *
34*49cdfc7eSAndroid Build Coastguard Worker  * USAGE
35*49cdfc7eSAndroid Build Coastguard Worker  *	fcntl16
36*49cdfc7eSAndroid Build Coastguard Worker  *
37*49cdfc7eSAndroid Build Coastguard Worker  * HISTORY
38*49cdfc7eSAndroid Build Coastguard Worker  *	07/2001 Ported by Wayne Boyer
39*49cdfc7eSAndroid Build Coastguard Worker  *	04/2002 wjhuie sigset cleanups
40*49cdfc7eSAndroid Build Coastguard Worker  *
41*49cdfc7eSAndroid Build Coastguard Worker  * RESTRICTIONS
42*49cdfc7eSAndroid Build Coastguard Worker  *	None
43*49cdfc7eSAndroid Build Coastguard Worker  */
44*49cdfc7eSAndroid Build Coastguard Worker 
45*49cdfc7eSAndroid Build Coastguard Worker #include <fcntl.h>
46*49cdfc7eSAndroid Build Coastguard Worker #include <signal.h>
47*49cdfc7eSAndroid Build Coastguard Worker #include <errno.h>
48*49cdfc7eSAndroid Build Coastguard Worker #include "test.h"
49*49cdfc7eSAndroid Build Coastguard Worker #include "safe_macros.h"
50*49cdfc7eSAndroid Build Coastguard Worker #include <sys/stat.h>
51*49cdfc7eSAndroid Build Coastguard Worker #include <sys/types.h>
52*49cdfc7eSAndroid Build Coastguard Worker #include <sys/wait.h>
53*49cdfc7eSAndroid Build Coastguard Worker 
54*49cdfc7eSAndroid Build Coastguard Worker 
55*49cdfc7eSAndroid Build Coastguard Worker #define SKIPVAL 0x0f00
56*49cdfc7eSAndroid Build Coastguard Worker //#define       SKIP    SKIPVAL, 0, 0L, 0L, IGNORED
57*49cdfc7eSAndroid Build Coastguard Worker #define SKIP 0,0,0L,0L,0
58*49cdfc7eSAndroid Build Coastguard Worker #if (SKIPVAL == F_RDLCK) || (SKIPVAL == F_WRLCK)
59*49cdfc7eSAndroid Build Coastguard Worker #error invalid SKIP, must not be F_RDLCK or F_WRLCK
60*49cdfc7eSAndroid Build Coastguard Worker #endif
61*49cdfc7eSAndroid Build Coastguard Worker 
62*49cdfc7eSAndroid Build Coastguard Worker #define	IGNORED		0
63*49cdfc7eSAndroid Build Coastguard Worker #define	NOBLOCK		2	/* immediate success */
64*49cdfc7eSAndroid Build Coastguard Worker #define	WILLBLOCK	3	/* blocks, succeeds, parent unlocks records */
65*49cdfc7eSAndroid Build Coastguard Worker #define	TIME_OUT	10
66*49cdfc7eSAndroid Build Coastguard Worker int NO_NFS = 1;			/* Test on NFS or not */
67*49cdfc7eSAndroid Build Coastguard Worker 
68*49cdfc7eSAndroid Build Coastguard Worker typedef struct {
69*49cdfc7eSAndroid Build Coastguard Worker 	struct flock parent_a;
70*49cdfc7eSAndroid Build Coastguard Worker 	struct flock parent_b;
71*49cdfc7eSAndroid Build Coastguard Worker 	struct flock child_a;
72*49cdfc7eSAndroid Build Coastguard Worker 	struct flock child_b;
73*49cdfc7eSAndroid Build Coastguard Worker 	struct flock parent_c;
74*49cdfc7eSAndroid Build Coastguard Worker 	struct flock parent_d;
75*49cdfc7eSAndroid Build Coastguard Worker } testcase;
76*49cdfc7eSAndroid Build Coastguard Worker 
77*49cdfc7eSAndroid Build Coastguard Worker static testcase testcases[] = {
78*49cdfc7eSAndroid Build Coastguard Worker 	/* #1 Parent_a making a write lock on entire file */
79*49cdfc7eSAndroid Build Coastguard Worker 	{{F_WRLCK, 0, 0L, 0L, IGNORED},
80*49cdfc7eSAndroid Build Coastguard Worker 	 /* Parent_b skipped */
81*49cdfc7eSAndroid Build Coastguard Worker 	 {SKIP},
82*49cdfc7eSAndroid Build Coastguard Worker 	 /* Child_a read lock on byte 1 to byte 5 */
83*49cdfc7eSAndroid Build Coastguard Worker 	 {F_RDLCK, 0, 0L, 5L, NOBLOCK},
84*49cdfc7eSAndroid Build Coastguard Worker 	 /* Child_b read lock on byte 6 to byte 10 */
85*49cdfc7eSAndroid Build Coastguard Worker 	 {F_RDLCK, 0, 6L, 5L, NOBLOCK},
86*49cdfc7eSAndroid Build Coastguard Worker 	 /*
87*49cdfc7eSAndroid Build Coastguard Worker 	  * Parent_c read lock on entire file
88*49cdfc7eSAndroid Build Coastguard Worker 	  */
89*49cdfc7eSAndroid Build Coastguard Worker 	 {F_RDLCK, 0, 0L, 0L, IGNORED},
90*49cdfc7eSAndroid Build Coastguard Worker 	 /* Parent_d skipped */
91*49cdfc7eSAndroid Build Coastguard Worker 	 {SKIP},},
92*49cdfc7eSAndroid Build Coastguard Worker 
93*49cdfc7eSAndroid Build Coastguard Worker 	/* #2 Parent_a making a write lock on entire file */
94*49cdfc7eSAndroid Build Coastguard Worker 	{{F_WRLCK, 0, 0L, 0L, IGNORED},
95*49cdfc7eSAndroid Build Coastguard Worker 	 /* Parent_b skipped */
96*49cdfc7eSAndroid Build Coastguard Worker 	 {SKIP},
97*49cdfc7eSAndroid Build Coastguard Worker 	 /* Child_a read lock on byte 1 to byte 5 */
98*49cdfc7eSAndroid Build Coastguard Worker 	 {F_RDLCK, 0, 0L, 5L, WILLBLOCK},
99*49cdfc7eSAndroid Build Coastguard Worker 	 /* Child_b read lock on byte 6 to byte 10 */
100*49cdfc7eSAndroid Build Coastguard Worker 	 {F_RDLCK, 0, 6L, 5L, WILLBLOCK},
101*49cdfc7eSAndroid Build Coastguard Worker 	 /*
102*49cdfc7eSAndroid Build Coastguard Worker 	  * Parent_c write lock on entire
103*49cdfc7eSAndroid Build Coastguard Worker 	  * file
104*49cdfc7eSAndroid Build Coastguard Worker 	  */
105*49cdfc7eSAndroid Build Coastguard Worker 	 {F_WRLCK, 0, 0L, 0L, IGNORED},
106*49cdfc7eSAndroid Build Coastguard Worker 	 /* Parent_d skipped */
107*49cdfc7eSAndroid Build Coastguard Worker 	 {SKIP},},
108*49cdfc7eSAndroid Build Coastguard Worker 
109*49cdfc7eSAndroid Build Coastguard Worker 	/* #3 Parent_a making a write lock on entire file */
110*49cdfc7eSAndroid Build Coastguard Worker 	{{F_WRLCK, 0, 0L, 0L, IGNORED},
111*49cdfc7eSAndroid Build Coastguard Worker 	 /* Parent_b skipped */
112*49cdfc7eSAndroid Build Coastguard Worker 	 {SKIP},
113*49cdfc7eSAndroid Build Coastguard Worker 	 /* Child_a read lock on byte 2 to byte 4 */
114*49cdfc7eSAndroid Build Coastguard Worker 	 {F_RDLCK, 0, 2L, 3L, WILLBLOCK},
115*49cdfc7eSAndroid Build Coastguard Worker 	 /* Child_b read lock on byte 6 to byte 8 */
116*49cdfc7eSAndroid Build Coastguard Worker 	 {F_RDLCK, 0, 6L, 3L, WILLBLOCK},
117*49cdfc7eSAndroid Build Coastguard Worker 	 /*
118*49cdfc7eSAndroid Build Coastguard Worker 	  * Parent_c read lock on byte 3 to
119*49cdfc7eSAndroid Build Coastguard Worker 	  * byte 7
120*49cdfc7eSAndroid Build Coastguard Worker 	  */
121*49cdfc7eSAndroid Build Coastguard Worker 	 {F_RDLCK, 0, 3L, 5L, IGNORED},
122*49cdfc7eSAndroid Build Coastguard Worker 	 /* Parent_d skipped */
123*49cdfc7eSAndroid Build Coastguard Worker 	 {SKIP},},
124*49cdfc7eSAndroid Build Coastguard Worker 
125*49cdfc7eSAndroid Build Coastguard Worker 	/* #4 Parent_a making a write lock on entire file */
126*49cdfc7eSAndroid Build Coastguard Worker 	{{F_WRLCK, 0, 0L, 0L, IGNORED},
127*49cdfc7eSAndroid Build Coastguard Worker 	 /* Parent_b skipped */
128*49cdfc7eSAndroid Build Coastguard Worker 	 {SKIP},
129*49cdfc7eSAndroid Build Coastguard Worker 	 /* Child_a read lock on byte 2 to byte 4 */
130*49cdfc7eSAndroid Build Coastguard Worker 	 {F_RDLCK, 0, 2L, 3L, WILLBLOCK},
131*49cdfc7eSAndroid Build Coastguard Worker 	 /* Child_b read lock on byte 6 to byte 8 */
132*49cdfc7eSAndroid Build Coastguard Worker 	 {F_RDLCK, 0, 6L, 3L, NOBLOCK},
133*49cdfc7eSAndroid Build Coastguard Worker 	 /*
134*49cdfc7eSAndroid Build Coastguard Worker 	  * Parent_c read lock on byte 5 to
135*49cdfc7eSAndroid Build Coastguard Worker 	  * byte 9
136*49cdfc7eSAndroid Build Coastguard Worker 	  */
137*49cdfc7eSAndroid Build Coastguard Worker 	 {F_RDLCK, 0, 5L, 5L, IGNORED},
138*49cdfc7eSAndroid Build Coastguard Worker 	 /* Parent_d skipped */
139*49cdfc7eSAndroid Build Coastguard Worker 	 {SKIP},},
140*49cdfc7eSAndroid Build Coastguard Worker 
141*49cdfc7eSAndroid Build Coastguard Worker 	/* #5 Parent_a making a write lock on entire file */
142*49cdfc7eSAndroid Build Coastguard Worker 	{{F_WRLCK, 0, 0L, 0L, IGNORED},
143*49cdfc7eSAndroid Build Coastguard Worker 	 /* Parent_b skipped */
144*49cdfc7eSAndroid Build Coastguard Worker 	 {SKIP},
145*49cdfc7eSAndroid Build Coastguard Worker 	 /* Child_a read lock on byte 3 to byte 7 */
146*49cdfc7eSAndroid Build Coastguard Worker 	 {F_RDLCK, 0, 3L, 5L, NOBLOCK},
147*49cdfc7eSAndroid Build Coastguard Worker 	 /* Child_b read lock on byte 5 to byte 10 */
148*49cdfc7eSAndroid Build Coastguard Worker 	 {F_RDLCK, 0, 5L, 6L, WILLBLOCK},
149*49cdfc7eSAndroid Build Coastguard Worker 	 /*
150*49cdfc7eSAndroid Build Coastguard Worker 	  * Parent_c read lock on byte 2 to
151*49cdfc7eSAndroid Build Coastguard Worker 	  * byte 8
152*49cdfc7eSAndroid Build Coastguard Worker 	  */
153*49cdfc7eSAndroid Build Coastguard Worker 	 {F_RDLCK, 0, 2L, 7L, IGNORED},
154*49cdfc7eSAndroid Build Coastguard Worker 	 /* Parent_d skipped */
155*49cdfc7eSAndroid Build Coastguard Worker 	 {SKIP},},
156*49cdfc7eSAndroid Build Coastguard Worker 
157*49cdfc7eSAndroid Build Coastguard Worker 	/* #6 Parent_a making a write lock on entire file */
158*49cdfc7eSAndroid Build Coastguard Worker 	{{F_WRLCK, 0, 0L, 0L, IGNORED},
159*49cdfc7eSAndroid Build Coastguard Worker 	 /* Parent_b skipped */
160*49cdfc7eSAndroid Build Coastguard Worker 	 {SKIP},
161*49cdfc7eSAndroid Build Coastguard Worker 	 /* Child_a read lock on byte 2 to byte 4 */
162*49cdfc7eSAndroid Build Coastguard Worker 	 {F_RDLCK, 0, 2L, 3L, WILLBLOCK},
163*49cdfc7eSAndroid Build Coastguard Worker 	 /* Child_b write lock on byte 6 to byte 8 */
164*49cdfc7eSAndroid Build Coastguard Worker 	 {F_RDLCK, 0, 6L, 3L, NOBLOCK},
165*49cdfc7eSAndroid Build Coastguard Worker 	 /* Parent_c no lock on byte 3 to 9 */
166*49cdfc7eSAndroid Build Coastguard Worker 	 {F_UNLCK, 0, 3L, 7L, IGNORED},
167*49cdfc7eSAndroid Build Coastguard Worker 	 /* Parent_d skipped */
168*49cdfc7eSAndroid Build Coastguard Worker 	 {SKIP},},
169*49cdfc7eSAndroid Build Coastguard Worker 
170*49cdfc7eSAndroid Build Coastguard Worker 	/* #7 Parent_a making a write lock on entire file */
171*49cdfc7eSAndroid Build Coastguard Worker 	{{F_WRLCK, 0, 0L, 0L, IGNORED},
172*49cdfc7eSAndroid Build Coastguard Worker 	 /* Parent_b read lock on byte 3 to byte 7 */
173*49cdfc7eSAndroid Build Coastguard Worker 	 {F_RDLCK, 0, 3L, 5L, IGNORED},
174*49cdfc7eSAndroid Build Coastguard Worker 	 /* Child_a read lock on byte 2 to byte 4 */
175*49cdfc7eSAndroid Build Coastguard Worker 	 {F_RDLCK, 0, 2L, 3L, NOBLOCK},
176*49cdfc7eSAndroid Build Coastguard Worker 	 /* Child_b read lock on byte 6 to byte 8 */
177*49cdfc7eSAndroid Build Coastguard Worker 	 {F_RDLCK, 0, 6L, 3L, NOBLOCK},
178*49cdfc7eSAndroid Build Coastguard Worker 	 /*
179*49cdfc7eSAndroid Build Coastguard Worker 	  * Parent_c read lock on byte 1 to
180*49cdfc7eSAndroid Build Coastguard Worker 	  * byte 9
181*49cdfc7eSAndroid Build Coastguard Worker 	  */
182*49cdfc7eSAndroid Build Coastguard Worker 	 {F_RDLCK, 0, 1L, 9L, IGNORED},
183*49cdfc7eSAndroid Build Coastguard Worker 	 /* Parent_d skipped */
184*49cdfc7eSAndroid Build Coastguard Worker 	 {SKIP},},
185*49cdfc7eSAndroid Build Coastguard Worker 
186*49cdfc7eSAndroid Build Coastguard Worker 	/* #8 Parent_a making a write lock on byte 2 to byte 4 */
187*49cdfc7eSAndroid Build Coastguard Worker 	{{F_WRLCK, 0, 2L, 3L, IGNORED},
188*49cdfc7eSAndroid Build Coastguard Worker 	 /* Parent_b write lock on byte 6 to byte 8 */
189*49cdfc7eSAndroid Build Coastguard Worker 	 {F_WRLCK, 0, 6L, 3L, IGNORED},
190*49cdfc7eSAndroid Build Coastguard Worker 	 /* Child_a read lock on byte 3 to byte 7 */
191*49cdfc7eSAndroid Build Coastguard Worker 	 {F_RDLCK, 0, 3L, 5L, NOBLOCK},
192*49cdfc7eSAndroid Build Coastguard Worker 	 /* Child_b skipped */
193*49cdfc7eSAndroid Build Coastguard Worker 	 {SKIP},
194*49cdfc7eSAndroid Build Coastguard Worker 	 /*
195*49cdfc7eSAndroid Build Coastguard Worker 	  * Parent_c read lock on byte 1 to
196*49cdfc7eSAndroid Build Coastguard Worker 	  * byte 5
197*49cdfc7eSAndroid Build Coastguard Worker 	  */
198*49cdfc7eSAndroid Build Coastguard Worker 	 {F_RDLCK, 0, 1L, 5L, IGNORED},
199*49cdfc7eSAndroid Build Coastguard Worker 	 /*
200*49cdfc7eSAndroid Build Coastguard Worker 	  * Parent_d read lock on
201*49cdfc7eSAndroid Build Coastguard Worker 	  * byte 5 to byte 9
202*49cdfc7eSAndroid Build Coastguard Worker 	  */
203*49cdfc7eSAndroid Build Coastguard Worker 	 {F_RDLCK, 0, 5L, 5L,
204*49cdfc7eSAndroid Build Coastguard Worker 	  IGNORED},},
205*49cdfc7eSAndroid Build Coastguard Worker 
206*49cdfc7eSAndroid Build Coastguard Worker 	/* #9 Parent_a making a write lock on entire file */
207*49cdfc7eSAndroid Build Coastguard Worker 	{{F_WRLCK, 0, 0L, 0L, IGNORED},
208*49cdfc7eSAndroid Build Coastguard Worker 	 /* Parent_b read lock on byte 3 to byte 7 */
209*49cdfc7eSAndroid Build Coastguard Worker 	 {F_RDLCK, 0, 3L, 5L, IGNORED},
210*49cdfc7eSAndroid Build Coastguard Worker 	 /* Child_a read lock on byte 2 to byte 4 */
211*49cdfc7eSAndroid Build Coastguard Worker 	 {F_RDLCK, 0, 2L, 3L, NOBLOCK},
212*49cdfc7eSAndroid Build Coastguard Worker 	 /* Child_b read lock on byte 6 to byte 8 */
213*49cdfc7eSAndroid Build Coastguard Worker 	 {F_RDLCK, 0, 6L, 3L, NOBLOCK},
214*49cdfc7eSAndroid Build Coastguard Worker 	 /*
215*49cdfc7eSAndroid Build Coastguard Worker 	  * Parent_c read lock on byte 1 to
216*49cdfc7eSAndroid Build Coastguard Worker 	  * byte 3
217*49cdfc7eSAndroid Build Coastguard Worker 	  */
218*49cdfc7eSAndroid Build Coastguard Worker 	 {F_RDLCK, 0, 1L, 3L, IGNORED},
219*49cdfc7eSAndroid Build Coastguard Worker 	 /*
220*49cdfc7eSAndroid Build Coastguard Worker 	  * Parent_d read lock on
221*49cdfc7eSAndroid Build Coastguard Worker 	  * byte 7 to byte 9
222*49cdfc7eSAndroid Build Coastguard Worker 	  */
223*49cdfc7eSAndroid Build Coastguard Worker 	 {F_RDLCK, 0, 7L, 3L,
224*49cdfc7eSAndroid Build Coastguard Worker 	  IGNORED},},
225*49cdfc7eSAndroid Build Coastguard Worker 
226*49cdfc7eSAndroid Build Coastguard Worker 	/* #10 Parent_a making a write lock on entire file */
227*49cdfc7eSAndroid Build Coastguard Worker 	{{F_WRLCK, 0, 0L, 0L, IGNORED},
228*49cdfc7eSAndroid Build Coastguard Worker 	 /* Parent_b skipped */
229*49cdfc7eSAndroid Build Coastguard Worker 	 {SKIP},
230*49cdfc7eSAndroid Build Coastguard Worker 	 /* Child_a read lock on byte 2 to byte 4 */
231*49cdfc7eSAndroid Build Coastguard Worker 	 {F_RDLCK, 0, 2L, 3L, NOBLOCK},
232*49cdfc7eSAndroid Build Coastguard Worker 	 /* Child_b read lock on byte 6 to byte 8 */
233*49cdfc7eSAndroid Build Coastguard Worker 	 {F_RDLCK, 0, 6L, 3L, NOBLOCK},
234*49cdfc7eSAndroid Build Coastguard Worker 	 /*
235*49cdfc7eSAndroid Build Coastguard Worker 	  * Parent_c read lock on byte 1 to
236*49cdfc7eSAndroid Build Coastguard Worker 	  * byte 7
237*49cdfc7eSAndroid Build Coastguard Worker 	  */
238*49cdfc7eSAndroid Build Coastguard Worker 	 {F_RDLCK, 0, 1L, 7L, IGNORED},
239*49cdfc7eSAndroid Build Coastguard Worker 	 /*
240*49cdfc7eSAndroid Build Coastguard Worker 	  * Parent_d read lock on
241*49cdfc7eSAndroid Build Coastguard Worker 	  * byte 3 to byte 9
242*49cdfc7eSAndroid Build Coastguard Worker 	  */
243*49cdfc7eSAndroid Build Coastguard Worker 	 {F_RDLCK, 0, 3L, 7L,
244*49cdfc7eSAndroid Build Coastguard Worker 	  IGNORED},},
245*49cdfc7eSAndroid Build Coastguard Worker 
246*49cdfc7eSAndroid Build Coastguard Worker 	/* #11 Parent_a making a write lock on entire file */
247*49cdfc7eSAndroid Build Coastguard Worker 	{{F_WRLCK, 0, 0L, 0L, IGNORED},
248*49cdfc7eSAndroid Build Coastguard Worker 	 /* Parent_b skipped */
249*49cdfc7eSAndroid Build Coastguard Worker 	 {SKIP},
250*49cdfc7eSAndroid Build Coastguard Worker 	 /* Child_a read lock on byte 3 to byte 7 */
251*49cdfc7eSAndroid Build Coastguard Worker 	 {F_RDLCK, 0, 3L, 5L, NOBLOCK},
252*49cdfc7eSAndroid Build Coastguard Worker 	 /* Child_b read lock on byte 3 to byte 7 */
253*49cdfc7eSAndroid Build Coastguard Worker 	 {F_RDLCK, 0, 3L, 5L, NOBLOCK},
254*49cdfc7eSAndroid Build Coastguard Worker 	 /*
255*49cdfc7eSAndroid Build Coastguard Worker 	  * Parent_c read lock on byte 3 to
256*49cdfc7eSAndroid Build Coastguard Worker 	  * byte 7
257*49cdfc7eSAndroid Build Coastguard Worker 	  */
258*49cdfc7eSAndroid Build Coastguard Worker 	 {F_RDLCK, 0, 3L, 5L, IGNORED},
259*49cdfc7eSAndroid Build Coastguard Worker 	 /* Parent_d skipped */
260*49cdfc7eSAndroid Build Coastguard Worker 	 {SKIP},},
261*49cdfc7eSAndroid Build Coastguard Worker };
262*49cdfc7eSAndroid Build Coastguard Worker 
263*49cdfc7eSAndroid Build Coastguard Worker static testcase *thiscase;
264*49cdfc7eSAndroid Build Coastguard Worker static struct flock *thislock;
265*49cdfc7eSAndroid Build Coastguard Worker static int parent;
266*49cdfc7eSAndroid Build Coastguard Worker static int child_flag1 = 0;
267*49cdfc7eSAndroid Build Coastguard Worker static int child_flag2 = 0;
268*49cdfc7eSAndroid Build Coastguard Worker static int parent_flag = 0;
269*49cdfc7eSAndroid Build Coastguard Worker static int alarm_flag = 0;
270*49cdfc7eSAndroid Build Coastguard Worker static int child_pid[2], flag[2];
271*49cdfc7eSAndroid Build Coastguard Worker static int fd;
272*49cdfc7eSAndroid Build Coastguard Worker static int test;
273*49cdfc7eSAndroid Build Coastguard Worker static char tmpname[40];
274*49cdfc7eSAndroid Build Coastguard Worker 
275*49cdfc7eSAndroid Build Coastguard Worker #define	FILEDATA	"tenbytes!"
276*49cdfc7eSAndroid Build Coastguard Worker 
277*49cdfc7eSAndroid Build Coastguard Worker extern void catch_int(int sig);	/* signal catching subroutine */
278*49cdfc7eSAndroid Build Coastguard Worker 
279*49cdfc7eSAndroid Build Coastguard Worker char *TCID = "fcntl16";
280*49cdfc7eSAndroid Build Coastguard Worker int TST_TOTAL = 1;
281*49cdfc7eSAndroid Build Coastguard Worker 
282*49cdfc7eSAndroid Build Coastguard Worker /*
283*49cdfc7eSAndroid Build Coastguard Worker  * cleanup - performs all the ONE TIME cleanup for this test at completion or
284*49cdfc7eSAndroid Build Coastguard Worker  *	premature exit
285*49cdfc7eSAndroid Build Coastguard Worker  */
cleanup(void)286*49cdfc7eSAndroid Build Coastguard Worker void cleanup(void)
287*49cdfc7eSAndroid Build Coastguard Worker {
288*49cdfc7eSAndroid Build Coastguard Worker 	tst_rmdir();
289*49cdfc7eSAndroid Build Coastguard Worker 
290*49cdfc7eSAndroid Build Coastguard Worker }
291*49cdfc7eSAndroid Build Coastguard Worker 
dochild(int kid)292*49cdfc7eSAndroid Build Coastguard Worker void dochild(int kid)
293*49cdfc7eSAndroid Build Coastguard Worker {
294*49cdfc7eSAndroid Build Coastguard Worker 	/* child process */
295*49cdfc7eSAndroid Build Coastguard Worker 	struct sigaction sact;
296*49cdfc7eSAndroid Build Coastguard Worker 	sact.sa_flags = 0;
297*49cdfc7eSAndroid Build Coastguard Worker 	sact.sa_handler = catch_int;
298*49cdfc7eSAndroid Build Coastguard Worker 	sigemptyset(&sact.sa_mask);
299*49cdfc7eSAndroid Build Coastguard Worker 	(void)sigaction(SIGUSR1, &sact, NULL);
300*49cdfc7eSAndroid Build Coastguard Worker 
301*49cdfc7eSAndroid Build Coastguard Worker 	/* Lock should succeed after blocking and parent releases lock */
302*49cdfc7eSAndroid Build Coastguard Worker 	if (kid) {
303*49cdfc7eSAndroid Build Coastguard Worker 		if ((kill(parent, SIGUSR2)) < 0) {
304*49cdfc7eSAndroid Build Coastguard Worker 			tst_resm(TFAIL, "Attempt to send signal to parent "
305*49cdfc7eSAndroid Build Coastguard Worker 				 "failed");
306*49cdfc7eSAndroid Build Coastguard Worker 			tst_resm(TFAIL, "Test case %d, child %d, errno = %d",
307*49cdfc7eSAndroid Build Coastguard Worker 				 test + 1, kid, errno);
308*49cdfc7eSAndroid Build Coastguard Worker 			exit(1);
309*49cdfc7eSAndroid Build Coastguard Worker 		}
310*49cdfc7eSAndroid Build Coastguard Worker 	} else {
311*49cdfc7eSAndroid Build Coastguard Worker 		if ((kill(parent, SIGUSR1)) < 0) {
312*49cdfc7eSAndroid Build Coastguard Worker 			tst_resm(TFAIL, "Attempt to send signal to parent "
313*49cdfc7eSAndroid Build Coastguard Worker 				 "failed");
314*49cdfc7eSAndroid Build Coastguard Worker 			tst_resm(TFAIL, "Test case %d, child %d, errno = %d",
315*49cdfc7eSAndroid Build Coastguard Worker 				 test + 1, kid, errno);
316*49cdfc7eSAndroid Build Coastguard Worker 			exit(1);
317*49cdfc7eSAndroid Build Coastguard Worker 		}
318*49cdfc7eSAndroid Build Coastguard Worker 	}
319*49cdfc7eSAndroid Build Coastguard Worker 
320*49cdfc7eSAndroid Build Coastguard Worker 	if ((fcntl(fd, F_SETLKW, thislock)) < 0) {
321*49cdfc7eSAndroid Build Coastguard Worker 		if (errno == EINTR && parent_flag) {
322*49cdfc7eSAndroid Build Coastguard Worker 			/*
323*49cdfc7eSAndroid Build Coastguard Worker 			 * signal received is waiting for lock to clear,
324*49cdfc7eSAndroid Build Coastguard Worker 			 * this is expected if flag = WILLBLOCK
325*49cdfc7eSAndroid Build Coastguard Worker 			 */
326*49cdfc7eSAndroid Build Coastguard Worker 			exit(1);
327*49cdfc7eSAndroid Build Coastguard Worker 		} else {
328*49cdfc7eSAndroid Build Coastguard Worker 			tst_resm(TFAIL, "Attempt to set child BLOCKING lock "
329*49cdfc7eSAndroid Build Coastguard Worker 				 "failed");
330*49cdfc7eSAndroid Build Coastguard Worker 			tst_resm(TFAIL, "Test case %d, errno = %d", test + 1,
331*49cdfc7eSAndroid Build Coastguard Worker 				 errno);
332*49cdfc7eSAndroid Build Coastguard Worker 			exit(2);
333*49cdfc7eSAndroid Build Coastguard Worker 		}
334*49cdfc7eSAndroid Build Coastguard Worker 	}
335*49cdfc7eSAndroid Build Coastguard Worker 	exit(0);
336*49cdfc7eSAndroid Build Coastguard Worker }				/* end of child process */
337*49cdfc7eSAndroid Build Coastguard Worker 
catch_alarm(int sig)338*49cdfc7eSAndroid Build Coastguard Worker void catch_alarm(int sig)
339*49cdfc7eSAndroid Build Coastguard Worker {
340*49cdfc7eSAndroid Build Coastguard Worker 	alarm_flag = 1;
341*49cdfc7eSAndroid Build Coastguard Worker }
342*49cdfc7eSAndroid Build Coastguard Worker 
catch_usr1(int sig)343*49cdfc7eSAndroid Build Coastguard Worker void catch_usr1(int sig)
344*49cdfc7eSAndroid Build Coastguard Worker {				/* invoked on catching SIGUSR1 */
345*49cdfc7eSAndroid Build Coastguard Worker 	/*
346*49cdfc7eSAndroid Build Coastguard Worker 	 * Set flag to let parent know that child #1 is ready to have the
347*49cdfc7eSAndroid Build Coastguard Worker 	 * lock removed
348*49cdfc7eSAndroid Build Coastguard Worker 	 */
349*49cdfc7eSAndroid Build Coastguard Worker 	child_flag1 = 1;
350*49cdfc7eSAndroid Build Coastguard Worker }
351*49cdfc7eSAndroid Build Coastguard Worker 
catch_usr2(int sig)352*49cdfc7eSAndroid Build Coastguard Worker void catch_usr2(int sig)
353*49cdfc7eSAndroid Build Coastguard Worker {				/* invoked on catching SIGUSR2 */
354*49cdfc7eSAndroid Build Coastguard Worker 	/*
355*49cdfc7eSAndroid Build Coastguard Worker 	 * Set flag to let parent know that child #2 is ready to have the
356*49cdfc7eSAndroid Build Coastguard Worker 	 * lock removed
357*49cdfc7eSAndroid Build Coastguard Worker 	 */
358*49cdfc7eSAndroid Build Coastguard Worker 	child_flag2 = 1;
359*49cdfc7eSAndroid Build Coastguard Worker }
360*49cdfc7eSAndroid Build Coastguard Worker 
catch_int(int sig)361*49cdfc7eSAndroid Build Coastguard Worker void catch_int(int sig)
362*49cdfc7eSAndroid Build Coastguard Worker {				/* invoked on child catching SIGUSR1 */
363*49cdfc7eSAndroid Build Coastguard Worker 	/*
364*49cdfc7eSAndroid Build Coastguard Worker 	 * Set flag to interrupt fcntl call in child and force a controlled
365*49cdfc7eSAndroid Build Coastguard Worker 	 * exit
366*49cdfc7eSAndroid Build Coastguard Worker 	 */
367*49cdfc7eSAndroid Build Coastguard Worker 	parent_flag = 1;
368*49cdfc7eSAndroid Build Coastguard Worker }
369*49cdfc7eSAndroid Build Coastguard Worker 
child_sig(int sig,int nkids)370*49cdfc7eSAndroid Build Coastguard Worker void child_sig(int sig, int nkids)
371*49cdfc7eSAndroid Build Coastguard Worker {
372*49cdfc7eSAndroid Build Coastguard Worker 	int i;
373*49cdfc7eSAndroid Build Coastguard Worker 
374*49cdfc7eSAndroid Build Coastguard Worker 	for (i = 0; i < nkids; i++) {
375*49cdfc7eSAndroid Build Coastguard Worker 		if (kill(child_pid[i], 0) == 0) {
376*49cdfc7eSAndroid Build Coastguard Worker 			if ((kill(child_pid[i], sig)) < 0) {
377*49cdfc7eSAndroid Build Coastguard Worker 				tst_resm(TFAIL, "Attempt to signal child %d, "
378*49cdfc7eSAndroid Build Coastguard Worker 					 "failed", i + 1);
379*49cdfc7eSAndroid Build Coastguard Worker 			}
380*49cdfc7eSAndroid Build Coastguard Worker 		}
381*49cdfc7eSAndroid Build Coastguard Worker 	}
382*49cdfc7eSAndroid Build Coastguard Worker }
383*49cdfc7eSAndroid Build Coastguard Worker 
384*49cdfc7eSAndroid Build Coastguard Worker /*
385*49cdfc7eSAndroid Build Coastguard Worker  * setup - performs all ONE TIME steup for this test
386*49cdfc7eSAndroid Build Coastguard Worker  */
setup(void)387*49cdfc7eSAndroid Build Coastguard Worker void setup(void)
388*49cdfc7eSAndroid Build Coastguard Worker {
389*49cdfc7eSAndroid Build Coastguard Worker 	struct sigaction sact;
390*49cdfc7eSAndroid Build Coastguard Worker 
391*49cdfc7eSAndroid Build Coastguard Worker 	tst_sig(FORK, DEF_HANDLER, cleanup);
392*49cdfc7eSAndroid Build Coastguard Worker 
393*49cdfc7eSAndroid Build Coastguard Worker 	umask(0);
394*49cdfc7eSAndroid Build Coastguard Worker 
395*49cdfc7eSAndroid Build Coastguard Worker 	/* Pause if option was specified */
396*49cdfc7eSAndroid Build Coastguard Worker 	TEST_PAUSE;
397*49cdfc7eSAndroid Build Coastguard Worker 
398*49cdfc7eSAndroid Build Coastguard Worker 	parent = getpid();
399*49cdfc7eSAndroid Build Coastguard Worker 
400*49cdfc7eSAndroid Build Coastguard Worker 	tst_tmpdir();
401*49cdfc7eSAndroid Build Coastguard Worker 
402*49cdfc7eSAndroid Build Coastguard Worker 	/* On NFS or not */
403*49cdfc7eSAndroid Build Coastguard Worker 	if (tst_fs_type(cleanup, ".") == TST_NFS_MAGIC)
404*49cdfc7eSAndroid Build Coastguard Worker 		NO_NFS = 0;
405*49cdfc7eSAndroid Build Coastguard Worker 
406*49cdfc7eSAndroid Build Coastguard Worker 	/* set up temp filename */
407*49cdfc7eSAndroid Build Coastguard Worker 	sprintf(tmpname, "fcntl4.%d", parent);
408*49cdfc7eSAndroid Build Coastguard Worker 
409*49cdfc7eSAndroid Build Coastguard Worker 	/*
410*49cdfc7eSAndroid Build Coastguard Worker 	 * Set up signal handling functions
411*49cdfc7eSAndroid Build Coastguard Worker 	 */
412*49cdfc7eSAndroid Build Coastguard Worker 	memset(&sact, 0, sizeof(sact));
413*49cdfc7eSAndroid Build Coastguard Worker 	sact.sa_handler = catch_usr1;
414*49cdfc7eSAndroid Build Coastguard Worker 	sigemptyset(&sact.sa_mask);
415*49cdfc7eSAndroid Build Coastguard Worker 	sigaddset(&sact.sa_mask, SIGUSR1);
416*49cdfc7eSAndroid Build Coastguard Worker 	sigaction(SIGUSR1, &sact, NULL);
417*49cdfc7eSAndroid Build Coastguard Worker 
418*49cdfc7eSAndroid Build Coastguard Worker 	memset(&sact, 0, sizeof(sact));
419*49cdfc7eSAndroid Build Coastguard Worker 	sact.sa_handler = catch_usr2;
420*49cdfc7eSAndroid Build Coastguard Worker 	sigemptyset(&sact.sa_mask);
421*49cdfc7eSAndroid Build Coastguard Worker 	sigaddset(&sact.sa_mask, SIGUSR2);
422*49cdfc7eSAndroid Build Coastguard Worker 	sigaction(SIGUSR2, &sact, NULL);
423*49cdfc7eSAndroid Build Coastguard Worker 
424*49cdfc7eSAndroid Build Coastguard Worker 	memset(&sact, 0, sizeof(sact));
425*49cdfc7eSAndroid Build Coastguard Worker 	sact.sa_handler = catch_alarm;
426*49cdfc7eSAndroid Build Coastguard Worker 	sigemptyset(&sact.sa_mask);
427*49cdfc7eSAndroid Build Coastguard Worker 	sigaddset(&sact.sa_mask, SIGALRM);
428*49cdfc7eSAndroid Build Coastguard Worker 	sigaction(SIGALRM, &sact, NULL);
429*49cdfc7eSAndroid Build Coastguard Worker }
430*49cdfc7eSAndroid Build Coastguard Worker 
run_test(int file_flag,int file_mode,int start,int end)431*49cdfc7eSAndroid Build Coastguard Worker int run_test(int file_flag, int file_mode, int start, int end)
432*49cdfc7eSAndroid Build Coastguard Worker {
433*49cdfc7eSAndroid Build Coastguard Worker 	int child_count;
434*49cdfc7eSAndroid Build Coastguard Worker 	int child;
435*49cdfc7eSAndroid Build Coastguard Worker 	int nexited;
436*49cdfc7eSAndroid Build Coastguard Worker 	int status, expect_stat;
437*49cdfc7eSAndroid Build Coastguard Worker 	int i, fail = 0;
438*49cdfc7eSAndroid Build Coastguard Worker 
439*49cdfc7eSAndroid Build Coastguard Worker 	/* loop through all test cases */
440*49cdfc7eSAndroid Build Coastguard Worker 	for (test = start; test < end; test++) {
441*49cdfc7eSAndroid Build Coastguard Worker 		/* open a temp file to lock */
442*49cdfc7eSAndroid Build Coastguard Worker 		fd = SAFE_OPEN(cleanup, tmpname, file_flag, file_mode);
443*49cdfc7eSAndroid Build Coastguard Worker 
444*49cdfc7eSAndroid Build Coastguard Worker 		/* write some dummy data to the file */
445*49cdfc7eSAndroid Build Coastguard Worker 		(void)write(fd, FILEDATA, 10);
446*49cdfc7eSAndroid Build Coastguard Worker 
447*49cdfc7eSAndroid Build Coastguard Worker 		/* Initialize first parent lock structure */
448*49cdfc7eSAndroid Build Coastguard Worker 		thiscase = &testcases[test];
449*49cdfc7eSAndroid Build Coastguard Worker 		thislock = &thiscase->parent_a;
450*49cdfc7eSAndroid Build Coastguard Worker 
451*49cdfc7eSAndroid Build Coastguard Worker 		/* set the initial parent lock on the file */
452*49cdfc7eSAndroid Build Coastguard Worker 		if ((fcntl(fd, F_SETLK, thislock)) < 0) {
453*49cdfc7eSAndroid Build Coastguard Worker 			tst_resm(TFAIL, "First parent lock failed");
454*49cdfc7eSAndroid Build Coastguard Worker 			tst_resm(TFAIL, "Test case %d, errno = %d", test + 1,
455*49cdfc7eSAndroid Build Coastguard Worker 				 errno);
456*49cdfc7eSAndroid Build Coastguard Worker 			close(fd);
457*49cdfc7eSAndroid Build Coastguard Worker 			unlink(tmpname);
458*49cdfc7eSAndroid Build Coastguard Worker 			return 1;
459*49cdfc7eSAndroid Build Coastguard Worker 		}
460*49cdfc7eSAndroid Build Coastguard Worker 
461*49cdfc7eSAndroid Build Coastguard Worker 		/* Initialize second parent lock structure */
462*49cdfc7eSAndroid Build Coastguard Worker 		thislock = &thiscase->parent_b;
463*49cdfc7eSAndroid Build Coastguard Worker 
464*49cdfc7eSAndroid Build Coastguard Worker 		if ((thislock->l_type) != IGNORED) {	/*SKIPVAL */
465*49cdfc7eSAndroid Build Coastguard Worker 			/* set the second parent lock */
466*49cdfc7eSAndroid Build Coastguard Worker 			if ((fcntl(fd, F_SETLK, thislock)) < 0) {
467*49cdfc7eSAndroid Build Coastguard Worker 				tst_resm(TFAIL, "Second parent lock failed");
468*49cdfc7eSAndroid Build Coastguard Worker 				tst_resm(TFAIL, "Test case %d, errno = %d",
469*49cdfc7eSAndroid Build Coastguard Worker 					 test + 1, errno);
470*49cdfc7eSAndroid Build Coastguard Worker 				close(fd);
471*49cdfc7eSAndroid Build Coastguard Worker 				unlink(tmpname);
472*49cdfc7eSAndroid Build Coastguard Worker 				return 1;
473*49cdfc7eSAndroid Build Coastguard Worker 			}
474*49cdfc7eSAndroid Build Coastguard Worker 		}
475*49cdfc7eSAndroid Build Coastguard Worker 
476*49cdfc7eSAndroid Build Coastguard Worker 		/* Initialize first child lock structure */
477*49cdfc7eSAndroid Build Coastguard Worker 		thislock = &thiscase->child_a;
478*49cdfc7eSAndroid Build Coastguard Worker 
479*49cdfc7eSAndroid Build Coastguard Worker 		/* Initialize child counter and flags */
480*49cdfc7eSAndroid Build Coastguard Worker 		alarm_flag = parent_flag = 0;
481*49cdfc7eSAndroid Build Coastguard Worker 		child_flag1 = child_flag2 = 0;
482*49cdfc7eSAndroid Build Coastguard Worker 		child_count = 0;
483*49cdfc7eSAndroid Build Coastguard Worker 
484*49cdfc7eSAndroid Build Coastguard Worker 		/* spawn child processes */
485*49cdfc7eSAndroid Build Coastguard Worker 		for (i = 0; i < 2; i++) {
486*49cdfc7eSAndroid Build Coastguard Worker 			if (thislock->l_type != IGNORED) {
487*49cdfc7eSAndroid Build Coastguard Worker 				if ((child = tst_fork()) == 0)
488*49cdfc7eSAndroid Build Coastguard Worker 					dochild(i);
489*49cdfc7eSAndroid Build Coastguard Worker 				if (child < 0) {
490*49cdfc7eSAndroid Build Coastguard Worker 					perror("Fork failed");
491*49cdfc7eSAndroid Build Coastguard Worker 					return 1;
492*49cdfc7eSAndroid Build Coastguard Worker 				}
493*49cdfc7eSAndroid Build Coastguard Worker 				child_count++;
494*49cdfc7eSAndroid Build Coastguard Worker 				child_pid[i] = child;
495*49cdfc7eSAndroid Build Coastguard Worker 				flag[i] = thislock->l_pid;
496*49cdfc7eSAndroid Build Coastguard Worker 			}
497*49cdfc7eSAndroid Build Coastguard Worker 			/* Initialize second child lock structure */
498*49cdfc7eSAndroid Build Coastguard Worker 			thislock = &thiscase->child_b;
499*49cdfc7eSAndroid Build Coastguard Worker 		}
500*49cdfc7eSAndroid Build Coastguard Worker 		/* parent process */
501*49cdfc7eSAndroid Build Coastguard Worker 
502*49cdfc7eSAndroid Build Coastguard Worker 		/*
503*49cdfc7eSAndroid Build Coastguard Worker 		 * Wait for children to signal they are ready. Set a timeout
504*49cdfc7eSAndroid Build Coastguard Worker 		 * just in case they don't signal at all.
505*49cdfc7eSAndroid Build Coastguard Worker 		 */
506*49cdfc7eSAndroid Build Coastguard Worker 		alarm(TIME_OUT);
507*49cdfc7eSAndroid Build Coastguard Worker 
508*49cdfc7eSAndroid Build Coastguard Worker 		while (!alarm_flag
509*49cdfc7eSAndroid Build Coastguard Worker 		       && (child_flag1 + child_flag2 != child_count)) {
510*49cdfc7eSAndroid Build Coastguard Worker 			pause();
511*49cdfc7eSAndroid Build Coastguard Worker 		}
512*49cdfc7eSAndroid Build Coastguard Worker 
513*49cdfc7eSAndroid Build Coastguard Worker 		/*
514*49cdfc7eSAndroid Build Coastguard Worker 		 * Turn off alarm and unmask signals
515*49cdfc7eSAndroid Build Coastguard Worker 		 */
516*49cdfc7eSAndroid Build Coastguard Worker 		alarm((unsigned)0);
517*49cdfc7eSAndroid Build Coastguard Worker 
518*49cdfc7eSAndroid Build Coastguard Worker 		if (child_flag1 + child_flag2 != child_count) {
519*49cdfc7eSAndroid Build Coastguard Worker 			tst_resm(TFAIL, "Test case %d: kids didn't signal",
520*49cdfc7eSAndroid Build Coastguard Worker 				 test + 1);
521*49cdfc7eSAndroid Build Coastguard Worker 			fail = 1;
522*49cdfc7eSAndroid Build Coastguard Worker 		}
523*49cdfc7eSAndroid Build Coastguard Worker 		child_flag1 = child_flag2 = alarm_flag = 0;
524*49cdfc7eSAndroid Build Coastguard Worker 
525*49cdfc7eSAndroid Build Coastguard Worker 		thislock = &thiscase->parent_c;
526*49cdfc7eSAndroid Build Coastguard Worker 
527*49cdfc7eSAndroid Build Coastguard Worker 		/* set the third parent lock on the file */
528*49cdfc7eSAndroid Build Coastguard Worker 		if ((fcntl(fd, F_SETLK, thislock)) < 0) {
529*49cdfc7eSAndroid Build Coastguard Worker 			tst_resm(TFAIL, "Third parent lock failed");
530*49cdfc7eSAndroid Build Coastguard Worker 			tst_resm(TFAIL, "Test case %d, errno = %d",
531*49cdfc7eSAndroid Build Coastguard Worker 				 test + 1, errno);
532*49cdfc7eSAndroid Build Coastguard Worker 			close(fd);
533*49cdfc7eSAndroid Build Coastguard Worker 			unlink(tmpname);
534*49cdfc7eSAndroid Build Coastguard Worker 			return 1;
535*49cdfc7eSAndroid Build Coastguard Worker 		}
536*49cdfc7eSAndroid Build Coastguard Worker 
537*49cdfc7eSAndroid Build Coastguard Worker 		/* Initialize fourth parent lock structure */
538*49cdfc7eSAndroid Build Coastguard Worker 		thislock = &thiscase->parent_d;
539*49cdfc7eSAndroid Build Coastguard Worker 
540*49cdfc7eSAndroid Build Coastguard Worker 		if ((thislock->l_type) != IGNORED) {	/*SKIPVAL */
541*49cdfc7eSAndroid Build Coastguard Worker 			/* set the fourth parent lock */
542*49cdfc7eSAndroid Build Coastguard Worker 			if ((fcntl(fd, F_SETLK, thislock)) < 0) {
543*49cdfc7eSAndroid Build Coastguard Worker 				tst_resm(TINFO, "Fourth parent lock failed");
544*49cdfc7eSAndroid Build Coastguard Worker 				tst_resm(TINFO, "Test case %d, errno = %d",
545*49cdfc7eSAndroid Build Coastguard Worker 					 test + 1, errno);
546*49cdfc7eSAndroid Build Coastguard Worker 				close(fd);
547*49cdfc7eSAndroid Build Coastguard Worker 				unlink(tmpname);
548*49cdfc7eSAndroid Build Coastguard Worker 				return 1;
549*49cdfc7eSAndroid Build Coastguard Worker 			}
550*49cdfc7eSAndroid Build Coastguard Worker 		}
551*49cdfc7eSAndroid Build Coastguard Worker 
552*49cdfc7eSAndroid Build Coastguard Worker 		/*
553*49cdfc7eSAndroid Build Coastguard Worker 		 * Wait for children to exit, or for timeout to occur.
554*49cdfc7eSAndroid Build Coastguard Worker 		 * Timeouts are expected for testcases where kids are
555*49cdfc7eSAndroid Build Coastguard Worker 		 * 'WILLBLOCK', In that case, send kids a wakeup interrupt
556*49cdfc7eSAndroid Build Coastguard Worker 		 * and wait again for them. If a second timeout occurs, then
557*49cdfc7eSAndroid Build Coastguard Worker 		 * something is wrong.
558*49cdfc7eSAndroid Build Coastguard Worker 		 */
559*49cdfc7eSAndroid Build Coastguard Worker 		alarm_flag = nexited = 0;
560*49cdfc7eSAndroid Build Coastguard Worker 		while (nexited < child_count) {
561*49cdfc7eSAndroid Build Coastguard Worker 			alarm(TIME_OUT);
562*49cdfc7eSAndroid Build Coastguard Worker 			child = wait(&status);
563*49cdfc7eSAndroid Build Coastguard Worker 			alarm(0);
564*49cdfc7eSAndroid Build Coastguard Worker 
565*49cdfc7eSAndroid Build Coastguard Worker 			if (child == -1) {
566*49cdfc7eSAndroid Build Coastguard Worker 				if (errno != EINTR || alarm_flag != 1) {
567*49cdfc7eSAndroid Build Coastguard Worker 					/*
568*49cdfc7eSAndroid Build Coastguard Worker 					 * Some error other than a timeout,
569*49cdfc7eSAndroid Build Coastguard Worker 					 * or else this is the second
570*49cdfc7eSAndroid Build Coastguard Worker 					 * timeout. Both cases are errors.
571*49cdfc7eSAndroid Build Coastguard Worker 					 */
572*49cdfc7eSAndroid Build Coastguard Worker 					break;
573*49cdfc7eSAndroid Build Coastguard Worker 				}
574*49cdfc7eSAndroid Build Coastguard Worker 
575*49cdfc7eSAndroid Build Coastguard Worker 				/*
576*49cdfc7eSAndroid Build Coastguard Worker 				 * Expected timeout case. Signal kids then
577*49cdfc7eSAndroid Build Coastguard Worker 				 * go back and wait again
578*49cdfc7eSAndroid Build Coastguard Worker 				 */
579*49cdfc7eSAndroid Build Coastguard Worker 				child_sig(SIGUSR1, child_count);
580*49cdfc7eSAndroid Build Coastguard Worker 				continue;
581*49cdfc7eSAndroid Build Coastguard Worker 			}
582*49cdfc7eSAndroid Build Coastguard Worker 
583*49cdfc7eSAndroid Build Coastguard Worker 			for (i = 0; i < child_count; i++)
584*49cdfc7eSAndroid Build Coastguard Worker 				if (child == child_pid[i])
585*49cdfc7eSAndroid Build Coastguard Worker 					break;
586*49cdfc7eSAndroid Build Coastguard Worker 			if (i == child_count) {
587*49cdfc7eSAndroid Build Coastguard Worker 				/*
588*49cdfc7eSAndroid Build Coastguard Worker 				 * Ignore unexpected kid, it could be a
589*49cdfc7eSAndroid Build Coastguard Worker 				 * leftover from a previous iteration that
590*49cdfc7eSAndroid Build Coastguard Worker 				 * timed out.
591*49cdfc7eSAndroid Build Coastguard Worker 				 */
592*49cdfc7eSAndroid Build Coastguard Worker 				continue;
593*49cdfc7eSAndroid Build Coastguard Worker 			}
594*49cdfc7eSAndroid Build Coastguard Worker 
595*49cdfc7eSAndroid Build Coastguard Worker 			/* Found the right kid, check his status */
596*49cdfc7eSAndroid Build Coastguard Worker 			nexited++;
597*49cdfc7eSAndroid Build Coastguard Worker 
598*49cdfc7eSAndroid Build Coastguard Worker 			expect_stat = (flag[i] == NOBLOCK) ? 0 : 1;
599*49cdfc7eSAndroid Build Coastguard Worker 
600*49cdfc7eSAndroid Build Coastguard Worker 			if (!WIFEXITED(status)
601*49cdfc7eSAndroid Build Coastguard Worker 			    || WEXITSTATUS(status) != expect_stat) {
602*49cdfc7eSAndroid Build Coastguard Worker 				/* got unexpected exit status from kid */
603*49cdfc7eSAndroid Build Coastguard Worker 				tst_resm(TFAIL, "Test case %d: child %d %s "
604*49cdfc7eSAndroid Build Coastguard Worker 					 "or got bad status (x%x)", test + 1,
605*49cdfc7eSAndroid Build Coastguard Worker 					 i, (flag[i] == NOBLOCK) ?
606*49cdfc7eSAndroid Build Coastguard Worker 					 "BLOCKED unexpectedly" :
607*49cdfc7eSAndroid Build Coastguard Worker 					 "failed to BLOCK", status);
608*49cdfc7eSAndroid Build Coastguard Worker 				fail = 1;
609*49cdfc7eSAndroid Build Coastguard Worker 			}
610*49cdfc7eSAndroid Build Coastguard Worker 		}
611*49cdfc7eSAndroid Build Coastguard Worker 
612*49cdfc7eSAndroid Build Coastguard Worker 		if (nexited != child_count) {
613*49cdfc7eSAndroid Build Coastguard Worker 			tst_resm(TFAIL, "Test case %d, caught %d expected %d "
614*49cdfc7eSAndroid Build Coastguard Worker 				 "children", test + 1, nexited, child_count);
615*49cdfc7eSAndroid Build Coastguard Worker 			child_sig(SIGKILL, nexited);
616*49cdfc7eSAndroid Build Coastguard Worker 			fail = 1;
617*49cdfc7eSAndroid Build Coastguard Worker 		}
618*49cdfc7eSAndroid Build Coastguard Worker 		close(fd);
619*49cdfc7eSAndroid Build Coastguard Worker 	}
620*49cdfc7eSAndroid Build Coastguard Worker 	unlink(tmpname);
621*49cdfc7eSAndroid Build Coastguard Worker 	if (fail) {
622*49cdfc7eSAndroid Build Coastguard Worker 		return 1;
623*49cdfc7eSAndroid Build Coastguard Worker 	} else {
624*49cdfc7eSAndroid Build Coastguard Worker 		return 0;
625*49cdfc7eSAndroid Build Coastguard Worker 	}
626*49cdfc7eSAndroid Build Coastguard Worker 	return 0;
627*49cdfc7eSAndroid Build Coastguard Worker }
628*49cdfc7eSAndroid Build Coastguard Worker 
main(int ac,char ** av)629*49cdfc7eSAndroid Build Coastguard Worker int main(int ac, char **av)
630*49cdfc7eSAndroid Build Coastguard Worker {
631*49cdfc7eSAndroid Build Coastguard Worker 
632*49cdfc7eSAndroid Build Coastguard Worker 	int lc;
633*49cdfc7eSAndroid Build Coastguard Worker 
634*49cdfc7eSAndroid Build Coastguard Worker 	tst_parse_opts(ac, av, NULL, NULL);
635*49cdfc7eSAndroid Build Coastguard Worker 
636*49cdfc7eSAndroid Build Coastguard Worker 	setup();		/* global setup */
637*49cdfc7eSAndroid Build Coastguard Worker 
638*49cdfc7eSAndroid Build Coastguard Worker 	for (lc = 0; TEST_LOOPING(lc); lc++) {
639*49cdfc7eSAndroid Build Coastguard Worker 		/* reset tst_count in case we are looping */
640*49cdfc7eSAndroid Build Coastguard Worker 		tst_count = 0;
641*49cdfc7eSAndroid Build Coastguard Worker 
642*49cdfc7eSAndroid Build Coastguard Worker /* //block1: */
643*49cdfc7eSAndroid Build Coastguard Worker 		/*
644*49cdfc7eSAndroid Build Coastguard Worker 		 * Check file locks on an ordinary file without
645*49cdfc7eSAndroid Build Coastguard Worker 		 * mandatory locking
646*49cdfc7eSAndroid Build Coastguard Worker 		 */
647*49cdfc7eSAndroid Build Coastguard Worker 		tst_resm(TINFO, "Entering block 1");
648*49cdfc7eSAndroid Build Coastguard Worker 		if (run_test(O_CREAT | O_RDWR | O_TRUNC, 0777, 0, 11)) {
649*49cdfc7eSAndroid Build Coastguard Worker 			tst_resm(TINFO, "Test case 1: without mandatory "
650*49cdfc7eSAndroid Build Coastguard Worker 				 "locking FAILED");
651*49cdfc7eSAndroid Build Coastguard Worker 		} else {
652*49cdfc7eSAndroid Build Coastguard Worker 			tst_resm(TINFO, "Test case 1: without manadatory "
653*49cdfc7eSAndroid Build Coastguard Worker 				 "locking PASSED");
654*49cdfc7eSAndroid Build Coastguard Worker 		}
655*49cdfc7eSAndroid Build Coastguard Worker 		tst_resm(TINFO, "Exiting block 1");
656*49cdfc7eSAndroid Build Coastguard Worker 
657*49cdfc7eSAndroid Build Coastguard Worker /* //block2: */
658*49cdfc7eSAndroid Build Coastguard Worker 		/*
659*49cdfc7eSAndroid Build Coastguard Worker 		 * Check the file locks on a file with mandatory record
660*49cdfc7eSAndroid Build Coastguard Worker 		 * locking
661*49cdfc7eSAndroid Build Coastguard Worker 		 */
662*49cdfc7eSAndroid Build Coastguard Worker 		tst_resm(TINFO, "Entering block 2");
663*49cdfc7eSAndroid Build Coastguard Worker 		if (NO_NFS && run_test(O_CREAT | O_RDWR | O_TRUNC, S_ISGID |
664*49cdfc7eSAndroid Build Coastguard Worker 			     S_IRUSR | S_IWUSR, 0, 11)) {
665*49cdfc7eSAndroid Build Coastguard Worker 			tst_resm(TINFO, "Test case 2: with mandatory record "
666*49cdfc7eSAndroid Build Coastguard Worker 				 "locking FAILED");
667*49cdfc7eSAndroid Build Coastguard Worker 		} else {
668*49cdfc7eSAndroid Build Coastguard Worker 			if (NO_NFS)
669*49cdfc7eSAndroid Build Coastguard Worker 				tst_resm(TINFO, "Test case 2: with mandatory"
670*49cdfc7eSAndroid Build Coastguard Worker 					 " record locking PASSED");
671*49cdfc7eSAndroid Build Coastguard Worker 			else
672*49cdfc7eSAndroid Build Coastguard Worker 				tst_resm(TCONF, "Test case 2: NFS does not"
673*49cdfc7eSAndroid Build Coastguard Worker 					 " support mandatory locking");
674*49cdfc7eSAndroid Build Coastguard Worker 		}
675*49cdfc7eSAndroid Build Coastguard Worker 		tst_resm(TINFO, "Exiting block 2");
676*49cdfc7eSAndroid Build Coastguard Worker 
677*49cdfc7eSAndroid Build Coastguard Worker /* //block3: */
678*49cdfc7eSAndroid Build Coastguard Worker 		/*
679*49cdfc7eSAndroid Build Coastguard Worker 		 * Check file locks on a file with mandatory record locking
680*49cdfc7eSAndroid Build Coastguard Worker 		 * and no delay
681*49cdfc7eSAndroid Build Coastguard Worker 		 */
682*49cdfc7eSAndroid Build Coastguard Worker 		tst_resm(TINFO, "Entering block 3");
683*49cdfc7eSAndroid Build Coastguard Worker 		if (NO_NFS && run_test(O_CREAT | O_RDWR | O_TRUNC | O_NDELAY,
684*49cdfc7eSAndroid Build Coastguard Worker 			     S_ISGID | S_IRUSR | S_IWUSR, 0, 11)) {
685*49cdfc7eSAndroid Build Coastguard Worker 			tst_resm(TINFO, "Test case 3: mandatory locking with "
686*49cdfc7eSAndroid Build Coastguard Worker 				 "NODELAY FAILED");
687*49cdfc7eSAndroid Build Coastguard Worker 		} else {
688*49cdfc7eSAndroid Build Coastguard Worker 			if (NO_NFS)
689*49cdfc7eSAndroid Build Coastguard Worker 				tst_resm(TINFO, "Test case 3: mandatory"
690*49cdfc7eSAndroid Build Coastguard Worker 					 " locking with NODELAY PASSED");
691*49cdfc7eSAndroid Build Coastguard Worker 			else
692*49cdfc7eSAndroid Build Coastguard Worker 				tst_resm(TCONF, "Test case 3: NFS does not"
693*49cdfc7eSAndroid Build Coastguard Worker 					 " support mandatory locking");
694*49cdfc7eSAndroid Build Coastguard Worker 		}
695*49cdfc7eSAndroid Build Coastguard Worker 		tst_resm(TINFO, "Exiting block 3");
696*49cdfc7eSAndroid Build Coastguard Worker 	}
697*49cdfc7eSAndroid Build Coastguard Worker 	cleanup();
698*49cdfc7eSAndroid Build Coastguard Worker 	tst_exit();
699*49cdfc7eSAndroid Build Coastguard Worker }
700