1 /* test 5 */ 2 3 #include <sys/types.h> 4 #include <sys/wait.h> 5 #include <errno.h> 6 #include <fcntl.h> 7 #include <signal.h> 8 #include <stdlib.h> 9 #include <unistd.h> 10 #include <stdio.h> 11 #include <string.h> 12 13 #define ITERATIONS 2 14 int max_error = 3; 15 #include "common.h" 16 17 18 int subtest; 19 int zero[1024]; 20 int sigmap[5] = {SIGKILL, SIGUSR1, SIGSEGV}; 21 22 23 int main(int argc, char *argv[]); 24 void test5a(void); 25 void parent(int childpid); 26 void child(int parpid); 27 void func1(int s); 28 void func8(int s); 29 void func10(int s); 30 void func11(int s); 31 void test5b(void); 32 void test5c(void); 33 void test5d(void); 34 void test5e(void); 35 void test5f(void); 36 void test5g(void); 37 void funcalrm(int s); 38 void test5h(void); 39 void test5i(void); 40 void ex(void); 41 42 volatile int childsigs, parsigs, alarms; 43 44 int main(argc, argv) 45 int argc; 46 char *argv[]; 47 { 48 int i, m = 0x7777; 49 50 start(5); 51 52 for (i = 0; i < ITERATIONS; i++) { 53 if (m & 0001) test5a(); 54 if (m & 0002) test5b(); 55 if (m & 0004) test5c(); 56 if (m & 0010) test5d(); 57 if (m & 0020) test5e(); 58 if (m & 0040) test5f(); 59 if (m & 0100) test5g(); 60 if (m & 0200) test5h(); 61 if (m & 0400) test5i(); 62 } 63 quit(); 64 return(-1); /* impossible */ 65 } 66 67 void test5a() 68 { 69 int parpid, childpid, flag, *zp; 70 71 subtest = 0; 72 flag = 0; 73 for (zp = &zero[0]; zp < &zero[1024]; zp++) 74 if (*zp != 0) flag = 1; 75 if (flag) e(0); /* check if bss is cleared to 0 */ 76 if (signal(SIGHUP, func1) == SIG_ERR) e(1); 77 if (signal(SIGUSR1, func10) == SIG_ERR) e(2); 78 parpid = getpid(); 79 if ((childpid = fork()) != 0) { 80 if (childpid < 0) ex(); 81 parent(childpid); 82 } else { 83 child(parpid); 84 } 85 if (signal(SIGHUP, SIG_DFL) == SIG_ERR) e(4); 86 if (signal(SIGUSR1, SIG_DFL) == SIG_ERR) e(5); 87 } 88 89 void parent(childpid) 90 int childpid; 91 { 92 int i, pid; 93 94 for (i = 0; i < 3; i++) { 95 if (kill(childpid, SIGHUP) < 0) e(6); 96 while (parsigs == 0); 97 parsigs--; 98 } 99 if ( (pid = wait(&i)) < 0) e(7); 100 if (i != 256 * 6) e(8); 101 } 102 103 void child(parpid) 104 int parpid; 105 { 106 107 int i; 108 109 for (i = 0; i < 3; i++) { 110 while (childsigs == 0); 111 childsigs--; 112 if (kill(parpid, SIGUSR1) < 0) e(9); 113 } 114 exit(6); 115 } 116 117 void func1(s) 118 int s; /* for ANSI */ 119 { 120 if (signal(SIGHUP, func1) == SIG_ERR) e(10); 121 childsigs++; 122 } 123 124 void func8(s) 125 int s; 126 { 127 } 128 129 void func10(s) 130 int s; /* for ANSI */ 131 { 132 if (signal(SIGUSR1, func10) == SIG_ERR) e(11); 133 parsigs++; 134 } 135 136 void func11(s) 137 int s; /* for ANSI */ 138 { 139 e(38); 140 } 141 142 void test5b() 143 { 144 int cpid, n, pid; 145 146 subtest = 1; 147 if ((pid = fork()) != 0) { 148 if (pid < 0) ex(); 149 if ((pid = fork()) != 0) { 150 if (pid < 0) ex(); 151 if ((cpid = fork()) != 0) { 152 if (cpid < 0) ex(); 153 if (kill(cpid, SIGKILL) < 0) e(12); 154 if (wait(&n) < 0) e(13); 155 if (wait(&n) < 0) e(14); 156 if (wait(&n) < 0) e(15); 157 } else { 158 pause(); 159 while (1); 160 } 161 } else { 162 exit(0); 163 } 164 } else { 165 exit(0); 166 } 167 } 168 169 void test5c() 170 { 171 int n, i, pid, wpid; 172 173 /* Test exit status codes for processes killed by signals. */ 174 subtest = 3; 175 for (i = 0; i < 2; i++) { 176 if ((pid = fork()) != 0) { 177 if (pid < 0) ex(); 178 sleep(2); /* wait for child to pause */ 179 if (kill(pid, sigmap[i]) < 0) { 180 e(20); 181 exit(1); 182 } 183 if ((wpid = wait(&n)) < 0) e(21); 184 if ((n & 077) != sigmap[i]) e(22); 185 if (pid != wpid) e(23); 186 } else { 187 pause(); 188 exit(0); 189 } 190 } 191 } 192 193 void test5d() 194 { 195 /* Test alarm */ 196 197 int i; 198 199 subtest = 4; 200 alarms = 0; 201 for (i = 0; i < 8; i++) { 202 signal(SIGALRM, funcalrm); 203 alarm(1); 204 pause(); 205 if (alarms != i + 1) e(24); 206 } 207 } 208 209 void test5e() 210 { 211 /* When a signal knocks a processes out of WAITPID or PAUSE, it is supposed to 212 * get EINTR as error status. Check that. 213 */ 214 int n; 215 216 subtest = 5; 217 if (signal(SIGFPE, func8) == SIG_ERR) e(25); 218 if ((n = fork()) != 0) { 219 /* Parent must delay to give child a chance to pause. */ 220 if (n < 0) ex(); 221 sleep(1); 222 if (kill(n, SIGFPE) < 0) e(26); 223 if (wait(&n) < 0) e(27); 224 if (signal(SIGFPE, SIG_DFL) == SIG_ERR) e(28); 225 } else { 226 (void) pause(); 227 if (errno != EINTR && -errno != EINTR) e(29); 228 exit(0); 229 } 230 } 231 232 void test5f() 233 { 234 int i, j, k, n; 235 236 subtest = 6; 237 if (getuid() != 0) return; 238 n = fork(); 239 if (n < 0) ex(); 240 if (n) { 241 wait(&i); 242 i = (i >> 8) & 0377; 243 if (i != (n & 0377)) e(30); 244 } else { 245 i = getgid(); 246 j = getegid(); 247 k = (i + j + 7) & 0377; 248 if (setgid(k) < 0) e(31); 249 if (getgid() != k) e(32); 250 if (getegid() != k) e(33); 251 i = getuid(); 252 j = geteuid(); 253 k = (i + j + 1) & 0377; 254 if (setuid(k) < 0) e(34); 255 if (getuid() != k) e(35); 256 if (geteuid() != k) e(36); 257 i = getpid() & 0377; 258 if (wait(&j) != -1) e(37); 259 exit(i); 260 } 261 } 262 263 void test5g() 264 { 265 int n; 266 267 subtest = 7; 268 signal(SIGSEGV, func11); 269 signal(SIGSEGV, SIG_IGN); 270 n = getpid(); 271 if (kill(n, SIGSEGV) != 0) e(1); 272 signal(SIGSEGV, SIG_DFL); 273 } 274 275 void funcalrm(s) 276 int s; /* for ANSI */ 277 { 278 alarms++; 279 } 280 281 void test5h() 282 { 283 /* When a signal knocks a processes out of PIPE, it is supposed to 284 * get EINTR as error status. Check that. 285 */ 286 int n, fd[2]; 287 288 subtest = 8; 289 unlink("XXX.test5"); 290 if (signal(SIGFPE, func8) == SIG_ERR) e(1); 291 pipe(fd); 292 if ((n = fork()) != 0) { 293 /* Parent must delay to give child a chance to pause. */ 294 if (n < 0) ex(); 295 while (access("XXX.test5", 0) != 0) /* just wait */ ; 296 sleep(1); 297 unlink("XXX.test5"); 298 if (kill(n, SIGFPE) < 0) e(2); 299 if (wait(&n) < 0) e(3); 300 if (signal(SIGFPE, SIG_DFL) == SIG_ERR) e(4); 301 if (close(fd[0]) != 0) e(5); 302 if (close(fd[1]) != 0) e(6); 303 } else { 304 if (creat("XXX.test5", 0777) < 0) e(7); 305 (void) read(fd[0], (char *) &n, 1); 306 if (errno != EINTR) e(8); 307 exit(0); 308 } 309 } 310 311 void test5i() 312 { 313 int fd[2], pid, buf[10], n; 314 315 subtest = 9; 316 pipe(fd); 317 unlink("XXXxxxXXX"); 318 319 if ((pid = fork()) != 0) { 320 /* Parent */ 321 /* Wait until child has started and has created the XXXxxxXXX file. */ 322 while (access("XXXxxxXXX", 0) != 0) /* loop */ ; 323 sleep(1); 324 if (kill(pid, SIGKILL) != 0) e(1); 325 if (wait(&n) < 0) e(2); 326 if (close(fd[0]) != 0) e(3); 327 if (close(fd[1]) != 0) e(4); 328 } else { 329 if (creat("XXXxxxXXX", 0777) < 0) e(5); 330 read(fd[0], (char *) buf, 1); 331 e(5); /* should be killed by signal and not get here */ 332 } 333 unlink("XXXxxxXXX"); 334 } 335 336 void ex() 337 { 338 int e = errno; 339 printf("Fork failed: %s (%d)\n", strerror(e), e); 340 exit(1); 341 } 342 343