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 49char *TCID = "setsid01"; 50int TST_TOTAL = 1; 51 52#ifdef UCLINUX 53static char *argv0; 54#endif 55 56void do_child_1(void); 57void do_child_2(void); 58void setup(void); 59void cleanup(void); 60 61int 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 */ 151void 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 */ 208void do_child_2(void) 209{ 210 for (;;) ; 211} 212 213/* 214 * setup() - performs all ONE TIME setup for this test 215 */ 216void 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 */ 230void cleanup(void) 231{ 232 233} 234