1999-02-19 03:21:36 +03:00
/*
* Copyright ( c ) 1991 , 1992 Paul Kranenburg < pk @ cs . few . eur . nl >
* Copyright ( c ) 1993 Branko Lankester < branko @ hacktic . nl >
* Copyright ( c ) 1993 , 1994 , 1995 , 1996 Rick Sladkey < jrs @ world . std . com >
1999-12-23 17:20:14 +03:00
* Copyright ( c ) 1996 - 1999 Wichert Akkerman < wichert @ cistron . nl >
* Copyright ( c ) 1999 IBM Deutschland Entwicklung GmbH , IBM Corporation
* Linux for s390 port by D . J . Barrow
* < barrow_dj @ mail . yahoo . com , djbarrow @ de . ibm . com >
1999-02-19 03:21:36 +03:00
* All rights reserved .
*
* Redistribution and use in source and binary forms , with or without
* modification , are permitted provided that the following conditions
* are met :
* 1. Redistributions of source code must retain the above copyright
* notice , this list of conditions and the following disclaimer .
* 2. Redistributions in binary form must reproduce the above copyright
* notice , this list of conditions and the following disclaimer in the
* documentation and / or other materials provided with the distribution .
* 3. The name of the author may not be used to endorse or promote products
* derived from this software without specific prior written permission .
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ` ` AS IS ' ' AND ANY EXPRESS OR
* IMPLIED WARRANTIES , INCLUDING , BUT NOT LIMITED TO , THE IMPLIED WARRANTIES
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED .
* IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT , INDIRECT ,
* INCIDENTAL , SPECIAL , EXEMPLARY , OR CONSEQUENTIAL DAMAGES ( INCLUDING , BUT
* NOT LIMITED TO , PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES ; LOSS OF USE ,
* DATA , OR PROFITS ; OR BUSINESS INTERRUPTION ) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY , WHETHER IN CONTRACT , STRICT LIABILITY , OR TORT
* ( INCLUDING NEGLIGENCE OR OTHERWISE ) ARISING IN ANY WAY OUT OF THE USE OF
* THIS SOFTWARE , EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE .
*
* $ Id $
*/
# include "defs.h"
# include <signal.h>
# include <sys/user.h>
# include <fcntl.h>
# ifdef SVR4
# include <sys/ucontext.h>
# endif /* SVR4 */
1999-07-13 19:45:02 +04:00
# ifdef HAVE_SYS_REG_H
# include <sys / reg.h>
1999-10-06 17:06:34 +04:00
# ifndef PTRACE_PEEKUSR
1999-07-13 19:45:02 +04:00
# define PTRACE_PEEKUSR PTRACE_PEEKUSER
1999-10-06 17:06:34 +04:00
# endif
# ifndef PTRACE_POKEUSR
1999-07-13 19:45:02 +04:00
# define PTRACE_POKEUSR PTRACE_POKEUSER
1999-05-09 04:29:58 +04:00
# endif
2000-02-20 02:59:03 +03:00
# elif defined(HAVE_LINUX_PTRACE_H)
# undef PTRACE_SYSCALL
# include <linux/ptrace.h>
1999-10-06 17:06:34 +04:00
# endif
1999-07-13 19:45:02 +04:00
2000-02-20 02:59:03 +03:00
1999-07-13 19:45:02 +04:00
# ifdef LINUX
2000-02-04 00:58:30 +03:00
# ifdef IA64
# include <asm / ptrace_offsets.h>
# endif /* !IA64 */
2001-03-29 00:29:17 +04:00
# if HAVE_ASM_REG_H
2003-01-30 23:15:23 +03:00
# ifdef SPARC
2001-03-29 00:29:17 +04:00
# define fpq kernel_fpq
# define fq kernel_fq
# define fpu kernel_fpu
2003-01-30 23:15:23 +03:00
# endif
# include <asm / reg.h>
# ifdef SPARC
2001-03-29 00:29:17 +04:00
# undef fpq
# undef fq
2002-12-17 08:10:37 +03:00
# undef fpu
2003-01-30 23:15:23 +03:00
# endif
2001-03-29 00:29:17 +04:00
# endif /* HAVE_ASM_REG_H */
2003-01-30 23:15:23 +03:00
2001-03-29 00:29:17 +04:00
# ifdef SPARC
1999-02-19 03:21:36 +03:00
typedef struct {
1999-08-30 03:15:07 +04:00
struct regs si_regs ;
1999-02-19 03:21:36 +03:00
int si_mask ;
} m_siginfo_t ;
2003-01-30 23:15:23 +03:00
# elif defined HAVE_ASM_SIGCONTEXT_H
# if !defined(IA64) && !defined(X86_64)
2001-03-29 00:29:17 +04:00
# include <asm/sigcontext.h>
2003-01-30 23:15:23 +03:00
# endif /* !IA64 && !X86_64 */
1999-02-19 03:21:36 +03:00
# else /* !HAVE_ASM_SIGCONTEXT_H */
# ifdef I386
struct sigcontext_struct {
unsigned short gs , __gsh ;
unsigned short fs , __fsh ;
unsigned short es , __esh ;
unsigned short ds , __dsh ;
unsigned long edi ;
unsigned long esi ;
unsigned long ebp ;
unsigned long esp ;
unsigned long ebx ;
unsigned long edx ;
unsigned long ecx ;
unsigned long eax ;
unsigned long trapno ;
unsigned long err ;
unsigned long eip ;
unsigned short cs , __csh ;
unsigned long eflags ;
unsigned long esp_at_signal ;
unsigned short ss , __ssh ;
unsigned long i387 ;
unsigned long oldmask ;
unsigned long cr2 ;
} ;
# else /* !I386 */
# ifdef M68K
1999-05-09 04:29:58 +04:00
struct sigcontext
1999-02-19 03:21:36 +03:00
{
unsigned long sc_mask ;
unsigned long sc_usp ;
unsigned long sc_d0 ;
unsigned long sc_d1 ;
unsigned long sc_a0 ;
unsigned long sc_a1 ;
unsigned short sc_sr ;
unsigned long sc_pc ;
unsigned short sc_formatvec ;
} ;
# endif /* M68K */
# endif /* !I386 */
# endif /* !HAVE_ASM_SIGCONTEXT_H */
# ifndef NSIG
# define NSIG 32
# endif
# ifdef ARM
# undef NSIG
# define NSIG 32
# endif
# endif /* LINUX */
char * signalent0 [ ] = {
# include "signalent.h"
} ;
int nsignals0 = sizeof signalent0 / sizeof signalent0 [ 0 ] ;
# if SUPPORTED_PERSONALITIES >= 2
char * signalent1 [ ] = {
# include "signalent1.h"
} ;
int nsignals1 = sizeof signalent1 / sizeof signalent1 [ 0 ] ;
# endif /* SUPPORTED_PERSONALITIES >= 2 */
# if SUPPORTED_PERSONALITIES >= 3
char * signalent2 [ ] = {
# include "signalent2.h"
} ;
int nsignals2 = sizeof signalent2 / sizeof signalent2 [ 0 ] ;
# endif /* SUPPORTED_PERSONALITIES >= 3 */
char * * signalent ;
int nsignals ;
2000-09-02 01:03:06 +04:00
# if defined(SUNOS4) || defined(FREEBSD)
1999-02-19 03:21:36 +03:00
static struct xlat sigvec_flags [ ] = {
{ SV_ONSTACK , " SV_ONSTACK " } ,
{ SV_INTERRUPT , " SV_INTERRUPT " } ,
{ SV_RESETHAND , " SV_RESETHAND " } ,
{ SA_NOCLDSTOP , " SA_NOCLDSTOP " } ,
{ 0 , NULL } ,
} ;
2000-09-02 01:03:06 +04:00
# endif /* SUNOS4 || FREEBSD */
1999-02-19 03:21:36 +03:00
# ifdef HAVE_SIGACTION
2002-12-16 02:58:41 +03:00
# if defined LINUX && defined I386
/* The libc headers do not define this constant since it should only be
used by the implementation . So wwe define it here . */
# ifndef SA_RESTORER
# define SA_RESTORER 0x04000000
# endif
# endif
1999-02-19 03:21:36 +03:00
static struct xlat sigact_flags [ ] = {
2000-04-11 02:22:31 +04:00
# ifdef SA_RESTORER
{ SA_RESTORER , " SA_RESTORER " } ,
# endif
1999-02-19 03:21:36 +03:00
# ifdef SA_STACK
{ SA_STACK , " SA_STACK " } ,
# endif
# ifdef SA_RESTART
{ SA_RESTART , " SA_RESTART " } ,
# endif
# ifdef SA_INTERRUPT
{ SA_INTERRUPT , " SA_INTERRUPT " } ,
# endif
# ifdef SA_NOMASK
{ SA_NOMASK , " SA_NOMASK " } ,
# endif
# ifdef SA_ONESHOT
{ SA_ONESHOT , " SA_ONESHOT " } ,
# endif
# ifdef SA_SIGINFO
{ SA_SIGINFO , " SA_SIGINFO " } ,
# endif
# ifdef SA_RESETHAND
{ SA_RESETHAND , " SA_RESETHAND " } ,
# endif
# ifdef SA_ONSTACK
{ SA_ONSTACK , " SA_ONSTACK " } ,
# endif
# ifdef SA_NODEFER
{ SA_NODEFER , " SA_NODEFER " } ,
# endif
# ifdef SA_NOCLDSTOP
{ SA_NOCLDSTOP , " SA_NOCLDSTOP " } ,
# endif
# ifdef SA_NOCLDWAIT
{ SA_NOCLDWAIT , " SA_NOCLDWAIT " } ,
# endif
# ifdef _SA_BSDCALL
{ _SA_BSDCALL , " _SA_BSDCALL " } ,
# endif
{ 0 , NULL } ,
} ;
static struct xlat sigprocmaskcmds [ ] = {
{ SIG_BLOCK , " SIG_BLOCK " } ,
{ SIG_UNBLOCK , " SIG_UNBLOCK " } ,
{ SIG_SETMASK , " SIG_SETMASK " } ,
# ifdef SIG_SETMASK32
{ SIG_SETMASK32 , " SIG_SETMASK32 " } ,
# endif
{ 0 , NULL } ,
} ;
# endif /* HAVE_SIGACTION */
1999-03-30 03:23:13 +04:00
/* Anonymous realtime signals. */
/* Under glibc 2.1, SIGRTMIN et al are functions, but __SIGRTMIN is a
constant . This is what we want . Otherwise , just use SIGRTMIN . */
# ifdef SIGRTMIN
# ifndef __SIGRTMIN
# define __SIGRTMIN SIGRTMIN
# define __SIGRTMAX SIGRTMAX /* likewise */
# endif
# endif
char *
signame ( sig )
int sig ;
{
static char buf [ 30 ] ;
if ( sig < nsignals ) {
return signalent [ sig ] ;
# ifdef SIGRTMIN
1999-03-30 04:16:41 +04:00
} else if ( sig > = __SIGRTMIN & & sig < = __SIGRTMAX ) {
1999-05-09 04:29:58 +04:00
sprintf ( buf , " SIGRT_%ld " , ( long ) ( sig - __SIGRTMIN ) ) ;
1999-03-30 03:23:13 +04:00
return buf ;
# endif /* SIGRTMIN */
} else {
sprintf ( buf , " %d " , sig ) ;
return buf ;
}
}
1999-02-19 03:21:36 +03:00
1999-08-30 03:15:07 +04:00
# ifndef UNIXWARE
1999-04-06 05:19:39 +04:00
static void
long_to_sigset ( l , s )
long l ;
sigset_t * s ;
{
sigemptyset ( s ) ;
* ( long * ) s = l ;
}
1999-08-30 03:15:07 +04:00
# endif
1999-04-06 05:19:39 +04:00
static int
copy_sigset_len ( tcp , addr , s , len )
struct tcb * tcp ;
2000-02-04 00:58:30 +03:00
long addr ;
1999-04-06 05:19:39 +04:00
sigset_t * s ;
int len ;
{
if ( len > sizeof ( * s ) )
len = sizeof ( * s ) ;
sigemptyset ( s ) ;
if ( umoven ( tcp , addr , len , ( char * ) s ) < 0 )
return - 1 ;
return 0 ;
}
# ifdef LINUX
/* Original sigset is unsigned long */
# define copy_sigset(tcp, addr, s) copy_sigset_len(tcp, addr, s, sizeof(long))
# else
# define copy_sigset(tcp, addr, s) copy_sigset_len(tcp, addr, s, sizeof(sigset_t))
# endif
1999-02-19 03:21:36 +03:00
static char *
1999-04-06 05:19:39 +04:00
sprintsigmask ( s , mask , rt )
1999-02-19 03:21:36 +03:00
char * s ;
sigset_t * mask ;
1999-04-06 05:19:39 +04:00
int rt ; /* set might include realtime sigs */
1999-02-19 03:21:36 +03:00
{
int i , nsigs ;
1999-04-06 05:19:39 +04:00
int maxsigs ;
1999-02-19 03:21:36 +03:00
char * format ;
2002-12-17 08:10:37 +03:00
static char outstr [ 8 * sizeof ( sigset_t ) * 8 ] ;
1999-02-19 03:21:36 +03:00
strcpy ( outstr , s ) ;
s = outstr + strlen ( outstr ) ;
nsigs = 0 ;
1999-04-06 05:19:39 +04:00
maxsigs = nsignals ;
# ifdef __SIGRTMAX
if ( rt )
maxsigs = __SIGRTMAX ; /* instead */
# endif
for ( i = 1 ; i < maxsigs ; i + + ) {
1999-02-19 03:21:36 +03:00
if ( sigismember ( mask , i ) = = 1 )
nsigs + + ;
}
if ( nsigs > = nsignals * 2 / 3 ) {
* s + + = ' ~ ' ;
1999-04-06 05:19:39 +04:00
for ( i = 1 ; i < maxsigs ; i + + ) {
1999-02-19 03:21:36 +03:00
switch ( sigismember ( mask , i ) ) {
case 1 :
sigdelset ( mask , i ) ;
break ;
case 0 :
sigaddset ( mask , i ) ;
break ;
}
}
}
format = " %s " ;
* s + + = ' [ ' ;
1999-04-06 05:19:39 +04:00
for ( i = 1 ; i < maxsigs ; i + + ) {
1999-02-19 03:21:36 +03:00
if ( sigismember ( mask , i ) = = 1 ) {
2001-03-06 18:08:09 +03:00
/* real-time signals on solaris don't have
* signalent entries
*/
if ( i < nsignals ) {
sprintf ( s , format , signalent [ i ] + 3 ) ;
}
else {
char tsig [ 32 ] ;
sprintf ( tsig , " %u " , i ) ;
sprintf ( s , format , tsig ) ;
}
s + = strlen ( s ) ;
1999-02-19 03:21:36 +03:00
format = " %s " ;
}
}
* s + + = ' ] ' ;
* s = ' \0 ' ;
return outstr ;
}
static void
1999-04-06 05:19:39 +04:00
printsigmask ( mask , rt )
1999-02-19 03:21:36 +03:00
sigset_t * mask ;
1999-04-06 05:19:39 +04:00
int rt ;
1999-02-19 03:21:36 +03:00
{
1999-04-06 05:19:39 +04:00
tprintf ( " %s " , sprintsigmask ( " " , mask , rt ) ) ;
1999-02-19 03:21:36 +03:00
}
void
printsignal ( nr )
int nr ;
{
1999-03-30 03:23:13 +04:00
tprintf ( signame ( nr ) ) ;
1999-02-19 03:21:36 +03:00
}
2001-10-10 03:47:38 +04:00
# ifdef LINUX
2001-10-18 19:13:53 +04:00
# ifndef ILL_ILLOPC
# define ILL_ILLOPC 1 /* illegal opcode */
# define ILL_ILLOPN 2 /* illegal operand */
# define ILL_ILLADR 3 /* illegal addressing mode */
# define ILL_ILLTRP 4 /* illegal trap */
# define ILL_PRVOPC 5 /* privileged opcode */
# define ILL_PRVREG 6 /* privileged register */
# define ILL_COPROC 7 /* coprocessor error */
# define ILL_BADSTK 8 /* internal stack error */
# define FPE_INTDIV 1 /* integer divide by zero */
# define FPE_INTOVF 2 /* integer overflow */
# define FPE_FLTDIV 3 /* floating point divide by zero */
# define FPE_FLTOVF 4 /* floating point overflow */
# define FPE_FLTUND 5 /* floating point underflow */
# define FPE_FLTRES 6 /* floating point inexact result */
# define FPE_FLTINV 7 /* floating point invalid operation */
# define FPE_FLTSUB 8 /* subscript out of range */
# define SEGV_MAPERR 1 /* address not mapped to object */
# define SEGV_ACCERR 2 /* invalid permissions for mapped object */
# define BUS_ADRALN 1 /* invalid address alignment */
# define BUS_ADRERR 2 /* non-existant physical address */
# define BUS_OBJERR 3 /* object specific hardware error */
# define TRAP_BRKPT 1 /* process breakpoint */
# define TRAP_TRACE 2 /* process trace trap */
# define CLD_EXITED 1 /* child has exited */
# define CLD_KILLED 2 /* child was killed */
# define CLD_DUMPED 3 /* child terminated abnormally */
# define CLD_TRAPPED 4 /* traced child has trapped */
# define CLD_STOPPED 5 /* child has stopped */
# define CLD_CONTINUED 6 /* stopped child has continued */
# define POLL_IN 1 /* data input available */
# define POLL_OUT 2 /* output buffers available */
# define POLL_MSG 3 /* input message available */
# define POLL_ERR 4 /* i/o error */
# define POLL_PRI 5 /* high priority input available */
# define POLL_HUP 6 /* device disconnected */
# define SI_USER 0 /* sent by kill, sigsend, raise */
# define SI_QUEUE -1 /* sent by sigqueue */
# define SI_TIMER -2 /* sent by timer expiration */
# define SI_MESGQ -3 /* sent by real time mesq state change */
# define SI_ASYNCIO -4 /* sent by AIO completion */
2003-05-23 04:29:02 +04:00
# define SI_SIGIO -5 /* Sent by SIGIO */
# define SI_TKILL -6 /* Sent by tkill */
2001-10-18 19:13:53 +04:00
# endif
# if __GLIBC_MINOR__ < 1
/* Type for data associated with a signal. */
typedef union sigval
{
int sival_int ;
void * sival_ptr ;
} sigval_t ;
# define __SI_MAX_SIZE 128
# define __SI_PAD_SIZE ((__SI_MAX_SIZE / sizeof (int)) - 3)
typedef struct siginfo
{
int si_signo ; /* Signal number. */
int si_errno ; /* If non-zero, an errno value associated with
this signal , as defined in < errno . h > . */
int si_code ; /* Signal code. */
union
{
int _pad [ __SI_PAD_SIZE ] ;
/* kill(). */
struct
{
__pid_t si_pid ; /* Sending process ID. */
__uid_t si_uid ; /* Real user ID of sending process. */
} _kill ;
/* POSIX.1b timers. */
struct
{
unsigned int _timer1 ;
unsigned int _timer2 ;
} _timer ;
/* POSIX.1b signals. */
struct
{
__pid_t si_pid ; /* Sending process ID. */
__uid_t si_uid ; /* Real user ID of sending process. */
sigval_t si_sigval ; /* Signal value. */
} _rt ;
/* SIGCHLD. */
struct
{
__pid_t si_pid ; /* Which child. */
int si_status ; /* Exit value or signal. */
__clock_t si_utime ;
__clock_t si_stime ;
} _sigchld ;
/* SIGILL, SIGFPE, SIGSEGV, SIGBUS. */
struct
{
void * si_addr ; /* Faulting insn/memory ref. */
} _sigfault ;
/* SIGPOLL. */
struct
{
int si_band ; /* Band event for SIGPOLL. */
int si_fd ;
} _sigpoll ;
} _sifields ;
} siginfo_t ;
# define si_pid _sifields._kill.si_pid
# define si_uid _sifields._kill.si_uid
# define si_status _sifields._sigchld.si_status
# define si_utime _sifields._sigchld.si_utime
# define si_stime _sifields._sigchld.si_stime
# define si_value _sifields._rt.si_sigval
# define si_int _sifields._rt.si_sigval.sival_int
# define si_ptr _sifields._rt.si_sigval.sival_ptr
# define si_addr _sifields._sigfault.si_addr
# define si_band _sifields._sigpoll.si_band
# define si_fd _sifields._sigpoll.si_fd
# endif
# endif
# if defined (SVR4) || defined (LINUX)
static struct xlat siginfo_codes [ ] = {
# ifdef SI_NOINFO
{ SI_NOINFO , " SI_NOINFO " } ,
# endif
# ifdef SI_USER
{ SI_USER , " SI_USER " } ,
# endif
# ifdef SI_LWP
{ SI_LWP , " SI_LWP " } ,
# endif
# ifdef SI_QUEUE
{ SI_QUEUE , " SI_QUEUE " } ,
# endif
# ifdef SI_TIMER
{ SI_TIMER , " SI_TIMER " } ,
# endif
# ifdef SI_ASYNCIO
{ SI_ASYNCIO , " SI_ASYNCIO " } ,
# endif
# ifdef SI_MESGQ
{ SI_MESGQ , " SI_MESGQ " } ,
2003-05-23 04:29:02 +04:00
# endif
# ifdef SI_SIGIO
{ SI_SIGIO , " SI_SIGIO " } ,
# endif
# ifdef SI_TKILL
{ SI_TKILL , " SI_TKILL " } ,
2001-10-18 19:13:53 +04:00
# endif
{ 0 , NULL } ,
} ;
static struct xlat sigill_codes [ ] = {
{ ILL_ILLOPC , " ILL_ILLOPC " } ,
{ ILL_ILLOPN , " ILL_ILLOPN " } ,
{ ILL_ILLADR , " ILL_ILLADR " } ,
{ ILL_ILLTRP , " ILL_ILLTRP " } ,
{ ILL_PRVOPC , " ILL_PRVOPC " } ,
{ ILL_PRVREG , " ILL_PRVREG " } ,
{ ILL_COPROC , " ILL_COPROC " } ,
{ ILL_BADSTK , " ILL_BADSTK " } ,
{ 0 , NULL } ,
} ;
static struct xlat sigfpe_codes [ ] = {
{ FPE_INTDIV , " FPE_INTDIV " } ,
{ FPE_INTOVF , " FPE_INTOVF " } ,
{ FPE_FLTDIV , " FPE_FLTDIV " } ,
{ FPE_FLTOVF , " FPE_FLTOVF " } ,
{ FPE_FLTUND , " FPE_FLTUND " } ,
{ FPE_FLTRES , " FPE_FLTRES " } ,
{ FPE_FLTINV , " FPE_FLTINV " } ,
{ FPE_FLTSUB , " FPE_FLTSUB " } ,
{ 0 , NULL } ,
} ;
static struct xlat sigtrap_codes [ ] = {
{ TRAP_BRKPT , " TRAP_BRKPT " } ,
{ TRAP_TRACE , " TRAP_TRACE " } ,
{ 0 , NULL } ,
} ;
static struct xlat sigchld_codes [ ] = {
{ CLD_EXITED , " CLD_EXITED " } ,
{ CLD_KILLED , " CLD_KILLED " } ,
{ CLD_DUMPED , " CLD_DUMPED " } ,
{ CLD_TRAPPED , " CLD_TRAPPED " } ,
{ CLD_STOPPED , " CLD_STOPPED " } ,
{ CLD_CONTINUED , " CLD_CONTINUED " } ,
{ 0 , NULL } ,
} ;
static struct xlat sigpoll_codes [ ] = {
{ POLL_IN , " POLL_IN " } ,
{ POLL_OUT , " POLL_OUT " } ,
{ POLL_MSG , " POLL_MSG " } ,
{ POLL_ERR , " POLL_ERR " } ,
{ POLL_PRI , " POLL_PRI " } ,
{ POLL_HUP , " POLL_HUP " } ,
{ 0 , NULL } ,
} ;
static struct xlat sigprof_codes [ ] = {
# ifdef PROF_SIG
{ PROF_SIG , " PROF_SIG " } ,
# endif
{ 0 , NULL } ,
} ;
# ifdef SIGEMT
static struct xlat sigemt_codes [ ] = {
# ifdef EMT_TAGOVF
{ EMT_TAGOVF , " EMT_TAGOVF " } ,
# endif
{ 0 , NULL } ,
} ;
# endif
static struct xlat sigsegv_codes [ ] = {
{ SEGV_MAPERR , " SEGV_MAPERR " } ,
{ SEGV_ACCERR , " SEGV_ACCERR " } ,
{ 0 , NULL } ,
} ;
static struct xlat sigbus_codes [ ] = {
{ BUS_ADRALN , " BUS_ADRALN " } ,
{ BUS_ADRERR , " BUS_ADRERR " } ,
{ BUS_OBJERR , " BUS_OBJERR " } ,
{ 0 , NULL } ,
} ;
void
printsiginfo ( sip , verbose )
siginfo_t * sip ;
int verbose ;
{
char * code ;
if ( sip - > si_signo = = 0 ) {
tprintf ( " {} " ) ;
return ;
}
tprintf ( " {si_signo= " ) ;
printsignal ( sip - > si_signo ) ;
code = xlookup ( siginfo_codes , sip - > si_code ) ;
if ( ! code ) {
switch ( sip - > si_signo ) {
case SIGTRAP :
code = xlookup ( sigtrap_codes , sip - > si_code ) ;
break ;
case SIGCHLD :
code = xlookup ( sigchld_codes , sip - > si_code ) ;
break ;
case SIGPOLL :
code = xlookup ( sigpoll_codes , sip - > si_code ) ;
break ;
case SIGPROF :
code = xlookup ( sigprof_codes , sip - > si_code ) ;
break ;
case SIGILL :
code = xlookup ( sigill_codes , sip - > si_code ) ;
break ;
# ifdef SIGEMT
case SIGEMT :
code = xlookup ( sigemt_codes , sip - > si_code ) ;
break ;
# endif
case SIGFPE :
code = xlookup ( sigfpe_codes , sip - > si_code ) ;
break ;
case SIGSEGV :
code = xlookup ( sigsegv_codes , sip - > si_code ) ;
break ;
case SIGBUS :
code = xlookup ( sigbus_codes , sip - > si_code ) ;
break ;
}
}
if ( code )
tprintf ( " , si_code=%s " , code ) ;
else
tprintf ( " , si_code=%#x " , sip - > si_code ) ;
# ifdef SI_NOINFO
if ( sip - > si_code ! = SI_NOINFO )
# endif
{
if ( sip - > si_errno ) {
if ( sip - > si_errno < 0 | | sip - > si_errno > = nerrnos )
tprintf ( " , si_errno=%d " , sip - > si_errno ) ;
else
tprintf ( " , si_errno=%s " ,
errnoent [ sip - > si_errno ] ) ;
}
# ifdef SI_FROMUSER
if ( SI_FROMUSER ( sip ) ) {
tprintf ( " , si_pid=%ld, si_uid=%ld " ,
sip - > si_pid , sip - > si_uid ) ;
# ifdef SI_QUEUE
switch ( sip - > si_code ) {
case SI_QUEUE :
# ifdef SI_TIMER
case SI_TIMER :
# endif /* SI_QUEUE */
case SI_ASYNCIO :
# ifdef SI_MESGQ
case SI_MESGQ :
# endif /* SI_MESGQ */
tprintf ( " , si_value=%d " ,
sip - > si_value . sival_int ) ;
break ;
}
# endif /* SI_QUEUE */
}
else
# endif /* SI_FROMUSER */
{
switch ( sip - > si_signo ) {
case SIGCHLD :
tprintf ( " , si_pid=%ld, si_status= " ,
( long ) sip - > si_pid ) ;
if ( sip - > si_code = = CLD_EXITED )
tprintf ( " %d " , sip - > si_status ) ;
else
printsignal ( sip - > si_status ) ;
# if LINUX
if ( ! verbose )
tprintf ( " , ... " ) ;
else
tprintf ( " , si_utime=%lu, si_stime=%lu " ,
sip - > si_utime ,
sip - > si_stime ) ;
# endif
break ;
case SIGILL : case SIGFPE :
case SIGSEGV : case SIGBUS :
tprintf ( " , si_addr=%#lx " ,
( unsigned long ) sip - > si_addr ) ;
break ;
case SIGPOLL :
switch ( sip - > si_code ) {
case POLL_IN : case POLL_OUT : case POLL_MSG :
tprintf ( " , si_band=%ld " ,
( long ) sip - > si_band ) ;
break ;
}
break ;
# ifdef LINUX
default :
tprintf ( " , si_pid=%lu, si_uid=%lu, " ,
( unsigned long ) sip - > si_pid ,
( unsigned long ) sip - > si_uid ) ;
if ( ! verbose )
tprintf ( " ... " ) ;
else {
tprintf ( " si_value={int=%u, ptr=%#lx} " ,
sip - > si_int ,
( unsigned long ) sip - > si_ptr ) ;
}
# endif
2002-12-17 08:10:37 +03:00
2001-10-18 19:13:53 +04:00
}
}
}
tprintf ( " } " ) ;
}
# endif /* SVR4 || LINUX */
# ifdef LINUX
2001-10-10 03:47:38 +04:00
static void
parse_sigset_t ( const char * str , sigset_t * set )
{
unsigned int digit ;
int i ;
sigemptyset ( set ) ;
for ( i = _NSIG - 4 ; i > = 0 ; i - = 4 , + + str ) {
if ( * str > = ' a ' )
digit = ( * str - ' a ' ) + 10 ;
else
digit = * str - ' 0 ' ;
if ( digit & 1 )
sigaddset ( set , i + 1 ) ;
if ( digit & 2 )
sigaddset ( set , i + 2 ) ;
if ( digit & 4 )
sigaddset ( set , i + 3 ) ;
if ( digit & 8 )
sigaddset ( set , i + 4 ) ;
}
}
# endif
1999-02-19 03:21:36 +03:00
/*
* Check process TCP for the disposition of signal SIG .
* Return 1 if the process would somehow manage to survive signal SIG ,
* else return 0. This routine will never be called with SIGKILL .
*/
int
sigishandled ( tcp , sig )
struct tcb * tcp ;
int sig ;
{
# ifdef LINUX
int sfd ;
char sname [ 32 ] ;
2001-04-12 13:10:24 +04:00
char buf [ 2048 ] ;
1999-02-19 03:21:36 +03:00
char * s ;
int i ;
2001-10-10 03:47:38 +04:00
sigset_t ignored , caught ;
2001-04-12 13:10:24 +04:00
# endif
# ifdef SVR4
/*
* Since procfs doesn ' t interfere with wait I think it is safe
* to punt on this question . If not , the information is there .
*/
return 1 ;
# else /* !SVR4 */
switch ( sig ) {
case SIGCONT :
case SIGSTOP :
case SIGTSTP :
case SIGTTIN :
case SIGTTOU :
case SIGCHLD :
case SIGIO :
# if defined(SIGURG) && SIGURG != SIGIO
case SIGURG :
# endif
case SIGWINCH :
/* Gloria Gaynor says ... */
return 1 ;
default :
break ;
}
# endif /* !SVR4 */
# ifdef LINUX
1999-02-19 03:21:36 +03:00
/* This is incredibly costly but it's worth it. */
2001-04-12 13:10:24 +04:00
/* NOTE: LinuxThreads internally uses SIGRTMIN, SIGRTMIN + 1 and
SIGRTMIN + 2 , so we can ' t use the obsolete / proc / % d / stat which
doesn ' t handle real - time signals ) . */
sprintf ( sname , " /proc/%d/status " , tcp - > pid ) ;
1999-02-19 03:21:36 +03:00
if ( ( sfd = open ( sname , O_RDONLY ) ) = = - 1 ) {
perror ( sname ) ;
return 1 ;
}
2001-04-12 13:10:24 +04:00
i = read ( sfd , buf , sizeof ( buf ) ) ;
1999-02-19 03:21:36 +03:00
buf [ i ] = ' \0 ' ;
close ( sfd ) ;
/*
2001-04-12 13:10:24 +04:00
* Skip the extraneous fields . We need to skip
1999-02-19 03:21:36 +03:00
* command name has any spaces in it . So be it .
*/
2001-10-10 03:47:38 +04:00
s = strstr ( buf , " SigIgn: \t " ) ;
2001-04-12 13:10:24 +04:00
if ( ! s )
{
fprintf ( stderr , " /proc/pid/status format error \n " ) ;
1999-02-19 03:21:36 +03:00
return 1 ;
}
2001-10-10 03:47:38 +04:00
parse_sigset_t ( s + 8 , & ignored ) ;
2001-04-12 13:10:24 +04:00
2001-10-10 03:47:38 +04:00
s = strstr ( buf , " SigCgt: \t " ) ;
if ( ! s )
{
fprintf ( stderr , " /proc/pid/status format error \n " ) ;
return 1 ;
}
parse_sigset_t ( s + 8 , & caught ) ;
2001-04-12 13:10:24 +04:00
1999-02-19 03:21:36 +03:00
# ifdef DEBUG
2001-10-10 03:47:38 +04:00
fprintf ( stderr , " sigs: %016qx %016qx (sig=%d) \n " ,
* ( long long * ) & ignored , * ( long long * ) & caught , sig ) ;
1999-02-19 03:21:36 +03:00
# endif
2001-10-10 03:47:38 +04:00
if ( sigismember ( & ignored , sig ) | | sigismember ( & caught , sig ) )
1999-02-19 03:21:36 +03:00
return 1 ;
# endif /* LINUX */
# ifdef SUNOS4
void ( * u_signal ) ( ) ;
if ( upeek ( tcp - > pid , uoff ( u_signal [ 0 ] ) + sig * sizeof ( u_signal ) ,
( long * ) & u_signal ) < 0 ) {
return 0 ;
}
if ( u_signal ! = SIG_DFL )
return 1 ;
# endif /* SUNOS4 */
return 0 ;
}
2000-09-02 01:03:06 +04:00
# if defined(SUNOS4) || defined(FREEBSD)
1999-02-19 03:21:36 +03:00
int
sys_sigvec ( tcp )
struct tcb * tcp ;
{
struct sigvec sv ;
long addr ;
if ( entering ( tcp ) ) {
printsignal ( tcp - > u_arg [ 0 ] ) ;
tprintf ( " , " ) ;
addr = tcp - > u_arg [ 1 ] ;
} else {
addr = tcp - > u_arg [ 2 ] ;
}
if ( addr = = 0 )
tprintf ( " NULL " ) ;
else if ( ! verbose ( tcp ) )
tprintf ( " %#lx " , addr ) ;
else if ( umove ( tcp , addr , & sv ) < 0 )
tprintf ( " {...} " ) ;
else {
switch ( ( int ) sv . sv_handler ) {
case ( int ) SIG_ERR :
tprintf ( " {SIG_ERR} " ) ;
break ;
case ( int ) SIG_DFL :
tprintf ( " {SIG_DFL} " ) ;
break ;
case ( int ) SIG_IGN :
if ( tcp - > u_arg [ 0 ] = = SIGTRAP ) {
tcp - > flags | = TCB_SIGTRAPPED ;
kill ( tcp - > pid , SIGSTOP ) ;
}
tprintf ( " {SIG_IGN} " ) ;
break ;
case ( int ) SIG_HOLD :
if ( tcp - > u_arg [ 0 ] = = SIGTRAP ) {
tcp - > flags | = TCB_SIGTRAPPED ;
kill ( tcp - > pid , SIGSTOP ) ;
}
tprintf ( " SIG_HOLD " ) ;
break ;
default :
if ( tcp - > u_arg [ 0 ] = = SIGTRAP ) {
tcp - > flags | = TCB_SIGTRAPPED ;
kill ( tcp - > pid , SIGSTOP ) ;
}
tprintf ( " {%#lx, " , ( unsigned long ) sv . sv_handler ) ;
1999-04-06 05:19:39 +04:00
printsigmask ( & sv . sv_mask , 0 ) ;
1999-02-19 03:21:36 +03:00
tprintf ( " , " ) ;
if ( ! printflags ( sigvec_flags , sv . sv_flags ) )
tprintf ( " 0 " ) ;
tprintf ( " } " ) ;
}
}
if ( entering ( tcp ) )
tprintf ( " , " ) ;
return 0 ;
}
int
sys_sigpause ( tcp )
struct tcb * tcp ;
{
if ( entering ( tcp ) ) { /* WTA: UD had a bug here: he forgot the braces */
1999-04-06 05:19:39 +04:00
sigset_t sigm ;
long_to_sigset ( tcp - > u_arg [ 0 ] , & sigm ) ;
printsigmask ( & sigm , 0 ) ;
1999-02-19 03:21:36 +03:00
}
return 0 ;
}
int
sys_sigstack ( tcp )
struct tcb * tcp ;
{
struct sigstack ss ;
long addr ;
if ( entering ( tcp ) )
addr = tcp - > u_arg [ 0 ] ;
else
addr = tcp - > u_arg [ 1 ] ;
if ( addr = = 0 )
tprintf ( " NULL " ) ;
else if ( umove ( tcp , addr , & ss ) < 0 )
tprintf ( " %#lx " , addr ) ;
else {
tprintf ( " {ss_sp %#lx " , ( unsigned long ) ss . ss_sp ) ;
tprintf ( " ss_onstack %s} " , ss . ss_onstack ? " YES " : " NO " ) ;
}
if ( entering ( tcp ) )
tprintf ( " , " ) ;
return 0 ;
}
int
sys_sigcleanup ( tcp )
struct tcb * tcp ;
{
return 0 ;
}
2000-09-02 01:03:06 +04:00
# endif /* SUNOS4 || FREEBSD */
1999-02-19 03:21:36 +03:00
# ifndef SVR4
int
sys_sigsetmask ( tcp )
struct tcb * tcp ;
{
if ( entering ( tcp ) ) {
sigset_t sigm ;
1999-04-06 05:19:39 +04:00
long_to_sigset ( tcp - > u_arg [ 0 ] , & sigm ) ;
printsigmask ( & sigm , 0 ) ;
2000-09-02 01:03:06 +04:00
# ifndef USE_PROCFS
1999-02-19 03:21:36 +03:00
if ( ( tcp - > u_arg [ 0 ] & sigmask ( SIGTRAP ) ) ) {
/* Mark attempt to block SIGTRAP */
tcp - > flags | = TCB_SIGTRAPPED ;
/* Send unblockable signal */
kill ( tcp - > pid , SIGSTOP ) ;
}
2002-12-17 08:10:37 +03:00
# endif /* !USE_PROCFS */
1999-02-19 03:21:36 +03:00
}
else if ( ! syserror ( tcp ) ) {
sigset_t sigm ;
1999-04-06 05:19:39 +04:00
long_to_sigset ( tcp - > u_rval , & sigm ) ;
tcp - > auxstr = sprintsigmask ( " old mask " , & sigm , 0 ) ;
1999-02-19 03:21:36 +03:00
return RVAL_HEX | RVAL_STR ;
}
return 0 ;
}
int
sys_sigblock ( tcp )
struct tcb * tcp ;
{
return sys_sigsetmask ( tcp ) ;
}
# endif /* !SVR4 */
# ifdef HAVE_SIGACTION
# ifdef LINUX
struct old_sigaction {
__sighandler_t __sa_handler ;
unsigned long sa_mask ;
unsigned long sa_flags ;
void ( * sa_restorer ) ( void ) ;
} ;
1999-05-09 04:29:58 +04:00
# define SA_HANDLER __sa_handler
# endif /* LINUX */
2002-12-17 08:10:37 +03:00
# ifndef SA_HANDLER
# define SA_HANDLER sa_handler
1999-02-19 03:21:36 +03:00
# endif
int
sys_sigaction ( tcp )
struct tcb * tcp ;
{
long addr ;
1999-04-06 05:19:39 +04:00
# ifdef LINUX
2001-03-06 12:25:46 +03:00
sigset_t sigset ;
1999-02-19 03:21:36 +03:00
struct old_sigaction sa ;
# else
struct sigaction sa ;
# endif
if ( entering ( tcp ) ) {
printsignal ( tcp - > u_arg [ 0 ] ) ;
tprintf ( " , " ) ;
addr = tcp - > u_arg [ 1 ] ;
} else
addr = tcp - > u_arg [ 2 ] ;
if ( addr = = 0 )
tprintf ( " NULL " ) ;
else if ( ! verbose ( tcp ) )
tprintf ( " %#lx " , addr ) ;
else if ( umove ( tcp , addr , & sa ) < 0 )
tprintf ( " {...} " ) ;
else {
1999-05-09 04:29:58 +04:00
switch ( ( long ) sa . SA_HANDLER ) {
1999-02-19 03:21:36 +03:00
case ( long ) SIG_ERR :
tprintf ( " {SIG_ERR} " ) ;
break ;
case ( long ) SIG_DFL :
tprintf ( " {SIG_DFL} " ) ;
break ;
case ( long ) SIG_IGN :
2000-09-02 01:03:06 +04:00
# ifndef USE_PROCFS
1999-02-19 03:21:36 +03:00
if ( tcp - > u_arg [ 0 ] = = SIGTRAP ) {
tcp - > flags | = TCB_SIGTRAPPED ;
kill ( tcp - > pid , SIGSTOP ) ;
}
2000-09-02 01:03:06 +04:00
# endif /* !USE_PROCFS */
1999-02-19 03:21:36 +03:00
tprintf ( " {SIG_IGN} " ) ;
break ;
default :
2000-09-02 01:03:06 +04:00
# ifndef USE_PROCFS
1999-02-19 03:21:36 +03:00
if ( tcp - > u_arg [ 0 ] = = SIGTRAP ) {
tcp - > flags | = TCB_SIGTRAPPED ;
kill ( tcp - > pid , SIGSTOP ) ;
}
2000-09-02 01:03:06 +04:00
# endif /* !USE_PROCFS */
1999-05-09 04:29:58 +04:00
tprintf ( " {%#lx, " , ( long ) sa . SA_HANDLER ) ;
1999-11-26 12:55:42 +03:00
# ifndef LINUX
printsigmask ( & sa . sa_mask , 0 ) ;
# else
1999-04-06 05:19:39 +04:00
long_to_sigset ( sa . sa_mask , & sigset ) ;
printsigmask ( & sigset , 0 ) ;
1999-11-26 12:55:42 +03:00
# endif
1999-02-19 03:21:36 +03:00
tprintf ( " , " ) ;
if ( ! printflags ( sigact_flags , sa . sa_flags ) )
tprintf ( " 0 " ) ;
2002-12-16 02:58:41 +03:00
# ifdef SA_RESTORER
if ( sa . sa_flags & SA_RESTORER )
tprintf ( " , %p " , sa . sa_restorer ) ;
# endif
1999-02-19 03:21:36 +03:00
tprintf ( " } " ) ;
}
}
if ( entering ( tcp ) )
tprintf ( " , " ) ;
# ifdef LINUX
else
tprintf ( " , %#lx " , ( unsigned long ) sa . sa_restorer ) ;
# endif
return 0 ;
}
int
sys_signal ( tcp )
struct tcb * tcp ;
{
if ( entering ( tcp ) ) {
printsignal ( tcp - > u_arg [ 0 ] ) ;
2000-08-10 06:14:04 +04:00
tprintf ( " , " ) ;
1999-02-19 03:21:36 +03:00
switch ( tcp - > u_arg [ 1 ] ) {
case ( int ) SIG_ERR :
tprintf ( " SIG_ERR " ) ;
break ;
case ( int ) SIG_DFL :
tprintf ( " SIG_DFL " ) ;
break ;
case ( int ) SIG_IGN :
2000-09-02 01:03:06 +04:00
# ifndef USE_PROCFS
1999-02-19 03:21:36 +03:00
if ( tcp - > u_arg [ 0 ] = = SIGTRAP ) {
tcp - > flags | = TCB_SIGTRAPPED ;
kill ( tcp - > pid , SIGSTOP ) ;
}
2000-09-02 01:03:06 +04:00
# endif /* !USE_PROCFS */
1999-02-19 03:21:36 +03:00
tprintf ( " SIG_IGN " ) ;
break ;
default :
2000-09-02 01:03:06 +04:00
# ifndef USE_PROCFS
1999-02-19 03:21:36 +03:00
if ( tcp - > u_arg [ 0 ] = = SIGTRAP ) {
tcp - > flags | = TCB_SIGTRAPPED ;
kill ( tcp - > pid , SIGSTOP ) ;
}
2000-09-02 01:03:06 +04:00
# endif /* !USE_PROCFS */
1999-02-19 03:21:36 +03:00
tprintf ( " %#lx " , tcp - > u_arg [ 1 ] ) ;
}
2000-08-10 06:14:04 +04:00
return 0 ;
}
else {
switch ( tcp - > u_rval ) {
case ( int ) SIG_ERR :
tcp - > auxstr = " SIG_ERR " ; break ;
case ( int ) SIG_DFL :
tcp - > auxstr = " SIG_DFL " ; break ;
case ( int ) SIG_IGN :
tcp - > auxstr = " SIG_IGN " ; break ;
default :
tcp - > auxstr = NULL ;
}
return RVAL_HEX | RVAL_STR ;
}
}
int
sys_sighold ( tcp )
struct tcb * tcp ;
{
if ( entering ( tcp ) ) {
printsignal ( tcp - > u_arg [ 0 ] ) ;
1999-02-19 03:21:36 +03:00
}
return 0 ;
}
# endif /* HAVE_SIGACTION */
# ifdef LINUX
int
sys_sigreturn ( tcp )
struct tcb * tcp ;
{
2002-10-07 18:31:00 +04:00
# if defined(S390) || defined(S390X)
1999-12-23 17:20:14 +03:00
long usp ;
struct sigcontext_struct sc ;
if ( entering ( tcp ) ) {
tcp - > u_arg [ 0 ] = 0 ;
if ( upeek ( tcp - > pid , PT_GPR15 , & usp ) < 0 )
return 0 ;
if ( umove ( tcp , usp + __SIGNAL_FRAMESIZE , & sc ) < 0 )
return 0 ;
tcp - > u_arg [ 0 ] = 1 ;
memcpy ( & tcp - > u_arg [ 1 ] , & sc . oldmask [ 0 ] , sizeof ( sigset_t ) ) ;
} else {
tcp - > u_rval = tcp - > u_error = 0 ;
if ( tcp - > u_arg [ 0 ] = = 0 )
return 0 ;
2002-10-07 18:31:00 +04:00
tcp - > auxstr = sprintsigmask ( " mask now " , ( sigset_t * ) & tcp - > u_arg [ 1 ] , 0 ) ;
1999-12-23 17:20:14 +03:00
return RVAL_NONE | RVAL_STR ;
}
return 0 ;
# else
1999-02-19 03:21:36 +03:00
# ifdef I386
long esp ;
struct sigcontext_struct sc ;
if ( entering ( tcp ) ) {
tcp - > u_arg [ 0 ] = 0 ;
if ( upeek ( tcp - > pid , 4 * UESP , & esp ) < 0 )
return 0 ;
if ( umove ( tcp , esp , & sc ) < 0 )
return 0 ;
tcp - > u_arg [ 0 ] = 1 ;
tcp - > u_arg [ 1 ] = sc . oldmask ;
}
else {
sigset_t sigm ;
1999-04-06 05:19:39 +04:00
long_to_sigset ( tcp - > u_arg [ 1 ] , & sigm ) ;
1999-02-19 03:21:36 +03:00
tcp - > u_rval = tcp - > u_error = 0 ;
if ( tcp - > u_arg [ 0 ] = = 0 )
return 0 ;
1999-04-06 05:19:39 +04:00
tcp - > auxstr = sprintsigmask ( " mask now " , & sigm , 0 ) ;
1999-02-19 03:21:36 +03:00
return RVAL_NONE | RVAL_STR ;
}
return 0 ;
# else /* !I386 */
2000-02-04 00:58:30 +03:00
# ifdef IA64
struct sigcontext sc ;
long sp ;
if ( entering ( tcp ) ) {
2000-05-01 05:53:59 +04:00
/* offset of sigcontext in the kernel's sigframe structure: */
# define SIGFRAME_SC_OFFSET 0x90
2000-02-04 00:58:30 +03:00
tcp - > u_arg [ 0 ] = 0 ;
if ( upeek ( tcp - > pid , PT_R12 , & sp ) < 0 )
return 0 ;
2000-05-01 05:53:59 +04:00
if ( umove ( tcp , sp + 16 + SIGFRAME_SC_OFFSET , & sc ) < 0 )
2000-02-04 00:58:30 +03:00
return 0 ;
tcp - > u_arg [ 0 ] = 1 ;
2000-05-01 05:53:59 +04:00
memcpy ( tcp - > u_arg + 1 , & sc . sc_mask , sizeof ( sc . sc_mask ) ) ;
2000-02-04 00:58:30 +03:00
}
else {
2000-05-01 05:53:59 +04:00
sigset_t sigm ;
memcpy ( & sigm , tcp - > u_arg + 1 , sizeof ( sigm ) ) ;
2000-02-04 00:58:30 +03:00
tcp - > u_rval = tcp - > u_error = 0 ;
if ( tcp - > u_arg [ 0 ] = = 0 )
return 0 ;
2000-05-01 05:53:59 +04:00
tcp - > auxstr = sprintsigmask ( " mask now " , & sigm , 0 ) ;
2000-02-04 00:58:30 +03:00
return RVAL_NONE | RVAL_STR ;
}
return 0 ;
# else /* !IA64 */
1999-02-19 03:21:36 +03:00
# ifdef POWERPC
long esp ;
struct sigcontext_struct sc ;
if ( entering ( tcp ) ) {
tcp - > u_arg [ 0 ] = 0 ;
2003-01-14 12:59:00 +03:00
if ( upeek ( tcp - > pid , sizeof ( unsigned long ) * PT_R1 , & esp ) < 0 )
1999-02-19 03:21:36 +03:00
return 0 ;
if ( umove ( tcp , esp , & sc ) < 0 )
return 0 ;
tcp - > u_arg [ 0 ] = 1 ;
tcp - > u_arg [ 1 ] = sc . oldmask ;
}
else {
sigset_t sigm ;
1999-04-06 05:19:39 +04:00
long_to_sigset ( tcp - > u_arg [ 1 ] , & sigm ) ;
1999-02-19 03:21:36 +03:00
tcp - > u_rval = tcp - > u_error = 0 ;
if ( tcp - > u_arg [ 0 ] = = 0 )
return 0 ;
1999-04-06 05:19:39 +04:00
tcp - > auxstr = sprintsigmask ( " mask now " , & sigm , 0 ) ;
1999-02-19 03:21:36 +03:00
return RVAL_NONE | RVAL_STR ;
}
return 0 ;
# else /* !POWERPC */
# ifdef M68K
long usp ;
1999-05-09 04:29:58 +04:00
struct sigcontext sc ;
1999-02-19 03:21:36 +03:00
if ( entering ( tcp ) ) {
tcp - > u_arg [ 0 ] = 0 ;
if ( upeek ( tcp - > pid , 4 * PT_USP , & usp ) < 0 )
return 0 ;
if ( umove ( tcp , usp , & sc ) < 0 )
return 0 ;
tcp - > u_arg [ 0 ] = 1 ;
tcp - > u_arg [ 1 ] = sc . sc_mask ;
}
else {
sigset_t sigm ;
1999-04-06 05:19:39 +04:00
long_to_sigset ( tcp - > u_arg [ 1 ] , & sigm ) ;
1999-02-19 03:21:36 +03:00
tcp - > u_rval = tcp - > u_error = 0 ;
if ( tcp - > u_arg [ 0 ] = = 0 )
return 0 ;
1999-04-06 05:19:39 +04:00
tcp - > auxstr = sprintsigmask ( " mask now " , & sigm , 0 ) ;
1999-02-19 03:21:36 +03:00
return RVAL_NONE | RVAL_STR ;
}
return 0 ;
# else /* !M68K */
# ifdef ALPHA
long fp ;
struct sigcontext_struct sc ;
if ( entering ( tcp ) ) {
tcp - > u_arg [ 0 ] = 0 ;
if ( upeek ( tcp - > pid , REG_FP , & fp ) < 0 )
return 0 ;
if ( umove ( tcp , fp , & sc ) < 0 )
return 0 ;
tcp - > u_arg [ 0 ] = 1 ;
tcp - > u_arg [ 1 ] = sc . sc_mask ;
}
else {
sigset_t sigm ;
1999-04-06 05:19:39 +04:00
long_to_sigset ( tcp - > u_arg [ 1 ] , & sigm ) ;
1999-02-19 03:21:36 +03:00
tcp - > u_rval = tcp - > u_error = 0 ;
if ( tcp - > u_arg [ 0 ] = = 0 )
return 0 ;
1999-04-06 05:19:39 +04:00
tcp - > auxstr = sprintsigmask ( " mask now " , & sigm , 0 ) ;
1999-02-19 03:21:36 +03:00
return RVAL_NONE | RVAL_STR ;
}
return 0 ;
# else
# ifdef SPARC
long i1 ;
1999-08-30 03:15:07 +04:00
struct regs regs ;
1999-02-19 03:21:36 +03:00
m_siginfo_t si ;
if ( ptrace ( PTRACE_GETREGS , tcp - > pid , ( char * ) & regs , 0 ) < 0 ) {
perror ( " sigreturn: PTRACE_GETREGS " ) ;
return 0 ;
}
if ( entering ( tcp ) ) {
tcp - > u_arg [ 0 ] = 0 ;
1999-08-30 03:15:07 +04:00
i1 = regs . r_o1 ;
1999-02-19 03:21:36 +03:00
if ( umove ( tcp , i1 , & si ) < 0 ) {
perror ( " sigreturn: umove " ) ;
return 0 ;
}
tcp - > u_arg [ 0 ] = 1 ;
tcp - > u_arg [ 1 ] = si . si_mask ;
} else {
sigset_t sigm ;
1999-04-06 05:19:39 +04:00
long_to_sigset ( tcp - > u_arg [ 1 ] , & sigm ) ;
1999-02-19 03:21:36 +03:00
tcp - > u_rval = tcp - > u_error = 0 ;
if ( tcp - > u_arg [ 0 ] = = 0 )
return 0 ;
1999-04-06 05:19:39 +04:00
tcp - > auxstr = sprintsigmask ( " mask now " , & sigm , 0 ) ;
1999-02-19 03:21:36 +03:00
return RVAL_NONE | RVAL_STR ;
}
return 0 ;
2002-12-17 08:10:37 +03:00
# else
1999-11-01 00:15:38 +03:00
# ifdef MIPS
long sp ;
struct sigcontext sc ;
if ( entering ( tcp ) ) {
tcp - > u_arg [ 0 ] = 0 ;
if ( upeek ( tcp - > pid , REG_SP , & sp ) < 0 )
return 0 ;
if ( umove ( tcp , sp , & sc ) < 0 )
return 0 ;
tcp - > u_arg [ 0 ] = 1 ;
tcp - > u_arg [ 1 ] = sc . sc_sigset ;
} else {
tcp - > u_rval = tcp - > u_error = 0 ;
if ( tcp - > u_arg [ 0 ] = = 0 )
return 0 ;
tcp - > auxstr = sprintsigmask ( " mask now " , tcp - > u_arg [ 1 ] ) ;
return RVAL_NONE | RVAL_STR ;
}
return 0 ;
2001-03-27 16:17:16 +04:00
# else
2002-09-23 19:41:01 +04:00
# warning No sys_sigreturn() for this architecture
# warning (no problem, just a reminder :-)
2001-03-27 16:17:16 +04:00
return 0 ;
1999-11-01 00:15:38 +03:00
# endif /* MIPS */
1999-02-19 03:21:36 +03:00
# endif /* SPARC */
# endif /* ALPHA */
# endif /* !M68K */
# endif /* !POWERPC */
2000-02-04 00:58:30 +03:00
# endif /* !IA64 */
1999-02-19 03:21:36 +03:00
# endif /* !I386 */
1999-12-23 17:20:14 +03:00
# endif /* S390 */
1999-02-19 03:21:36 +03:00
}
int
sys_siggetmask ( tcp )
struct tcb * tcp ;
{
if ( exiting ( tcp ) ) {
sigset_t sigm ;
1999-04-06 05:19:39 +04:00
long_to_sigset ( tcp - > u_rval , & sigm ) ;
tcp - > auxstr = sprintsigmask ( " mask " , & sigm , 0 ) ;
1999-02-19 03:21:36 +03:00
}
return RVAL_HEX | RVAL_STR ;
}
int
sys_sigsuspend ( tcp )
struct tcb * tcp ;
{
if ( entering ( tcp ) ) {
sigset_t sigm ;
1999-04-06 05:19:39 +04:00
long_to_sigset ( tcp - > u_arg [ 2 ] , & sigm ) ;
1999-02-19 03:21:36 +03:00
#if 0
/* first two are not really arguments, but print them anyway */
/* nevermind, they are an anachronism now, too bad... */
tprintf ( " %d, %#x, " , tcp - > u_arg [ 0 ] , tcp - > u_arg [ 1 ] ) ;
# endif
1999-04-06 05:19:39 +04:00
printsigmask ( & sigm , 0 ) ;
1999-02-19 03:21:36 +03:00
}
return 0 ;
}
# endif /* LINUX */
2000-09-02 01:03:06 +04:00
# if defined(SVR4) || defined(FREEBSD)
1999-02-19 03:21:36 +03:00
int
sys_sigsuspend ( tcp )
struct tcb * tcp ;
{
sigset_t sigset ;
if ( entering ( tcp ) ) {
if ( umove ( tcp , tcp - > u_arg [ 0 ] , & sigset ) < 0 )
tprintf ( " [?] " ) ;
else
1999-11-26 13:12:59 +03:00
printsigmask ( & sigset , 0 ) ;
1999-02-19 03:21:36 +03:00
}
return 0 ;
}
2000-09-02 01:03:06 +04:00
# ifndef FREEBSD
1999-02-19 03:21:36 +03:00
static struct xlat ucontext_flags [ ] = {
{ UC_SIGMASK , " UC_SIGMASK " } ,
{ UC_STACK , " UC_STACK " } ,
{ UC_CPU , " UC_CPU " } ,
# ifdef UC_FPU
{ UC_FPU , " UC_FPU " } ,
# endif
# ifdef UC_INTR
{ UC_INTR , " UC_INTR " } ,
# endif
{ 0 , NULL } ,
} ;
2000-09-02 01:03:06 +04:00
# endif /* !FREEBSD */
# endif /* SVR4 || FREEBSD */
1999-02-19 03:21:36 +03:00
2000-09-02 01:03:06 +04:00
# if defined SVR4 || defined LINUX || defined FREEBSD
1999-02-19 03:21:36 +03:00
# if defined LINUX && !defined SS_ONSTACK
# define SS_ONSTACK 1
# define SS_DISABLE 2
# if __GLIBC_MINOR__ == 0
typedef struct
{
__ptr_t ss_sp ;
int ss_flags ;
size_t ss_size ;
} stack_t ;
# endif
# endif
2000-09-02 01:03:06 +04:00
# ifdef FREEBSD
# define stack_t struct sigaltstack
# endif
1999-02-19 03:21:36 +03:00
static struct xlat sigaltstack_flags [ ] = {
{ SS_ONSTACK , " SS_ONSTACK " } ,
{ SS_DISABLE , " SS_DISABLE " } ,
{ 0 , NULL } ,
} ;
# endif
# ifdef SVR4
static void
printcontext ( tcp , ucp )
struct tcb * tcp ;
ucontext_t * ucp ;
{
tprintf ( " { " ) ;
if ( ! abbrev ( tcp ) ) {
tprintf ( " uc_flags= " ) ;
if ( ! printflags ( ucontext_flags , ucp - > uc_flags ) )
tprintf ( " 0 " ) ;
tprintf ( " , uc_link=%#lx, " , ( unsigned long ) ucp - > uc_link ) ;
}
tprintf ( " uc_sigmask= " ) ;
2001-05-15 19:09:14 +04:00
printsigmask ( & ucp - > uc_sigmask , 0 ) ;
1999-02-19 03:21:36 +03:00
if ( ! abbrev ( tcp ) ) {
tprintf ( " , uc_stack={ss_sp=%#lx, ss_size=%d, ss_flags= " ,
( unsigned long ) ucp - > uc_stack . ss_sp ,
ucp - > uc_stack . ss_size ) ;
if ( ! printflags ( sigaltstack_flags , ucp - > uc_stack . ss_flags ) )
tprintf ( " 0 " ) ;
tprintf ( " } " ) ;
}
tprintf ( " , ...} " ) ;
}
int
sys_getcontext ( tcp )
struct tcb * tcp ;
{
ucontext_t uc ;
2000-08-10 06:14:04 +04:00
if ( exiting ( tcp ) ) {
if ( tcp - > u_error )
tprintf ( " %#lx " , tcp - > u_arg [ 0 ] ) ;
else if ( ! tcp - > u_arg [ 0 ] )
1999-02-19 03:21:36 +03:00
tprintf ( " NULL " ) ;
else if ( umove ( tcp , tcp - > u_arg [ 0 ] , & uc ) < 0 )
tprintf ( " {...} " ) ;
else
printcontext ( tcp , & uc ) ;
}
return 0 ;
}
int
sys_setcontext ( tcp )
struct tcb * tcp ;
{
ucontext_t uc ;
if ( entering ( tcp ) ) {
if ( ! tcp - > u_arg [ 0 ] )
tprintf ( " NULL " ) ;
else if ( umove ( tcp , tcp - > u_arg [ 0 ] , & uc ) < 0 )
tprintf ( " {...} " ) ;
else
printcontext ( tcp , & uc ) ;
}
else {
tcp - > u_rval = tcp - > u_error = 0 ;
if ( tcp - > u_arg [ 0 ] = = 0 )
return 0 ;
return RVAL_NONE ;
}
return 0 ;
}
# endif /* SVR4 */
2000-09-02 01:03:06 +04:00
# if defined(LINUX) || defined(FREEBSD)
1999-02-19 03:21:36 +03:00
static int
print_stack_t ( tcp , addr )
struct tcb * tcp ;
unsigned long addr ;
{
stack_t ss ;
if ( umove ( tcp , addr , & ss ) < 0 )
return - 1 ;
tprintf ( " {ss_sp=%#lx, ss_flags= " , ( unsigned long ) ss . ss_sp ) ;
if ( ! printflags ( sigaltstack_flags , ss . ss_flags ) )
tprintf ( " 0 " ) ;
tprintf ( " , ss_size=%lu} " , ( unsigned long ) ss . ss_size ) ;
return 0 ;
}
int
sys_sigaltstack ( tcp )
struct tcb * tcp ;
{
if ( entering ( tcp ) ) {
if ( tcp - > u_arg [ 0 ] = = 0 )
tprintf ( " NULL " ) ;
else if ( print_stack_t ( tcp , tcp - > u_arg [ 0 ] ) < 0 )
return - 1 ;
}
else {
tprintf ( " , " ) ;
if ( tcp - > u_arg [ 1 ] = = 0 )
tprintf ( " NULL " ) ;
else if ( print_stack_t ( tcp , tcp - > u_arg [ 1 ] ) < 0 )
return - 1 ;
}
return 0 ;
}
# endif
# ifdef HAVE_SIGACTION
int
sys_sigprocmask ( tcp )
struct tcb * tcp ;
{
# ifdef ALPHA
if ( entering ( tcp ) ) {
printxval ( sigprocmaskcmds , tcp - > u_arg [ 0 ] , " SIG_??? " ) ;
tprintf ( " , " ) ;
1999-04-06 05:19:39 +04:00
printsigmask ( tcp - > u_arg [ 1 ] , 0 ) ;
1999-02-19 03:21:36 +03:00
}
else if ( ! syserror ( tcp ) ) {
1999-04-06 05:19:39 +04:00
tcp - > auxstr = sprintsigmask ( " old mask " , tcp - > u_rval , 0 ) ;
1999-02-19 03:21:36 +03:00
return RVAL_HEX | RVAL_STR ;
}
# else /* !ALPHA */
sigset_t sigset ;
if ( entering ( tcp ) ) {
# ifdef SVR4
if ( tcp - > u_arg [ 0 ] = = 0 )
tprintf ( " 0 " ) ;
else
# endif /* SVR4 */
printxval ( sigprocmaskcmds , tcp - > u_arg [ 0 ] , " SIG_??? " ) ;
tprintf ( " , " ) ;
if ( ! tcp - > u_arg [ 1 ] )
tprintf ( " NULL, " ) ;
1999-04-06 05:19:39 +04:00
else if ( copy_sigset ( tcp , tcp - > u_arg [ 1 ] , & sigset ) < 0 )
1999-02-19 03:21:36 +03:00
tprintf ( " %#lx, " , tcp - > u_arg [ 1 ] ) ;
else {
1999-04-06 05:19:39 +04:00
printsigmask ( & sigset , 0 ) ;
1999-02-19 03:21:36 +03:00
tprintf ( " , " ) ;
}
}
else {
if ( ! tcp - > u_arg [ 2 ] )
tprintf ( " NULL " ) ;
else if ( syserror ( tcp ) )
tprintf ( " %#lx " , tcp - > u_arg [ 2 ] ) ;
1999-04-06 05:19:39 +04:00
else if ( copy_sigset ( tcp , tcp - > u_arg [ 2 ] , & sigset ) < 0 )
1999-02-19 03:21:36 +03:00
tprintf ( " [?] " ) ;
else
1999-04-06 05:19:39 +04:00
printsigmask ( & sigset , 0 ) ;
1999-02-19 03:21:36 +03:00
}
# endif /* !ALPHA */
return 0 ;
}
# endif /* HAVE_SIGACTION */
int
sys_kill ( tcp )
struct tcb * tcp ;
{
if ( entering ( tcp ) ) {
1999-03-30 03:23:13 +04:00
tprintf ( " %ld, %s " , tcp - > u_arg [ 0 ] , signame ( tcp - > u_arg [ 1 ] ) ) ;
1999-02-19 03:21:36 +03:00
}
return 0 ;
}
int
sys_killpg ( tcp )
struct tcb * tcp ;
{
return sys_kill ( tcp ) ;
}
int
sys_sigpending ( tcp )
struct tcb * tcp ;
{
sigset_t sigset ;
if ( exiting ( tcp ) ) {
if ( syserror ( tcp ) )
tprintf ( " %#lx " , tcp - > u_arg [ 0 ] ) ;
1999-04-06 05:19:39 +04:00
else if ( copy_sigset ( tcp , tcp - > u_arg [ 0 ] , & sigset ) < 0 )
1999-02-19 03:21:36 +03:00
tprintf ( " [?] " ) ;
else
1999-11-26 13:12:59 +03:00
printsigmask ( & sigset , 0 ) ;
1999-02-19 03:21:36 +03:00
}
return 0 ;
}
2001-10-18 18:48:26 +04:00
int sys_sigwait ( tcp )
struct tcb * tcp ;
{
sigset_t sigset ;
if ( entering ( tcp ) ) {
if ( copy_sigset ( tcp , tcp - > u_arg [ 0 ] , & sigset ) < 0 )
tprintf ( " [?] " ) ;
else
printsigmask ( & sigset , 0 ) ;
}
else {
if ( ! syserror ( tcp ) ) {
tcp - > auxstr = signalent [ tcp - > u_rval ] ;
return RVAL_DECIMAL | RVAL_STR ;
}
}
return 0 ;
}
1999-02-19 03:21:36 +03:00
# ifdef LINUX
int
sys_rt_sigprocmask ( tcp )
struct tcb * tcp ;
{
sigset_t sigset ;
1999-04-06 05:19:39 +04:00
/* Note: arg[3] is the length of the sigset. */
1999-02-19 03:21:36 +03:00
if ( entering ( tcp ) ) {
printxval ( sigprocmaskcmds , tcp - > u_arg [ 0 ] , " SIG_??? " ) ;
tprintf ( " , " ) ;
if ( ! tcp - > u_arg [ 1 ] )
tprintf ( " NULL, " ) ;
1999-04-06 05:19:39 +04:00
else if ( copy_sigset_len ( tcp , tcp - > u_arg [ 1 ] , & sigset , tcp - > u_arg [ 3 ] ) < 0 )
1999-02-19 03:21:36 +03:00
tprintf ( " %#lx, " , tcp - > u_arg [ 1 ] ) ;
else {
1999-04-06 05:19:39 +04:00
printsigmask ( & sigset , 1 ) ;
1999-02-19 03:21:36 +03:00
tprintf ( " , " ) ;
}
}
else {
if ( ! tcp - > u_arg [ 2 ] )
tprintf ( " NULL " ) ;
else if ( syserror ( tcp ) )
tprintf ( " %#lx " , tcp - > u_arg [ 2 ] ) ;
1999-04-06 05:19:39 +04:00
else if ( copy_sigset_len ( tcp , tcp - > u_arg [ 2 ] , & sigset , tcp - > u_arg [ 3 ] ) < 0 )
1999-02-19 03:21:36 +03:00
tprintf ( " [?] " ) ;
else
1999-04-06 05:19:39 +04:00
printsigmask ( & sigset , 1 ) ;
1999-03-30 03:33:35 +04:00
tprintf ( " , %lu " , tcp - > u_arg [ 3 ] ) ;
1999-02-19 03:21:36 +03:00
}
return 0 ;
}
/* Structure describing the action to be taken when a signal arrives. */
struct new_sigaction
{
union
{
__sighandler_t __sa_handler ;
void ( * __sa_sigaction ) ( int , siginfo_t * , void * ) ;
}
__sigaction_handler ;
unsigned long sa_flags ;
void ( * sa_restorer ) ( void ) ;
unsigned long int sa_mask [ 2 ] ;
} ;
int
sys_rt_sigaction ( tcp )
struct tcb * tcp ;
{
struct new_sigaction sa ;
sigset_t sigset ;
long addr ;
if ( entering ( tcp ) ) {
printsignal ( tcp - > u_arg [ 0 ] ) ;
tprintf ( " , " ) ;
addr = tcp - > u_arg [ 1 ] ;
} else
addr = tcp - > u_arg [ 2 ] ;
if ( addr = = 0 )
tprintf ( " NULL " ) ;
else if ( ! verbose ( tcp ) )
tprintf ( " %#lx " , addr ) ;
else if ( umove ( tcp , addr , & sa ) < 0 )
tprintf ( " {...} " ) ;
else {
switch ( ( long ) sa . __sigaction_handler . __sa_handler ) {
case ( long ) SIG_ERR :
tprintf ( " {SIG_ERR} " ) ;
break ;
case ( long ) SIG_DFL :
tprintf ( " {SIG_DFL} " ) ;
break ;
case ( long ) SIG_IGN :
tprintf ( " {SIG_IGN} " ) ;
break ;
default :
tprintf ( " {%#lx, " ,
( long ) sa . __sigaction_handler . __sa_handler ) ;
1999-04-06 05:19:39 +04:00
sigemptyset ( & sigset ) ;
1999-06-03 18:21:07 +04:00
# ifdef LINUXSPARC
if ( tcp - > u_arg [ 4 ] < = sizeof ( sigset ) )
memcpy ( & sigset , & sa . sa_mask , tcp - > u_arg [ 4 ] ) ;
# else
1999-04-06 05:19:39 +04:00
if ( tcp - > u_arg [ 3 ] < = sizeof ( sigset ) )
memcpy ( & sigset , & sa . sa_mask , tcp - > u_arg [ 3 ] ) ;
1999-06-03 18:21:07 +04:00
# endif
1999-04-06 05:19:39 +04:00
else
memcpy ( & sigset , & sa . sa_mask , sizeof ( sigset ) ) ;
printsigmask ( & sigset , 1 ) ;
1999-02-19 03:21:36 +03:00
tprintf ( " , " ) ;
if ( ! printflags ( sigact_flags , sa . sa_flags ) )
tprintf ( " 0 " ) ;
2002-12-16 02:58:41 +03:00
# ifdef SA_RESTORER
if ( sa . sa_flags & SA_RESTORER )
tprintf ( " , %p " , sa . sa_restorer ) ;
# endif
1999-02-19 03:21:36 +03:00
tprintf ( " } " ) ;
}
}
if ( entering ( tcp ) )
tprintf ( " , " ) ;
else
1999-06-03 18:21:07 +04:00
# ifdef LINUXSPARC
tprintf ( " , %#lx, %lu " , tcp - > u_arg [ 3 ] , tcp - > u_arg [ 4 ] ) ;
# elif defined(ALPHA)
tprintf ( " , %lu, %#lx " , tcp - > u_arg [ 3 ] , tcp - > u_arg [ 4 ] ) ;
# else
1999-02-19 03:21:36 +03:00
tprintf ( " , %lu " , addr = tcp - > u_arg [ 3 ] ) ;
1999-06-03 18:21:07 +04:00
# endif
1999-02-19 03:21:36 +03:00
return 0 ;
}
int
sys_rt_sigpending ( tcp )
struct tcb * tcp ;
{
sigset_t sigset ;
if ( exiting ( tcp ) ) {
if ( syserror ( tcp ) )
tprintf ( " %#lx " , tcp - > u_arg [ 0 ] ) ;
1999-04-06 05:19:39 +04:00
else if ( copy_sigset_len ( tcp , tcp - > u_arg [ 0 ] ,
& sigset , tcp - > u_arg [ 1 ] ) < 0 )
1999-02-19 03:21:36 +03:00
tprintf ( " [?] " ) ;
else
1999-11-26 13:12:59 +03:00
printsigmask ( & sigset , 1 ) ;
1999-02-19 03:21:36 +03:00
}
return 0 ;
}
int
sys_rt_sigsuspend ( tcp )
struct tcb * tcp ;
{
if ( entering ( tcp ) ) {
sigset_t sigm ;
1999-04-06 05:19:39 +04:00
if ( copy_sigset_len ( tcp , tcp - > u_arg [ 0 ] , & sigm , tcp - > u_arg [ 1 ] ) < 0 )
tprintf ( " [?] " ) ;
else
printsigmask ( & sigm , 1 ) ;
1999-02-19 03:21:36 +03:00
}
return 0 ;
}
int
sys_rt_sigqueueinfo ( tcp )
struct tcb * tcp ;
{
if ( entering ( tcp ) ) {
siginfo_t si ;
tprintf ( " %lu, " , tcp - > u_arg [ 0 ] ) ;
printsignal ( tcp - > u_arg [ 1 ] ) ;
tprintf ( " , " ) ;
if ( umove ( tcp , tcp - > u_arg [ 2 ] , & si ) < 0 )
tprintf ( " %#lx " , tcp - > u_arg [ 2 ] ) ;
else
2001-10-18 19:13:53 +04:00
printsiginfo ( & si , verbose ( tcp ) ) ;
1999-02-19 03:21:36 +03:00
}
return 0 ;
}
int sys_rt_sigtimedwait ( tcp )
struct tcb * tcp ;
{
if ( entering ( tcp ) ) {
sigset_t sigset ;
2002-12-17 08:10:37 +03:00
if ( copy_sigset_len ( tcp , tcp - > u_arg [ 0 ] ,
1999-04-06 05:19:39 +04:00
& sigset , tcp - > u_arg [ 3 ] ) < 0 )
1999-02-19 03:21:36 +03:00
tprintf ( " [?] " ) ;
else
1999-11-26 13:12:59 +03:00
printsigmask ( & sigset , 1 ) ;
1999-02-19 03:21:36 +03:00
tprintf ( " , " ) ;
}
else {
if ( syserror ( tcp ) )
tprintf ( " %#lx " , tcp - > u_arg [ 0 ] ) ;
else {
siginfo_t si ;
if ( umove ( tcp , tcp - > u_arg [ 1 ] , & si ) < 0 )
tprintf ( " %#lx " , tcp - > u_arg [ 1 ] ) ;
else
2001-10-18 19:13:53 +04:00
printsiginfo ( & si , verbose ( tcp ) ) ;
1999-02-19 03:21:36 +03:00
/* XXX For now */
tprintf ( " , %#lx " , tcp - > u_arg [ 2 ] ) ;
tprintf ( " , %d " , ( int ) tcp - > u_arg [ 3 ] ) ;
}
}
return 0 ;
} ;
# endif /* LINUX */