1 /* 2 * Copyright 2012, The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17 #include <portability.h> 18 #include <stdarg.h> 19 #include <stdlib.h> 20 #include <signal.h> 21 #include <signal_portable.h> 22 #include <stdio.h> 23 #include <sys/wait.h> 24 25 #define PORTABLE_TAG "waitpid_portable" 26 #include <log_portable.h> 27 28 /* 29 * Converts native status information at *status to portable. 30 */ 31 static void status_ntop(int *status) 32 { 33 int portable_status; 34 35 ALOGV("%s(status:%p) {", __func__, 36 status); 37 38 ASSERT(status != NULL); 39 40 /* 41 * The interpretation of status is documented in the wait(2) manual page 42 * and the implementation is in bionic/libc/include/sys/wait.h 43 */ 44 if (WIFSIGNALED(*status)) 45 portable_status = (*status & ~0x7f) | signum_ntop(WTERMSIG(*status)); 46 else if (WIFSTOPPED(*status)) 47 portable_status = (*status & ~0xff00) | (signum_ntop(WSTOPSIG(*status)) << 8); 48 else 49 portable_status = *status; 50 51 ALOGV("%s: (*status):0x%08x = portable_status:0x%08x", __func__, 52 *status, portable_status); 53 54 *status = portable_status; 55 56 ALOGV("%s: return; }", __func__); 57 } 58 59 60 pid_t WRAP(waitpid)(pid_t pid, int *status, int options) 61 { 62 pid_t rv; 63 64 ALOGV("%s(pid:%d, status:%p, options:0x%x) {", __func__, 65 pid, status, options); 66 67 rv = REAL(waitpid)(pid, status, options); 68 if (rv > 0 && status) 69 status_ntop(status); 70 71 ALOGV("%s: return rv:%d; }", __func__, rv); 72 return rv; 73 } 74 75 76 pid_t WRAP(wait)(int *status) 77 { 78 pid_t rv; 79 80 ALOGV("%s(status:%p) {", __func__, 81 status); 82 83 rv = REAL(wait)(status); 84 if (rv > 0 && status) 85 status_ntop(status); 86 87 ALOGV("%s: return rv:%d; }", __func__, rv); 88 return rv; 89 } 90 91 92 pid_t WRAP(wait3)(int *status, int options, struct rusage *rusage) 93 { 94 pid_t rv; 95 96 ALOGV("%s(status:%p, options:0x%x, rusage:%p) {", __func__, 97 status, options, rusage); 98 99 rv = REAL(wait3)(status, options, rusage); 100 if (rv > 0 && status) 101 status_ntop(status); 102 103 ALOGV("%s: return rv:%d; }", __func__, rv); 104 return rv; 105 } 106 107 // FIXME: WORKAROUND after Android wait4 has been implemented 108 pid_t REAL(wait4)(pid_t p, int *s, int o, struct rusage *r) { 109 extern pid_t __wait4(pid_t, int *, int, struct rusage *); 110 return __wait4(p,s,o,r); 111 } 112 113 pid_t WRAP(wait4)(pid_t pid, int *status, int options, struct rusage *rusage) 114 { 115 pid_t rv; 116 117 ALOGV("%s(pid:%d, status:%p, options:0x%x, rusage:%p) {", __func__, 118 pid, status, options, rusage); 119 120 rv = REAL(wait4)(pid, status, options, rusage); 121 if (rv > 0 && status) 122 status_ntop(status); 123 124 ALOGV("%s: return rv:%d; }", __func__, rv); 125 return rv; 126 } 127