1 /* 2 * Copyright (C) 2008 The Android Open Source Project 3 * All rights reserved. 4 * 5 * Redistribution and use in source and binary forms, with or without 6 * modification, are permitted provided that the following conditions 7 * are met: 8 * * Redistributions of source code must retain the above copyright 9 * notice, this list of conditions and the following disclaimer. 10 * * Redistributions in binary form must reproduce the above copyright 11 * notice, this list of conditions and the following disclaimer in 12 * the documentation and/or other materials provided with the 13 * distribution. 14 * 15 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 16 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 17 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS 18 * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE 19 * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, 20 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, 21 * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS 22 * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED 23 * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, 24 * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT 25 * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 26 * SUCH DAMAGE. 27 */ 28 29 #include <errno.h> 30 #include <stdio.h> 31 #include <stdlib.h> 32 #include <sys/wait.h> 33 34 #define CHILD_EXIT_CODE 111 35 36 typedef int (*wait_call_function)(pid_t child_pid); 37 38 static int check_wait_call(const char* title, 39 wait_call_function wait_func, 40 int expected_exit_code) { 41 printf("Testing %s(): ", title); 42 int cpid = fork(); 43 if (cpid < 0) { 44 fprintf(stderr, "ERROR: fork() failed: %s\n", strerror(errno)); 45 return -1; 46 } 47 48 if (cpid == 0) { /* in the chid process */ 49 printf("Child created pid=%d parent_pid=%d\n", getpid(), getppid()); 50 exit(expected_exit_code); 51 } 52 53 /* in the parent process */ 54 printf("Parent waiting for child with pid=%d\n", cpid); 55 int exit_code = wait_func(cpid); 56 if (exit_code < 0) 57 return -1; 58 59 if (exit_code != expected_exit_code) { 60 fprintf(stderr, "ERROR: Child exited with code %d, expected %d\n", 61 exit_code, expected_exit_code); 62 return -1; 63 } 64 printf("Testing %s(): OK\n", title); 65 return 0; 66 } 67 68 // To be called by check_wait_call() to check wait(). 69 static int check_wait(pid_t child_pid) { 70 int status = 0; 71 pid_t ret = wait(&status); 72 if (ret != child_pid) { 73 fprintf(stderr, "ERROR: wait() returned %d, expected %d\n", ret, child_pid); 74 return -1; 75 } 76 return WEXITSTATUS(status); 77 } 78 79 // To be called by check_wait_call() to check waitpid() 80 static int check_waitpid(pid_t child_pid) { 81 int status = 0; 82 pid_t ret = waitpid((pid_t)-1, &status, 0); 83 if (ret != child_pid) { 84 fprintf(stderr, "ERROR: waitpid() returned %d, expected %d\n", ret, child_pid); 85 return -1; 86 } 87 return WEXITSTATUS(status); 88 } 89 90 // To be called by check_wait_call() to check wait3() 91 static int check_wait3(pid_t child_pid) { 92 int status = 0; 93 struct rusage ru; 94 pid_t ret = wait3(&status, 0, &ru); 95 if (ret != child_pid) { 96 fprintf(stderr, "ERROR: wait3() returned %d, expected %d\n", ret, child_pid); 97 return -1; 98 } 99 return WEXITSTATUS(status); 100 } 101 102 // To be called by check_wait_call() to check wait3() 103 static int check_wait4(pid_t child_pid) { 104 int status = 0; 105 struct rusage ru; 106 pid_t ret = wait4(-1, &status, 0, &ru); 107 if (ret != child_pid) { 108 fprintf(stderr, "ERROR: wait3() returned %d, expected %d\n", ret, child_pid); 109 return -1; 110 } 111 return WEXITSTATUS(status); 112 } 113 114 int main(int argc, char *argv[]) { 115 printf("Testing for API level %d\n", __ANDROID_API__); 116 if (check_wait_call("wait", check_wait, CHILD_EXIT_CODE + 0) < 0 || 117 check_wait_call("waitpid", check_waitpid, CHILD_EXIT_CODE + 1) < 0 || 118 check_wait_call("wait3", check_wait3, CHILD_EXIT_CODE + 2) < 0 || 119 check_wait_call("wait4", check_wait4, CHILD_EXIT_CODE + 3)) { 120 return 1; 121 } 122 123 return EXIT_SUCCESS; 124 } 125 126