1#include "defs.h" 2 3#include <sys/wait.h> 4 5#ifndef __WNOTHREAD 6# define __WNOTHREAD 0x20000000 7#endif 8#ifndef __WALL 9# define __WALL 0x40000000 10#endif 11#ifndef __WCLONE 12# define __WCLONE 0x80000000 13#endif 14 15#include "xlat/wait4_options.h" 16 17#if !defined WCOREFLAG && defined WCOREFLG 18# define WCOREFLAG WCOREFLG 19#endif 20#ifndef WCOREFLAG 21# define WCOREFLAG 0x80 22#endif 23#ifndef WCOREDUMP 24# define WCOREDUMP(status) ((status) & 0200) 25#endif 26#ifndef W_STOPCODE 27# define W_STOPCODE(sig) ((sig) << 8 | 0x7f) 28#endif 29#ifndef W_EXITCODE 30# define W_EXITCODE(ret, sig) ((ret) << 8 | (sig)) 31#endif 32#ifndef W_CONTINUED 33# define W_CONTINUED 0xffff 34#endif 35 36#include "ptrace.h" 37#include "xlat/ptrace_events.h" 38 39static int 40printstatus(int status) 41{ 42 int exited = 0; 43 44 /* 45 * Here is a tricky presentation problem. This solution 46 * is still not entirely satisfactory but since there 47 * are no wait status constructors it will have to do. 48 */ 49 if (WIFSTOPPED(status)) { 50 int sig = WSTOPSIG(status); 51 tprintf("[{WIFSTOPPED(s) && WSTOPSIG(s) == %s%s}", 52 signame(sig & 0x7f), 53 sig & 0x80 ? " | 0x80" : ""); 54 status &= ~W_STOPCODE(sig); 55 } 56 else if (WIFSIGNALED(status)) { 57 tprintf("[{WIFSIGNALED(s) && WTERMSIG(s) == %s%s}", 58 signame(WTERMSIG(status)), 59 WCOREDUMP(status) ? " && WCOREDUMP(s)" : ""); 60 status &= ~(W_EXITCODE(0, WTERMSIG(status)) | WCOREFLAG); 61 } 62 else if (WIFEXITED(status)) { 63 tprintf("[{WIFEXITED(s) && WEXITSTATUS(s) == %d}", 64 WEXITSTATUS(status)); 65 exited = 1; 66 status &= ~W_EXITCODE(WEXITSTATUS(status), 0); 67 } 68#ifdef WIFCONTINUED 69 else if (WIFCONTINUED(status)) { 70 tprints("[{WIFCONTINUED(s)}"); 71 status &= ~W_CONTINUED; 72 } 73#endif 74 else { 75 tprintf("[%#x]", status); 76 return 0; 77 } 78 79 if (status) { 80 unsigned int event = (unsigned int) status >> 16; 81 if (event) { 82 tprints(" | "); 83 printxval(ptrace_events, event, "PTRACE_EVENT_???"); 84 tprints(" << 16"); 85 status &= 0xffff; 86 } 87 if (status) 88 tprintf(" | %#x", status); 89 } 90 tprints("]"); 91 92 return exited; 93} 94 95static int 96printwaitn(struct tcb *tcp, int n, int bitness) 97{ 98 int status; 99 100 if (entering(tcp)) { 101 /* On Linux, kernel-side pid_t is typedef'ed to int 102 * on all arches. Also, glibc-2.8 truncates wait3 and wait4 103 * pid argument to int on 64bit arches, producing, 104 * for example, wait4(4294967295, ...) instead of -1 105 * in strace. We have to use int here, not long. 106 */ 107 int pid = tcp->u_arg[0]; 108 tprintf("%d, ", pid); 109 } else { 110 /* status */ 111 if (!tcp->u_arg[1]) 112 tprints("NULL"); 113 else if (syserror(tcp) || tcp->u_rval == 0) 114 tprintf("%#lx", tcp->u_arg[1]); 115 else if (umove(tcp, tcp->u_arg[1], &status) < 0) 116 tprints("[?]"); 117 else 118 printstatus(status); 119 /* options */ 120 tprints(", "); 121 printflags(wait4_options, tcp->u_arg[2], "W???"); 122 if (n == 4) { 123 tprints(", "); 124 /* usage */ 125 if (!tcp->u_arg[3]) 126 tprints("NULL"); 127 else if (tcp->u_rval > 0) { 128#ifdef ALPHA 129 if (bitness) 130 printrusage32(tcp, tcp->u_arg[3]); 131 else 132#endif 133 printrusage(tcp, tcp->u_arg[3]); 134 } 135 else 136 tprintf("%#lx", tcp->u_arg[3]); 137 } 138 } 139 return 0; 140} 141 142SYS_FUNC(waitpid) 143{ 144 return printwaitn(tcp, 3, 0); 145} 146 147SYS_FUNC(wait4) 148{ 149 return printwaitn(tcp, 4, 0); 150} 151 152#ifdef ALPHA 153SYS_FUNC(osf_wait4) 154{ 155 return printwaitn(tcp, 4, 1); 156} 157#endif 158 159#include "xlat/waitid_types.h" 160 161SYS_FUNC(waitid) 162{ 163 if (entering(tcp)) { 164 printxval(waitid_types, tcp->u_arg[0], "P_???"); 165 tprintf(", %ld, ", tcp->u_arg[1]); 166 } 167 else { 168 /* siginfo */ 169 printsiginfo_at(tcp, tcp->u_arg[2]); 170 /* options */ 171 tprints(", "); 172 printflags(wait4_options, tcp->u_arg[3], "W???"); 173 if (tcp->s_ent->nargs > 4) { 174 /* usage */ 175 tprints(", "); 176 if (!tcp->u_arg[4]) 177 tprints("NULL"); 178 else if (tcp->u_error) 179 tprintf("%#lx", tcp->u_arg[4]); 180 else 181 printrusage(tcp, tcp->u_arg[4]); 182 } 183 } 184 return 0; 185} 186