2014-12-11 22:25:02 +03:00
# include "defs.h"
# include <sys/wait.h>
# include "xlat/wait4_options.h"
# if !defined WCOREFLAG && defined WCOREFLG
# define WCOREFLAG WCOREFLG
# endif
# ifndef WCOREFLAG
# define WCOREFLAG 0x80
# endif
# ifndef WCOREDUMP
# define WCOREDUMP(status) ((status) & 0200)
# endif
# ifndef W_STOPCODE
# define W_STOPCODE(sig) ((sig) << 8 | 0x7f)
# endif
# ifndef W_EXITCODE
# define W_EXITCODE(ret, sig) ((ret) << 8 | (sig))
# endif
2015-02-13 01:43:02 +03:00
# ifndef W_CONTINUED
# define W_CONTINUED 0xffff
# endif
2015-02-13 03:26:38 +03:00
# include "ptrace.h"
2015-02-13 01:43:02 +03:00
# include "xlat/ptrace_events.h"
2014-12-11 22:25:02 +03:00
static int
printstatus ( int status )
{
int exited = 0 ;
/*
* Here is a tricky presentation problem . This solution
* is still not entirely satisfactory but since there
* are no wait status constructors it will have to do .
*/
if ( WIFSTOPPED ( status ) ) {
2015-02-13 01:43:02 +03:00
int sig = WSTOPSIG ( status ) ;
tprintf ( " [{WIFSTOPPED(s) && WSTOPSIG(s) == %s%s} " ,
signame ( sig & 0x7f ) ,
sig & 0x80 ? " | 0x80 " : " " ) ;
status & = ~ W_STOPCODE ( sig ) ;
2014-12-11 22:25:02 +03:00
}
else if ( WIFSIGNALED ( status ) ) {
tprintf ( " [{WIFSIGNALED(s) && WTERMSIG(s) == %s%s} " ,
signame ( WTERMSIG ( status ) ) ,
WCOREDUMP ( status ) ? " && WCOREDUMP(s) " : " " ) ;
status & = ~ ( W_EXITCODE ( 0 , WTERMSIG ( status ) ) | WCOREFLAG ) ;
}
else if ( WIFEXITED ( status ) ) {
tprintf ( " [{WIFEXITED(s) && WEXITSTATUS(s) == %d} " ,
WEXITSTATUS ( status ) ) ;
exited = 1 ;
status & = ~ W_EXITCODE ( WEXITSTATUS ( status ) , 0 ) ;
}
2015-02-13 01:43:02 +03:00
# ifdef WIFCONTINUED
else if ( WIFCONTINUED ( status ) ) {
tprints ( " [{WIFCONTINUED(s)} " ) ;
status & = ~ W_CONTINUED ;
}
# endif
2014-12-11 22:25:02 +03:00
else {
tprintf ( " [%#x] " , status ) ;
return 0 ;
}
2015-02-13 01:43:02 +03:00
if ( status ) {
unsigned int event = ( unsigned int ) status > > 16 ;
if ( event ) {
tprints ( " | " ) ;
printxval ( ptrace_events , event , " PTRACE_EVENT_??? " ) ;
tprints ( " << 16 " ) ;
status & = 0xffff ;
}
if ( status )
tprintf ( " | %#x " , status ) ;
}
tprints ( " ] " ) ;
2014-12-11 22:25:02 +03:00
return exited ;
}
static int
printwaitn ( struct tcb * tcp , int n , int bitness )
{
int status ;
if ( entering ( tcp ) ) {
/* On Linux, kernel-side pid_t is typedef'ed to int
* on all arches . Also , glibc - 2.8 truncates wait3 and wait4
* pid argument to int on 64 bit arches , producing ,
* for example , wait4 ( 4294967295 , . . . ) instead of - 1
* in strace . We have to use int here , not long .
*/
int pid = tcp - > u_arg [ 0 ] ;
tprintf ( " %d, " , pid ) ;
} else {
/* status */
2015-07-15 03:36:20 +03:00
if ( tcp - > u_rval = = 0 )
printaddr ( tcp - > u_arg [ 1 ] ) ;
else if ( ! umove_or_printaddr ( tcp , tcp - > u_arg [ 1 ] , & status ) )
2014-12-11 22:25:02 +03:00
printstatus ( status ) ;
/* options */
tprints ( " , " ) ;
printflags ( wait4_options , tcp - > u_arg [ 2 ] , " W??? " ) ;
if ( n = = 4 ) {
tprints ( " , " ) ;
/* usage */
2015-07-15 03:36:20 +03:00
if ( tcp - > u_rval > 0 ) {
2014-12-11 22:25:02 +03:00
# ifdef ALPHA
if ( bitness )
printrusage32 ( tcp , tcp - > u_arg [ 3 ] ) ;
else
# endif
printrusage ( tcp , tcp - > u_arg [ 3 ] ) ;
}
else
2015-07-15 03:36:20 +03:00
printaddr ( tcp - > u_arg [ 3 ] ) ;
2014-12-11 22:25:02 +03:00
}
}
return 0 ;
}
2015-04-07 04:36:50 +03:00
SYS_FUNC ( waitpid )
2014-12-11 22:25:02 +03:00
{
return printwaitn ( tcp , 3 , 0 ) ;
}
2015-04-07 04:36:50 +03:00
SYS_FUNC ( wait4 )
2014-12-11 22:25:02 +03:00
{
return printwaitn ( tcp , 4 , 0 ) ;
}
# ifdef ALPHA
2015-04-07 04:36:50 +03:00
SYS_FUNC ( osf_wait4 )
2014-12-11 22:25:02 +03:00
{
return printwaitn ( tcp , 4 , 1 ) ;
}
# endif
# include "xlat/waitid_types.h"
2015-04-07 04:36:50 +03:00
SYS_FUNC ( waitid )
2014-12-11 22:25:02 +03:00
{
if ( entering ( tcp ) ) {
printxval ( waitid_types , tcp - > u_arg [ 0 ] , " P_??? " ) ;
tprintf ( " , %ld, " , tcp - > u_arg [ 1 ] ) ;
2015-07-15 03:36:20 +03:00
} else {
2014-12-11 22:25:02 +03:00
/* siginfo */
printsiginfo_at ( tcp , tcp - > u_arg [ 2 ] ) ;
/* options */
tprints ( " , " ) ;
printflags ( wait4_options , tcp - > u_arg [ 3 ] , " W??? " ) ;
if ( tcp - > s_ent - > nargs > 4 ) {
/* usage */
tprints ( " , " ) ;
2015-07-15 03:36:20 +03:00
printrusage ( tcp , tcp - > u_arg [ 4 ] ) ;
2014-12-11 22:25:02 +03:00
}
}
return 0 ;
}