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 <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 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 */ 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 */ 208 void do_child_2(void) 209 { 210 for (;;) ; 211 } 212 213 /* 214 * setup() - performs all ONE TIME setup for this test 215 */ 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 */ 230 void cleanup(void) 231 { 232 233 } 234