1/*
2 *   Copyright (C) Bull S.A. 2001
3 *   Copyright (c) International Business Machines  Corp., 2001
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 * Test Name: fcntl22
22 *
23 * Test Description:
24 *  Verify that, fcntl() fails with -1 and sets errno to EAGAIN when
25 *				  Operation  is  prohibited  by locks held by other processes.
26 *
27 * Expected Result:
28 *  fcntl() should fail with return value -1 and sets expected errno.
29 *
30 * HISTORY
31 *		 06/2002 Ported by Jacky Malcles
32 */
33
34#include <fcntl.h>
35#include <errno.h>
36#include <signal.h>
37#include <stdlib.h>
38#include <sys/types.h>
39#include <sys/wait.h>
40#include "test.h"
41
42int child_pid;
43int file;
44struct flock fl;
45
46char *TCID = "fcntl22";
47int TST_TOTAL = 1;
48
49void setup(void);
50void cleanup(void);
51
52int main(int ac, char **av)
53{
54	int lc;
55
56	tst_parse_opts(ac, av, NULL, NULL);
57
58	setup();
59
60	for (lc = 0; TEST_LOOPING(lc); lc++) {
61		tst_count = 0;
62
63		child_pid = FORK_OR_VFORK();
64		switch (child_pid) {
65		case 0:
66			TEST(fcntl(file, F_SETLK, &fl));
67
68			if (TEST_RETURN != -1) {
69				tst_resm(TFAIL, "fcntl() returned %ld,"
70					 "expected -1, errno=%d", TEST_RETURN,
71					 EAGAIN);
72			} else {
73				if (TEST_ERRNO == EAGAIN) {
74					tst_resm(TPASS,
75						 "fcntl() fails with expected "
76						 "error EAGAIN errno:%d",
77						 TEST_ERRNO);
78				} else {
79					tst_resm(TFAIL, "fcntl() fails, EAGAIN, "
80						 "errno=%d, expected errno=%d",
81						 TEST_ERRNO, EAGAIN);
82				}
83			}
84			tst_exit();
85		break;
86		case -1:
87			tst_brkm(TBROK|TERRNO, cleanup, "Fork failed");
88		break;
89		default:
90			tst_record_childstatus(cleanup, child_pid);
91		}
92
93	}
94
95	cleanup();
96	tst_exit();
97}
98
99void setup(void)
100{
101	tst_sig(FORK, DEF_HANDLER, cleanup);
102
103	TEST_PAUSE;
104
105	tst_tmpdir();
106
107	if ((file = creat("regfile", 0777)) == -1) {
108		tst_brkm(TBROK, cleanup,
109			 "creat(regfile, 0777) failed, errno:%d %s", errno,
110			 strerror(errno));
111	}
112
113	fl.l_type = F_WRLCK;
114	fl.l_whence = 0;
115	fl.l_start = 0;
116	fl.l_len = 0;
117
118	if (fcntl(file, F_SETLK, &fl) < 0)
119		tst_brkm(TBROK | TERRNO, cleanup, "fcntl() failed");
120}
121
122void cleanup(void)
123{
124	close(file);
125
126	tst_rmdir();
127}
128