1 /* $OpenBSD: cancel_wait.c,v 1.2 2015/09/14 08:36:32 guenther Exp $ */ 2 /* PUBLIC DOMAIN <marc@snafu.org> */ 3 4 /* 5 * Check that a thread waiting in wait/waitpid/wait3/wait4 can be 6 * cancelled. 7 */ 8 9 #include <sys/types.h> 10 #include <sys/resource.h> 11 #include <sys/time.h> 12 #include <sys/wait.h> 13 14 #include <err.h> 15 #include <pthread.h> 16 #include <unistd.h> 17 18 #include "test.h" 19 20 pid_t child; 21 int status; 22 23 static void * 24 wait_thread(void *arg) 25 { 26 wait(&status); 27 return (arg); 28 } 29 30 static void * 31 waitpid_thread(void *arg) 32 { 33 waitpid(child, &status, 0); 34 return (arg); 35 } 36 37 static void * 38 wait3_thread(void *arg) 39 { 40 wait3(&status, 0, NULL); 41 return (arg); 42 } 43 44 static void * 45 wait4_thread(void *arg) 46 { 47 wait4(child, &status, 0, NULL); 48 return (arg); 49 } 50 51 int 52 main(int argc, char *argv[]) 53 { 54 pthread_t thread; 55 void *ret = NULL; 56 57 child = fork(); 58 if (child == -1) 59 err(1, "fork"); 60 if (child == 0) { 61 sleep(1000000); 62 _exit(0); 63 } 64 65 status = 42; 66 67 printf("trying wait\n"); 68 CHECKr(pthread_create(&thread, NULL, wait_thread, NULL)); 69 sleep(1); 70 CHECKr(pthread_cancel(thread)); 71 CHECKr(pthread_join(thread, &ret)); 72 ASSERT(ret == PTHREAD_CANCELED); 73 ASSERT(status == 42); 74 75 printf("trying waitpid\n"); 76 CHECKr(pthread_create(&thread, NULL, waitpid_thread, NULL)); 77 sleep(1); 78 CHECKr(pthread_cancel(thread)); 79 CHECKr(pthread_join(thread, &ret)); 80 ASSERT(ret == PTHREAD_CANCELED); 81 ASSERT(status == 42); 82 83 printf("trying wait3\n"); 84 CHECKr(pthread_create(&thread, NULL, wait3_thread, NULL)); 85 sleep(1); 86 CHECKr(pthread_cancel(thread)); 87 CHECKr(pthread_join(thread, &ret)); 88 ASSERT(ret == PTHREAD_CANCELED); 89 ASSERT(status == 42); 90 91 printf("trying wait4\n"); 92 CHECKr(pthread_create(&thread, NULL, wait4_thread, NULL)); 93 sleep(1); 94 CHECKr(pthread_cancel(thread)); 95 CHECKr(pthread_join(thread, &ret)); 96 ASSERT(ret == PTHREAD_CANCELED); 97 ASSERT(status == 42); 98 99 kill(child, SIGKILL); 100 101 CHECKr(pthread_create(&thread, NULL, wait4_thread, NULL)); 102 sleep(1); 103 CHECKr(pthread_join(thread, &ret)); 104 ASSERT(ret == NULL); 105 ASSERT(WIFSIGNALED(status)); 106 ASSERT(WTERMSIG(status) == 9); 107 108 SUCCEED; 109 } 110