xref: /aosp_15_r20/external/ltp/testcases/kernel/syscalls/fcntl/fcntl18.c (revision 49cdfc7efb34551c7342be41a7384b9c40d7cab7)
1 /*
2  *
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  * NAME
22  *	fcntl18.c
23  *
24  * DESCRIPTION
25  *	Test to check the error conditions in fcntl system call
26  *
27  * USAGE
28  *	fcntl18
29  *
30  * HISTORY
31  *	07/2001 Ported by Wayne Boyer
32  *
33  * RESTRICTIONS
34  *	NONE
35  */
36 
37 #include <signal.h>
38 #include <errno.h>
39 #include <pwd.h>
40 #include <sys/types.h>
41 #include <sys/wait.h>
42 #include <sys/stat.h>
43 #include <sys/param.h>
44 #include <fcntl.h>
45 #include <unistd.h>
46 #include "test.h"
47 
48 #define INVAL_FLAG	-1
49 #define INVAL_MIN	(-2147483647L-1L)
50 
51 int fd;
52 char string[40] = "";
53 
54 char *TCID = "fcntl18";
55 int TST_TOTAL = 1;
56 struct passwd *pass;
57 
58 void setup(void);
59 void cleanup(void);
60 int fail;
61 
main(int ac,char ** av)62 int main(int ac, char **av)
63 {
64 	int retval;
65 	struct flock fl;
66 	int pid, status;
67 
68 	tst_parse_opts(ac, av, NULL, NULL);
69 
70 	setup();		/* global setup */
71 
72 /* //block1: */
73 	tst_resm(TINFO, "Enter block 1");
74 	fail = 0;
75 	if ((fd = open("temp.dat", O_CREAT | O_RDWR, 0777)) < 0) {	//mode must be specified when O_CREATE is in the flag
76 		tst_resm(TFAIL, "file opening error");
77 		fail = 1;
78 	}
79 
80 	/* Error condition if address is bad */
81 	retval = fcntl(fd, F_GETLK, (struct flock *)INVAL_FLAG);
82 	if (errno == EFAULT) {
83 		tst_resm(TPASS, "Test F_GETLK: for errno EFAULT PASSED");
84 	} else {
85 		tst_resm(TFAIL, "Test F_GETLK: for errno EFAULT FAILED");
86 		fail = 1;
87 	}
88 	if (fail) {
89 		tst_resm(TINFO, "Block 1 FAILED");
90 	} else {
91 		tst_resm(TINFO, "Block 1 PASSED");
92 	}
93 	tst_resm(TINFO, "Exit block 1");
94 
95 /* //block2: */
96 	tst_resm(TINFO, "Enter block 2");
97 	fail = 0;
98 	/* Error condition if address is bad */
99 	retval = fcntl(fd, F_GETLK, (struct flock *)INVAL_FLAG);
100 	if (errno == EFAULT) {
101 		tst_resm(TPASS, "Test F_GETLK: for errno EFAULT PASSED");
102 	} else {
103 		tst_resm(TFAIL, "Test F_GETLK: for errno EFAULT FAILED");
104 		fail = 1;
105 	}
106 	if (fail) {
107 		tst_resm(TINFO, "Block 2 FAILED");
108 	} else {
109 		tst_resm(TINFO, "Block 2 PASSED");
110 	}
111 	tst_resm(TINFO, "Exit block 2");
112 
113 /* //block3: */
114 	tst_resm(TINFO, "Enter block 3");
115 	fail = 0;
116 	if ((pid = tst_fork()) == 0) {	/* child */
117 		fail = 0;
118 		pass = getpwnam("nobody");
119 		retval = setreuid(-1, pass->pw_uid);
120 		if (retval < 0) {
121 			tst_resm(TFAIL, "setreuid to user nobody failed, "
122 				 "errno: %d", errno);
123 			fail = 1;
124 		}
125 
126 		/* Error condition: invalid cmd */
127 		retval = fcntl(fd, INVAL_FLAG, &fl);
128 		if (errno == EINVAL) {
129 			tst_resm(TPASS, "Test for errno EINVAL PASSED");
130 		} else {
131 			tst_resm(TFAIL, "Test for errno EINVAL FAILED, "
132 				 "got: %d", errno);
133 			fail = 1;
134 		}
135 		exit(fail);
136 	} else {		/* parent */
137 		waitpid(pid, &status, 0);
138 		if (WEXITSTATUS(status) != 0) {
139 			tst_resm(TFAIL, "child returned bad exit status");
140 			fail = 1;
141 		}
142 		if (fail) {
143 			tst_resm(TINFO, "Block 3 FAILED");
144 		} else {
145 			tst_resm(TINFO, "Block 3 PASSED");
146 		}
147 	}
148 	tst_resm(TINFO, "Exit block 3");
149 
150 	cleanup();
151 	tst_exit();
152 
153 }
154 
155 /*
156  * setup()
157  *	performs all ONE TIME setup for this test
158  */
setup(void)159 void setup(void)
160 {
161 
162 	tst_sig(FORK, DEF_HANDLER, cleanup);
163 
164 	tst_require_root();
165 
166 	umask(0);
167 
168 	TEST_PAUSE;
169 
170 	tst_tmpdir();
171 
172 	sprintf(string, "./fcntl18.%d.1", getpid());
173 	unlink(string);
174 }
175 
176 /*
177  * cleanup()
178  *	performs all the ONE TIME cleanup for this test at completion or
179  *	or premature exit.
180  */
cleanup(void)181 void cleanup(void)
182 {
183 	/*
184 	 * print timing status if that option was specified.
185 	 * print errno log if that option was specified
186 	 */
187 	close(fd);
188 
189 	tst_rmdir();
190 
191 	unlink("temp.dat");
192 
193 }
194