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