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 void do_child_1(void);
53 void do_child_2(void);
54 void setup(void);
55 void cleanup(void);
56
main(int ac,char ** av)57 int main(int ac, char **av)
58 {
59 int pid;
60 int fail = 0;
61 int ret, status;
62 int exno = 0;
63
64 int lc;
65
66 tst_parse_opts(ac, av, NULL, NULL);
67
68 /*
69 * perform global setup for the test
70 */
71 setup();
72
73 for (lc = 0; TEST_LOOPING(lc); lc++) {
74
75 /* reset tst_count in case we are looping */
76 tst_count = 0;
77
78 /*
79 * When the process group having forked of a child
80 * and then it attached itself to another process
81 * group and tries to setsid
82 */
83 pid = tst_fork();
84
85 if (pid == 0) {
86 if ((pid = tst_fork()) == -1) {
87 tst_resm(TFAIL, "Fork failed");
88
89 }
90 if (pid == 0) {
91 do_child_1();
92 } else {
93 if (setpgid(0, 0) < 0) {
94 tst_resm(TFAIL,
95 "setpgid(parent) failed: %s",
96 strerror(errno));
97 fail = 1;
98 }
99
100 if ((ret = wait(&status)) > 0) {
101 if (status != 0) {
102 tst_resm(TFAIL,
103 "Test {%d} exited "
104 "status 0x%0x (wanted 0x0)",
105 ret, status);
106 fail = 1;
107 }
108 }
109 }
110 exit(0);
111 } else {
112 if ((ret = wait(&status)) > 0) {
113 if (status != 0) {
114 tst_resm(TFAIL, "Test {%d} exited "
115 "status 0x%0x (wanted 0x0)",
116 ret, status);
117 fail = 1;
118 }
119 }
120 }
121
122 if (!(fail || exno)) {
123 tst_resm(TPASS, "all misc tests passed");
124 }
125 }
126 cleanup();
127 tst_exit();
128
129 }
130
131 /*
132 * do_child_1()
133 */
do_child_1(void)134 void do_child_1(void)
135 {
136 int exno = 0;
137 int retval, ret, status;
138 int pid;
139
140 sleep(1);
141
142 if (setpgid(0, 0) < 0) {
143 tst_resm(TFAIL, "setpgid(0,0) failed: %s", strerror(errno));
144 exno = 1;
145 }
146
147 if ((pid = tst_fork()) == -1) {
148 tst_brkm(TFAIL, NULL, "Fork failed");
149 }
150 if (pid == 0) {
151 do_child_2();
152 } else {
153 retval = setpgid(0, getppid());
154 if (retval < 0) {
155 tst_resm(TFAIL, "setpgid failed, errno :%d", errno);
156 exno = 2;
157 }
158
159 retval = setsid();
160
161 if (errno == EPERM) {
162 tst_resm(TPASS, "setsid SUCCESS to set "
163 "errno to EPERM");
164 } else {
165 tst_resm(TFAIL, "setsid failed, expected %d, "
166 "return %d", -1, errno);
167 exno = 3;
168 }
169 kill(pid, SIGKILL);
170 if ((ret = wait(&status)) > 0) {
171 if (status != 9) {
172 tst_resm(TFAIL,
173 "Test {%d} exited status 0x%-x (wanted 0x9)",
174 ret, status);
175 exno = 4;
176 }
177 }
178 }
179 exit(exno);
180 }
181
182 /*
183 * do_child_2()
184 */
do_child_2(void)185 void do_child_2(void)
186 {
187 for (;;) ;
188 }
189
190 /*
191 * setup() - performs all ONE TIME setup for this test
192 */
setup(void)193 void setup(void)
194 {
195
196 tst_sig(FORK, DEF_HANDLER, cleanup);
197
198 umask(0);
199
200 TEST_PAUSE;
201 }
202
203 /*
204 * cleanup() - performs all the ONE TIME cleanup for this test at completion
205 * or premature exit
206 */
cleanup(void)207 void cleanup(void)
208 {
209
210 }
211