• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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  * 	setsid01.c
23  *
24  * DESCRIPTION
25  * 	Test to check the error and trivial conditions in setsid system call
26  *
27  * USAGE
28  * 	setsid01
29  *
30  * RESTRICTIONS
31  * 	This test doesn't follow good LTP format - PLEASE FIX!
32  */
33 #include <sys/wait.h>
34 #include <limits.h>
35 #include <signal.h>
36 #include <errno.h>
37 #include <unistd.h>
38 #include <sys/param.h>
39 #include <sys/types.h>
40 #include <sys/stat.h>
41 #include "test.h"
42 
43 #define INVAL_FLAG	-1
44 #define USER2		301
45 #define INVAL_MAXGRP	NGROUPS_MAX + 1
46 #define INVAL_USER	999999
47 #define INVAL_PID	999999
48 
49 char *TCID = "setsid01";
50 int TST_TOTAL = 1;
51 
52 #ifdef UCLINUX
53 static char *argv0;
54 #endif
55 
56 void do_child_1(void);
57 void do_child_2(void);
58 void setup(void);
59 void cleanup(void);
60 
main(int ac,char ** av)61 int main(int ac, char **av)
62 {
63 	int pid;
64 	int fail = 0;
65 	int ret, status;
66 	int exno = 0;
67 
68 	int lc;
69 
70 	tst_parse_opts(ac, av, NULL, NULL);
71 #ifdef UCLINUX
72 	argv0 = av[0];
73 
74 	maybe_run_child(&do_child_1, "n", 1);
75 	maybe_run_child(&do_child_2, "n", 2);
76 #endif
77 
78 	/*
79 	 * perform global setup for the test
80 	 */
81 	setup();
82 
83 	for (lc = 0; TEST_LOOPING(lc); lc++) {
84 
85 		/* reset tst_count in case we are looping */
86 		tst_count = 0;
87 
88 		/*
89 		 * When the process group having forked of a child
90 		 * and then it attached itself to another process
91 		 * group and tries to setsid
92 		 */
93 		pid = FORK_OR_VFORK();
94 
95 		if (pid == 0) {
96 			if ((pid = FORK_OR_VFORK()) == -1) {
97 				tst_resm(TFAIL, "Fork failed");
98 
99 			}
100 			if (pid == 0) {
101 #ifdef UCLINUX
102 				if (self_exec(argv0, "n", 1) < 0) {
103 					tst_resm(TFAIL, "self_exec failed");
104 
105 				}
106 #else
107 				do_child_1();
108 #endif
109 			} else {
110 				if (setpgid(0, 0) < 0) {
111 					tst_resm(TFAIL,
112 						 "setpgid(parent) failed: %s",
113 						 strerror(errno));
114 					fail = 1;
115 				}
116 
117 				if ((ret = wait(&status)) > 0) {
118 					if (status != 0) {
119 						tst_resm(TFAIL,
120 							 "Test {%d} exited "
121 							 "status 0x%0x (wanted 0x0)",
122 							 ret, status);
123 						fail = 1;
124 					}
125 				}
126 			}
127 			exit(0);
128 		} else {
129 			if ((ret = wait(&status)) > 0) {
130 				if (status != 0) {
131 					tst_resm(TFAIL, "Test {%d} exited "
132 						 "status 0x%0x (wanted 0x0)",
133 						 ret, status);
134 					fail = 1;
135 				}
136 			}
137 		}
138 
139 		if (!(fail || exno)) {
140 			tst_resm(TPASS, "all misc tests passed");
141 		}
142 	}
143 	cleanup();
144 	tst_exit();
145 
146 }
147 
148 /*
149  * do_child_1()
150  */
do_child_1(void)151 void do_child_1(void)
152 {
153 	int exno = 0;
154 	int retval, ret, status;
155 	int pid;
156 
157 	sleep(1);
158 
159 	if (setpgid(0, 0) < 0) {
160 		tst_resm(TFAIL, "setpgid(0,0) failed: %s", strerror(errno));
161 		exno = 1;
162 	}
163 
164 	if ((pid = FORK_OR_VFORK()) == -1) {
165 		tst_brkm(TFAIL, NULL, "Fork failed");
166 	}
167 	if (pid == 0) {
168 #ifdef UCLINUX
169 		if (self_exec(argv0, "n", 2) < 0) {
170 			tst_brkm(TFAIL, NULL, "self_exec failed");
171 		}
172 #else
173 		do_child_2();
174 #endif
175 	} else {
176 		retval = setpgid(0, getppid());
177 		if (retval < 0) {
178 			tst_resm(TFAIL, "setpgid failed, errno :%d", errno);
179 			exno = 2;
180 		}
181 
182 		retval = setsid();
183 
184 		if (errno == EPERM) {
185 			tst_resm(TPASS, "setsid SUCCESS to set "
186 				 "errno to EPERM");
187 		} else {
188 			tst_resm(TFAIL, "setsid failed, expected %d,"
189 				 "return %d", -1, errno);
190 			exno = 3;
191 		}
192 		kill(pid, SIGKILL);
193 		if ((ret = wait(&status)) > 0) {
194 			if (status != 9) {
195 				tst_resm(TFAIL,
196 					 "Test {%d} exited status 0x%-x (wanted 0x9)",
197 					 ret, status);
198 				exno = 4;
199 			}
200 		}
201 	}
202 	exit(exno);
203 }
204 
205 /*
206  * do_child_2()
207  */
do_child_2(void)208 void do_child_2(void)
209 {
210 	for (;;) ;
211 }
212 
213 /*
214  * setup() - performs all ONE TIME setup for this test
215  */
setup(void)216 void setup(void)
217 {
218 
219 	tst_sig(FORK, DEF_HANDLER, cleanup);
220 
221 	umask(0);
222 
223 	TEST_PAUSE;
224 }
225 
226 /*
227  * cleanup() - performs all the ONE TIME cleanup for this test at completion
228  * 	       or premature exit
229  */
cleanup(void)230 void cleanup(void)
231 {
232 
233 }
234