home *** CD-ROM | disk | FTP | other *** search
- /*
- * @(#)signal.c 2.7 92/01/21
- *
- */
-
- #include <stdio.h>
- #include <string.h>
- #include <sys/types.h>
- #include <sys/ptrace.h>
- #include <sys/signal.h>
- #include <sys/user.h>
-
- #include "defs.h"
-
- char *signals[] = {
- "SIGNULL",
- "SIGHUP", /* 1 hangup */
- "SIGINT", /* 2 interrupt */
- "SIGQUIT", /* 3* quit */
- "SIGILL", /* 4* illegal instruction */
- "SIGTRAP", /* 5* trace trap */
- "SIGIOT", /* 6* IOT trap (not generated on Suns) */
- "SIGEMT", /* 7* EMT trap (A-line or F-line op code) */
- "SIGFPE", /* 8* arithmetic exception */
- "SIGKILL", /* 9 kill (cannot be caught, blocked, or ignored) */
- "SIGBUS", /* 10* bus error */
- "SIGSEGV", /* 11* segmentation violation */
- "SIGSYS", /* 12* bad argument to system call */
- "SIGPIPE", /* 13 write on a pipe with no one to read it */
- "SIGALRM", /* 14 alarm clock */
- "SIGTERM", /* 15 software termination signal */
- "SIGURG", /* 16@ urgent condition present on socket */
- "SIGSTOP", /* 17+ stop (cannot be caught, blocked, or ignored) */
- "SIGTSTP", /* 18+ stop signal generated from keyboard */
- "SIGCONT", /* 19@ continue after stop (cannot be blocked) */
- "SIGCHLD", /* 20@ child status has changed */
- "SIGTTIN", /* 21+ background read attempted from control terminal */
- "SIGTTOU", /* 22+ background write attempted to control terminal */
- "SIGIO", /* 23@ I/O is possible on a descriptor (see fcntl(2)) */
- "SIGXCPU", /* 24 cpu time limit exceeded (see setrlimit(2)) */
- "SIGXFSZ", /* 25 file size limit exceeded (see setrlimit(2)) */
- "SIGVTALRM", /* 26 virtual time alarm (see setitimer(2)) */
- "SIGPROF", /* 27 profiling timer alarm (see setitimer(2)) */
- "SIGWINCH", /* 28@ window changed (see win(4S)) */
- "SIGLOST", /* 29* resource lost (see lockd(8C)) */
- "SIGUSR1", /* 30 user-defined signal 1 */
- "SIGUSR2" /* 31 user-defined signal 2 */
- };
-
- static Xlat sigvec_flags[] = {
- SV_ONSTACK, "ONSTACK",
- SV_INTERRUPT, "INTERRUPT",
- SV_RESETHAND, "RESETHAND",
- #ifdef SA_NOCLDSTOP
- SA_NOCLDSTOP, "NOCLDSTOP",
- #endif
- 0, NULL,
- };
-
- static char *
- sprintsigmask(mask)
- {
- /* reserve 9 bytes per signal */
- static char sigstr[NSIG * 9];
- int i;
-
- sigstr[0] = '['; sigstr[1] = '\0';
- for (i = 0; i < NSIG; i++) {
- if (mask & sigmask(i)) {
- if (sigstr[1])
- (void)strcat(sigstr, " ");
- (void)strcat(sigstr, signals[i]);
- }
- }
- (void)strcat(sigstr, "]");
- return sigstr;
- }
-
- static void
- printsigmask(mask)
- sigset_t mask;
- {
- tprintf(sprintsigmask(mask));
- }
-
- void
- prsigdisp(pid)
- {
- sigset_t u_sigintr, u_sigreset, u_oldmask;
-
- if (upeek(pid, uoff(u_sigintr), &u_sigintr) < 0) {
- return;
- }
- if (upeek(pid, uoff(u_sigreset), &u_sigreset) < 0) {
- return;
- }
- if (upeek(pid, uoff(u_oldmask), &u_oldmask) < 0) {
- return;
- }
- (void)fprintf(stderr, "***SIGMASKS: sigintr%s", sprintsigmask(u_sigintr));
- (void)fprintf(stderr, " sigreset%s", sprintsigmask(u_sigreset));
- (void)fprintf(stderr, " oldmask%s\n", sprintsigmask(u_oldmask));
- return;
- }
-
- int
- sigishandled(pid, sig)
- int pid;
- u_short sig;
- {
- /*
- * Check pid's signal disposition.
- * return 1 if the process would somehow manage to
- * survive signal `sig', else return 0
- */
- void (*u_signal)();
-
- if (upeek(pid, uoff(u_signal[0])+sig*sizeof u_signal, (int *)&u_signal) < 0) {
- return 0;
- }
- if (u_signal != SIG_DFL)
- return 1;
-
- switch (sig) {
- /* Signals that are discarded by default (see sigvec(2)) */
- case SIGCONT:
- case SIGSTOP:
- case SIGTSTP:
- case SIGTTIN:
- case SIGTTOU:
- case SIGCHLD:
- case SIGIO:
- case SIGURG:
- case SIGWINCH:
- return 1;
- default:
- break;
- }
- return 0;
- }
-
- int
- sys_sigvec(tcp)
- struct tcb *tcp;
- {
- struct sigvec sv;
- int addr;
-
- if (entering(tcp)) {
- tprintf("%s, ", signals[tcp->u_args[0]]);
- addr = tcp->u_args[1];
- } else {
- addr = tcp->u_args[2];
- }
- if (addr == 0 || umove(tcp->pid, addr, sizeof sv, (char *)&sv) < 0) {
- tprintf("(struct sigvec *)0");
- } else {
- if (tcp->u_args[0] == SIGTRAP) {
- tcp->flags |= TCB_SIGTRAPPED;
- (void)kill(tcp->pid, SIGSTOP);
- }
- switch (sv.sv_handler) {
- case SIG_DFL:
- tprintf("SIG_DFL");
- break;
- case SIG_IGN:
- tprintf("SIG_IGN");
- break;
- case SIG_HOLD:
- tprintf("SIG_HOLD");
- break;
- default:
- tprintf("{%#x, ", sv.sv_handler);
- printsigmask(sv.sv_mask);
- tprintf(", ");
- if (!printflags(sigvec_flags, sv.sv_flags))
- tprintf("0");
- tprintf("}");
- }
- }
- if (entering(tcp))
- tprintf(", ");
- return 0;
- }
-
- int
- sys_sigsetmask(tcp)
- struct tcb *tcp;
- {
- if (entering(tcp)) {
- if (tcp->u_args[0])
- printsigmask(tcp->u_args[0]);
- else
- tprintf("0");
- if ((tcp->u_args[0] & sigmask(SIGTRAP))) {
- /* Mark attempt to block SIGTRAP */
- tcp->flags |= TCB_SIGTRAPPED;
- /* Send unblockable signal */
- (void)kill(tcp->pid, SIGSTOP);
- }
- } else {
- if (!syserror(tcp)) {
- if (tcp->u_rval != 0) {
- tcp->auxstr = sprintsigmask(tcp->u_rval);
- return RVAL_HEX | RVAL_STR;
- }
- return RVAL_HEX;
- }
- }
- return 0;
- }
-
- int
- sys_sigblock(tcp)
- struct tcb *tcp;
- {
- return sys_sigsetmask(tcp);
- }
-
- int
- sys_sigpause(tcp)
- struct tcb *tcp;
- {
- if (entering(tcp)) {
- if (tcp->u_args[0])
- printsigmask(tcp->u_args[0]);
- else
- tprintf("0");
- }
- return 0;
- }
-
- int
- sys_sigstack(tcp)
- struct tcb *tcp;
- {
- struct sigstack ss;
- int addr;
-
- if (entering(tcp)) {
- addr = tcp->u_args[0];
- } else {
- addr = tcp->u_args[1];
- }
- if (addr == 0 || umove(tcp->pid, addr, sizeof ss, (char *)&ss)) {
- tprintf("(struct sigstack *)0");
- } else {
- tprintf("{sp: %#x,", ss.ss_sp);
- tprintf("%s}", ss.ss_onstack?"ON":"OFF");
- }
- if (entering(tcp))
- tprintf(", ");
- return 0;
- }
-
- /*ARGSUSED*/
- int
- sys_sigcleanup(tcp)
- struct tcb *tcp;
- {
- return 0;
- }
-
- int
- sys_kill(tcp)
- struct tcb *tcp;
- {
- if (entering(tcp)) {
- tprintf("%d, %s",
- tcp->u_args[0], signals[tcp->u_args[1]]);
- }
- 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) ||
- umove(tcp->pid, tcp->u_args[0],
- sizeof sigset, (char *)&sigset) < 0)
- tprintf("%#x", tcp->u_args[0]);
- else
- printsigmask(sigset);
- }
- return 0;
- }
-
- static Xlat sigprocmaskhows[] = {
- #ifdef SIG_BLOCK
- SIG_BLOCK, "BLOCK",
- #endif
- #ifdef SIG_UNBLOCK
- SIG_UNBLOCK, "UNBLOCK",
- #endif
- #ifdef SIG_SETMASK
- SIG_SETMASK, "SETMASK",
- #endif
- 0, NULL,
- };
-
- /* Not currently a system call */
- int
- sys_setprocmask(tcp)
- struct tcb *tcp;
- {
- sigset_t sigset;
-
- if (entering(tcp)) {
- printxval(sigprocmaskhows, tcp->u_args[0], "SIG_???");
- tprintf(", ");
- if (tcp->u_args[1] == 0 || umove(tcp->pid, tcp->u_args[1],
- sizeof sigset, (char *)&sigset) < 0)
- tprintf("%#x", tcp->u_args[1]);
- else
- printsigmask(sigset);
- tprintf(", ");
- } else {
- if (syserror(tcp) || tcp->u_args[2] == 0 ||
- umove(tcp->pid, tcp->u_args[2],
- sizeof sigset, (char *)&sigset) < 0)
- tprintf("%#x", tcp->u_args[2]);
- else
- printsigmask(sigset);
- }
- return 0;
- }
-