#include #include #include #include "linuxsys.h" #include "linux.h" SYSCALL(sys_kill) { int pid; int sig; pid = (int)ARG1; sig = (int)ARG2; RETURN(_kill(pid, sig)); } struct sigaction { void *handler; ulong flags; void *restorer; uchar mask; }; static void uv2sigset(uchar *set, int setsize, uvlong mask) { int i; for(i=0; i> (i*8)) & 0xff); } else { set[i] = 0; } } } static uvlong sigset2uv(uchar *set, int setsize) { uvlong r; int i; r = 0LL; if(setsize > sizeof(uvlong)) setsize = sizeof(uvlong); for(i=0; iss.blocked); if(act){ x = sigset2uv(act, setsize); } else { RETURN(0); } x &= ~(1LL<<(SIGKILL-1)); x &= ~(1LL <<(SIGSTOP-1)); switch(how){ default: RETURN(-EINVAL); case SIG_BLOCK: threadp->ss.blocked |= x; break; case SIG_UNBLOCK: threadp->ss.blocked &= ~x; break; case SIG_SETMASK: threadp->ss.blocked = x; break; } RETURN(0); } static void printsigstate(char *s) { uvlong pending; uvlong blocked; blocked = threadp->ss.blocked; pending = sigpending(&threadp->ss); fprint(2, "[%d] [%s] sigstate: pending: 0x%llux, blocked 0x%llux, ready 0x%llux\n", threadp->pid, s, pending, blocked, pending & ~blocked); } SYSCALL(sys_rt_sigsuspend) { uvlong x; uvlong t; uchar *sm; int setsize; sm = (uchar*)ARG1; setsize = (int)ARG2; DPRINT("rt_sigsuspend(0x%p, %d)...",sm, setsize); // printsigstate("before sigsuspend"); t = threadp->ss.blocked; x = sigset2uv(sm, setsize); x &= ~(1LL<<(SIGKILL-1)); x &= ~(1LL <<(SIGSTOP-1)); threadp->ss.blocked = x; while(!(sigpending(&threadp->ss) & ~x)){ // printsigstate("sigsuspend sleep"); sleep(10000); // printsigstate("sigsuspend wakeup"); } // printsigstate("sigsuspend break"); sigenable(&threadp->ss); sigdisable(&threadp->ss); threadp->ss.blocked = t; // printsigstate("after sigsuspend"); RETURN(-EINTR); } SYSCALL(sys_rt_sigaction) { int sig; struct sigaction *act; struct sigaction *oact; int setsize; sig = (int)ARG1; act = (struct sigaction*)ARG2; oact = (struct sigaction*)ARG3; setsize = (int)ARG4; DPRINT("rt_sigaction(%d, 0x%p, 0x%p, %d)...", sig, act, oact, setsize); if(act && act->flags & (SA_SIGINFO | SA_ONSTACK)){ fprint(2, "[%d] rt_sigaction: unsopprted signalflags %lux\n", threadp->tid, act->flags); RETURN(-EINVAL); } if(oact){ oact->handler = threadp->ss.action[sig-1].handler; oact->flags = threadp->ss.action[sig-1].flags; oact->restorer = 0; uv2sigset(&oact->mask, setsize, threadp->ss.action[sig-1].blocked); } if(act){ threadp->ss.action[sig-1].handler = (void*)act->handler; threadp->ss.action[sig-1].flags = act->flags; threadp->ss.action[sig-1].blocked = sigset2uv(&act->mask, setsize); } RETURN(0); } SYSCALL(sys_rt_sigpending) { uchar *set; int setsize; set = (uchar*)ARG1; setsize = (int)ARG2; DPRINT("rt_sigpending(0x%p, %d)...", set, setsize); uv2sigset(set, setsize, sigpending(&threadp->ss)); RETURN(0); }