1f08c3bdfSopenharmony_ci/*
2f08c3bdfSopenharmony_ci *
3f08c3bdfSopenharmony_ci *   Copyright (c) International Business Machines  Corp., 2001
4f08c3bdfSopenharmony_ci *
5f08c3bdfSopenharmony_ci *   This program is free software;  you can redistribute it and/or modify
6f08c3bdfSopenharmony_ci *   it under the terms of the GNU General Public License as published by
7f08c3bdfSopenharmony_ci *   the Free Software Foundation; either version 2 of the License, or
8f08c3bdfSopenharmony_ci *   (at your option) any later version.
9f08c3bdfSopenharmony_ci *
10f08c3bdfSopenharmony_ci *   This program is distributed in the hope that it will be useful,
11f08c3bdfSopenharmony_ci *   but WITHOUT ANY WARRANTY;  without even the implied warranty of
12f08c3bdfSopenharmony_ci *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See
13f08c3bdfSopenharmony_ci *   the GNU General Public License for more details.
14f08c3bdfSopenharmony_ci *
15f08c3bdfSopenharmony_ci *   You should have received a copy of the GNU General Public License
16f08c3bdfSopenharmony_ci *   along with this program;  if not, write to the Free Software
17f08c3bdfSopenharmony_ci *   Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
18f08c3bdfSopenharmony_ci */
19f08c3bdfSopenharmony_ci
20f08c3bdfSopenharmony_ci/*
21f08c3bdfSopenharmony_ci * NAME
22f08c3bdfSopenharmony_ci *	fcntl18.c
23f08c3bdfSopenharmony_ci *
24f08c3bdfSopenharmony_ci * DESCRIPTION
25f08c3bdfSopenharmony_ci *	Test to check the error conditions in fcntl system call
26f08c3bdfSopenharmony_ci *
27f08c3bdfSopenharmony_ci * USAGE
28f08c3bdfSopenharmony_ci *	fcntl18
29f08c3bdfSopenharmony_ci *
30f08c3bdfSopenharmony_ci * HISTORY
31f08c3bdfSopenharmony_ci *	07/2001 Ported by Wayne Boyer
32f08c3bdfSopenharmony_ci *
33f08c3bdfSopenharmony_ci * RESTRICTIONS
34f08c3bdfSopenharmony_ci *	NONE
35f08c3bdfSopenharmony_ci */
36f08c3bdfSopenharmony_ci
37f08c3bdfSopenharmony_ci#include <signal.h>
38f08c3bdfSopenharmony_ci#include <errno.h>
39f08c3bdfSopenharmony_ci#include <pwd.h>
40f08c3bdfSopenharmony_ci#include <sys/types.h>
41f08c3bdfSopenharmony_ci#include <sys/wait.h>
42f08c3bdfSopenharmony_ci#include <sys/stat.h>
43f08c3bdfSopenharmony_ci#include <sys/param.h>
44f08c3bdfSopenharmony_ci#include <fcntl.h>
45f08c3bdfSopenharmony_ci#include <unistd.h>
46f08c3bdfSopenharmony_ci#include "test.h"
47f08c3bdfSopenharmony_ci
48f08c3bdfSopenharmony_ci#define INVAL_FLAG	-1
49f08c3bdfSopenharmony_ci#define INVAL_MIN	(-2147483647L-1L)
50f08c3bdfSopenharmony_ci
51f08c3bdfSopenharmony_ciint fd;
52f08c3bdfSopenharmony_cichar string[40] = "";
53f08c3bdfSopenharmony_ci
54f08c3bdfSopenharmony_cichar *TCID = "fcntl18";
55f08c3bdfSopenharmony_ciint TST_TOTAL = 1;
56f08c3bdfSopenharmony_cistruct passwd *pass;
57f08c3bdfSopenharmony_ci
58f08c3bdfSopenharmony_civoid setup(void);
59f08c3bdfSopenharmony_civoid cleanup(void);
60f08c3bdfSopenharmony_ciint fail;
61f08c3bdfSopenharmony_ci
62f08c3bdfSopenharmony_ciint main(int ac, char **av)
63f08c3bdfSopenharmony_ci{
64f08c3bdfSopenharmony_ci	int retval;
65f08c3bdfSopenharmony_ci	struct flock fl;
66f08c3bdfSopenharmony_ci	int pid, status;
67f08c3bdfSopenharmony_ci
68f08c3bdfSopenharmony_ci	tst_parse_opts(ac, av, NULL, NULL);
69f08c3bdfSopenharmony_ci
70f08c3bdfSopenharmony_ci	setup();		/* global setup */
71f08c3bdfSopenharmony_ci
72f08c3bdfSopenharmony_ci/* //block1: */
73f08c3bdfSopenharmony_ci#ifndef UCLINUX
74f08c3bdfSopenharmony_ci	/* Skip since uClinux does not implement memory protection */
75f08c3bdfSopenharmony_ci	tst_resm(TINFO, "Enter block 1");
76f08c3bdfSopenharmony_ci	fail = 0;
77f08c3bdfSopenharmony_ci	if ((fd = open("temp.dat", O_CREAT | O_RDWR, 0777)) < 0) {	//mode must be specified when O_CREATE is in the flag
78f08c3bdfSopenharmony_ci		tst_resm(TFAIL, "file opening error");
79f08c3bdfSopenharmony_ci		fail = 1;
80f08c3bdfSopenharmony_ci	}
81f08c3bdfSopenharmony_ci
82f08c3bdfSopenharmony_ci	/* Error condition if address is bad */
83f08c3bdfSopenharmony_ci	retval = fcntl(fd, F_GETLK, (struct flock *)INVAL_FLAG);
84f08c3bdfSopenharmony_ci	if (errno == EFAULT) {
85f08c3bdfSopenharmony_ci		tst_resm(TPASS, "Test F_GETLK: for errno EFAULT PASSED");
86f08c3bdfSopenharmony_ci	} else {
87f08c3bdfSopenharmony_ci		tst_resm(TFAIL, "Test F_GETLK: for errno EFAULT FAILED");
88f08c3bdfSopenharmony_ci		fail = 1;
89f08c3bdfSopenharmony_ci	}
90f08c3bdfSopenharmony_ci	if (fail) {
91f08c3bdfSopenharmony_ci		tst_resm(TINFO, "Block 1 FAILED");
92f08c3bdfSopenharmony_ci	} else {
93f08c3bdfSopenharmony_ci		tst_resm(TINFO, "Block 1 PASSED");
94f08c3bdfSopenharmony_ci	}
95f08c3bdfSopenharmony_ci	tst_resm(TINFO, "Exit block 1");
96f08c3bdfSopenharmony_ci#else
97f08c3bdfSopenharmony_ci	tst_resm(TINFO, "Skip block 1 on uClinux");
98f08c3bdfSopenharmony_ci#endif
99f08c3bdfSopenharmony_ci
100f08c3bdfSopenharmony_ci/* //block2: */
101f08c3bdfSopenharmony_ci#ifndef UCLINUX
102f08c3bdfSopenharmony_ci	/* Skip since uClinux does not implement memory protection */
103f08c3bdfSopenharmony_ci	tst_resm(TINFO, "Enter block 2");
104f08c3bdfSopenharmony_ci	fail = 0;
105f08c3bdfSopenharmony_ci	/* Error condition if address is bad */
106f08c3bdfSopenharmony_ci	retval = fcntl(fd, F_GETLK, (struct flock *)INVAL_FLAG);
107f08c3bdfSopenharmony_ci	if (errno == EFAULT) {
108f08c3bdfSopenharmony_ci		tst_resm(TPASS, "Test F_GETLK: for errno EFAULT PASSED");
109f08c3bdfSopenharmony_ci	} else {
110f08c3bdfSopenharmony_ci		tst_resm(TFAIL, "Test F_GETLK: for errno EFAULT FAILED");
111f08c3bdfSopenharmony_ci		fail = 1;
112f08c3bdfSopenharmony_ci	}
113f08c3bdfSopenharmony_ci	if (fail) {
114f08c3bdfSopenharmony_ci		tst_resm(TINFO, "Block 2 FAILED");
115f08c3bdfSopenharmony_ci	} else {
116f08c3bdfSopenharmony_ci		tst_resm(TINFO, "Block 2 PASSED");
117f08c3bdfSopenharmony_ci	}
118f08c3bdfSopenharmony_ci	tst_resm(TINFO, "Exit block 2");
119f08c3bdfSopenharmony_ci#else
120f08c3bdfSopenharmony_ci	tst_resm(TINFO, "Skip block 2 on uClinux");
121f08c3bdfSopenharmony_ci#endif
122f08c3bdfSopenharmony_ci
123f08c3bdfSopenharmony_ci/* //block3: */
124f08c3bdfSopenharmony_ci	tst_resm(TINFO, "Enter block 3");
125f08c3bdfSopenharmony_ci	fail = 0;
126f08c3bdfSopenharmony_ci	if ((pid = FORK_OR_VFORK()) == 0) {	/* child */
127f08c3bdfSopenharmony_ci		fail = 0;
128f08c3bdfSopenharmony_ci		pass = getpwnam("nobody");
129f08c3bdfSopenharmony_ci		retval = setreuid(-1, pass->pw_uid);
130f08c3bdfSopenharmony_ci		if (retval < 0) {
131f08c3bdfSopenharmony_ci			tst_resm(TFAIL, "setreuid to user nobody failed, "
132f08c3bdfSopenharmony_ci				 "errno: %d", errno);
133f08c3bdfSopenharmony_ci			fail = 1;
134f08c3bdfSopenharmony_ci		}
135f08c3bdfSopenharmony_ci
136f08c3bdfSopenharmony_ci		/* Error condition: invalid cmd */
137f08c3bdfSopenharmony_ci		retval = fcntl(fd, INVAL_FLAG, &fl);
138f08c3bdfSopenharmony_ci		if (errno == EINVAL) {
139f08c3bdfSopenharmony_ci			tst_resm(TPASS, "Test for errno EINVAL PASSED");
140f08c3bdfSopenharmony_ci		} else {
141f08c3bdfSopenharmony_ci			tst_resm(TFAIL, "Test for errno EINVAL FAILED, "
142f08c3bdfSopenharmony_ci				 "got: %d", errno);
143f08c3bdfSopenharmony_ci			fail = 1;
144f08c3bdfSopenharmony_ci		}
145f08c3bdfSopenharmony_ci		exit(fail);
146f08c3bdfSopenharmony_ci	} else {		/* parent */
147f08c3bdfSopenharmony_ci		waitpid(pid, &status, 0);
148f08c3bdfSopenharmony_ci		if (WEXITSTATUS(status) != 0) {
149f08c3bdfSopenharmony_ci			tst_resm(TFAIL, "child returned bad exit status");
150f08c3bdfSopenharmony_ci			fail = 1;
151f08c3bdfSopenharmony_ci		}
152f08c3bdfSopenharmony_ci		if (fail) {
153f08c3bdfSopenharmony_ci			tst_resm(TINFO, "Block 3 FAILED");
154f08c3bdfSopenharmony_ci		} else {
155f08c3bdfSopenharmony_ci			tst_resm(TINFO, "Block 3 PASSED");
156f08c3bdfSopenharmony_ci		}
157f08c3bdfSopenharmony_ci	}
158f08c3bdfSopenharmony_ci	tst_resm(TINFO, "Exit block 3");
159f08c3bdfSopenharmony_ci
160f08c3bdfSopenharmony_ci	cleanup();
161f08c3bdfSopenharmony_ci	tst_exit();
162f08c3bdfSopenharmony_ci
163f08c3bdfSopenharmony_ci}
164f08c3bdfSopenharmony_ci
165f08c3bdfSopenharmony_ci/*
166f08c3bdfSopenharmony_ci * setup()
167f08c3bdfSopenharmony_ci *	performs all ONE TIME setup for this test
168f08c3bdfSopenharmony_ci */
169f08c3bdfSopenharmony_civoid setup(void)
170f08c3bdfSopenharmony_ci{
171f08c3bdfSopenharmony_ci
172f08c3bdfSopenharmony_ci	tst_sig(FORK, DEF_HANDLER, cleanup);
173f08c3bdfSopenharmony_ci
174f08c3bdfSopenharmony_ci	tst_require_root();
175f08c3bdfSopenharmony_ci
176f08c3bdfSopenharmony_ci	umask(0);
177f08c3bdfSopenharmony_ci
178f08c3bdfSopenharmony_ci	TEST_PAUSE;
179f08c3bdfSopenharmony_ci
180f08c3bdfSopenharmony_ci	tst_tmpdir();
181f08c3bdfSopenharmony_ci
182f08c3bdfSopenharmony_ci	sprintf(string, "./fcntl18.%d.1", getpid());
183f08c3bdfSopenharmony_ci	unlink(string);
184f08c3bdfSopenharmony_ci}
185f08c3bdfSopenharmony_ci
186f08c3bdfSopenharmony_ci/*
187f08c3bdfSopenharmony_ci * cleanup()
188f08c3bdfSopenharmony_ci *	performs all the ONE TIME cleanup for this test at completion or
189f08c3bdfSopenharmony_ci *	or premature exit.
190f08c3bdfSopenharmony_ci */
191f08c3bdfSopenharmony_civoid cleanup(void)
192f08c3bdfSopenharmony_ci{
193f08c3bdfSopenharmony_ci	/*
194f08c3bdfSopenharmony_ci	 * print timing status if that option was specified.
195f08c3bdfSopenharmony_ci	 * print errno log if that option was specified
196f08c3bdfSopenharmony_ci	 */
197f08c3bdfSopenharmony_ci	close(fd);
198f08c3bdfSopenharmony_ci
199f08c3bdfSopenharmony_ci	tst_rmdir();
200f08c3bdfSopenharmony_ci
201f08c3bdfSopenharmony_ci	unlink("temp.dat");
202f08c3bdfSopenharmony_ci
203f08c3bdfSopenharmony_ci}
204