home *** CD-ROM | disk | FTP | other *** search
/ Usenet 1994 January / usenetsourcesnewsgroupsinfomagicjanuary1994.iso / sources / sun / volume3 / strace / part02 / signal.c < prev    next >
Encoding:
C/C++ Source or Header  |  1992-03-02  |  7.0 KB  |  338 lines

  1. /*
  2.  * @(#)signal.c    2.7 92/01/21
  3.  *
  4.  */
  5.  
  6. #include <stdio.h>
  7. #include <string.h>
  8. #include <sys/types.h>
  9. #include <sys/ptrace.h>
  10. #include <sys/signal.h>
  11. #include <sys/user.h>
  12.  
  13. #include "defs.h"
  14.  
  15. char *signals[] = {
  16.      "SIGNULL",
  17.      "SIGHUP",   /*    1    hangup */
  18.      "SIGINT",   /*    2    interrupt */
  19.      "SIGQUIT",  /*    3*   quit */
  20.      "SIGILL",   /*    4*   illegal instruction */
  21.      "SIGTRAP",  /*    5*   trace trap */
  22.      "SIGIOT",   /*    6*   IOT trap (not generated on Suns) */
  23.      "SIGEMT",   /*    7*   EMT trap (A-line or F-line op code) */
  24.      "SIGFPE",   /*    8*   arithmetic exception */
  25.      "SIGKILL",  /*    9    kill (cannot be caught, blocked, or ignored) */
  26.      "SIGBUS",   /*    10*  bus error */
  27.      "SIGSEGV",  /*    11*  segmentation violation */
  28.      "SIGSYS",   /*    12*  bad argument to system call */
  29.      "SIGPIPE",  /*    13   write on a pipe with no one to read it */
  30.      "SIGALRM",  /*    14   alarm clock */
  31.      "SIGTERM",  /*    15   software termination signal */
  32.      "SIGURG",   /*    16@  urgent condition present on socket */
  33.      "SIGSTOP",  /*    17+  stop (cannot be caught, blocked, or ignored) */
  34.      "SIGTSTP",  /*    18+  stop signal generated from keyboard */
  35.      "SIGCONT",  /*    19@  continue after stop (cannot be blocked) */
  36.      "SIGCHLD",  /*    20@  child status has changed */
  37.      "SIGTTIN",  /*    21+  background read attempted from control terminal */
  38.      "SIGTTOU",  /*    22+  background write attempted to control terminal */
  39.      "SIGIO",    /*    23@  I/O is possible on a descriptor (see fcntl(2)) */
  40.      "SIGXCPU",  /*    24   cpu time limit exceeded (see setrlimit(2)) */
  41.      "SIGXFSZ",  /*    25   file size limit exceeded (see setrlimit(2)) */
  42.      "SIGVTALRM", /*   26   virtual time alarm (see setitimer(2)) */
  43.      "SIGPROF",  /*    27   profiling timer alarm (see setitimer(2)) */
  44.      "SIGWINCH", /*    28@  window changed (see win(4S)) */
  45.      "SIGLOST",  /*    29*  resource lost (see lockd(8C)) */
  46.      "SIGUSR1",  /*    30   user-defined signal 1 */
  47.      "SIGUSR2"   /*    31   user-defined signal 2 */
  48. };
  49.  
  50. static Xlat sigvec_flags[] = {
  51.     SV_ONSTACK,    "ONSTACK",
  52.     SV_INTERRUPT,    "INTERRUPT",
  53.     SV_RESETHAND,    "RESETHAND",
  54. #ifdef    SA_NOCLDSTOP
  55.     SA_NOCLDSTOP,    "NOCLDSTOP",
  56. #endif
  57.     0,        NULL,
  58. };
  59.  
  60. static char *
  61. sprintsigmask(mask)
  62. {
  63.     /* reserve 9 bytes per signal */
  64.     static char sigstr[NSIG * 9];
  65.     int i;
  66.  
  67.     sigstr[0] = '['; sigstr[1] = '\0';
  68.     for (i = 0; i < NSIG; i++) {
  69.         if (mask & sigmask(i)) {
  70.             if (sigstr[1])
  71.                 (void)strcat(sigstr, " ");
  72.             (void)strcat(sigstr, signals[i]);
  73.         }
  74.     }
  75.     (void)strcat(sigstr, "]");
  76.     return sigstr;
  77. }
  78.  
  79. static void
  80. printsigmask(mask)
  81. sigset_t mask;
  82. {
  83.     tprintf(sprintsigmask(mask));
  84. }
  85.  
  86. void
  87. prsigdisp(pid)
  88. {
  89.     sigset_t u_sigintr, u_sigreset, u_oldmask;
  90.  
  91.     if (upeek(pid, uoff(u_sigintr), &u_sigintr) < 0) {
  92.         return;
  93.     }
  94.     if (upeek(pid, uoff(u_sigreset), &u_sigreset) < 0) {
  95.         return;
  96.     }
  97.     if (upeek(pid, uoff(u_oldmask), &u_oldmask) < 0) {
  98.         return;
  99.     }
  100.     (void)fprintf(stderr, "***SIGMASKS: sigintr%s", sprintsigmask(u_sigintr));
  101.     (void)fprintf(stderr, " sigreset%s", sprintsigmask(u_sigreset));
  102.     (void)fprintf(stderr, " oldmask%s\n", sprintsigmask(u_oldmask));
  103.     return;
  104. }
  105.  
  106. int
  107. sigishandled(pid, sig)
  108. int pid;
  109. u_short sig;
  110. {
  111.     /*
  112.      * Check pid's signal disposition.
  113.      * return 1 if the process would somehow manage to
  114.      * survive signal `sig', else return 0
  115.      */
  116.     void (*u_signal)();
  117.  
  118.     if (upeek(pid, uoff(u_signal[0])+sig*sizeof u_signal, (int *)&u_signal) < 0) {
  119.         return 0;
  120.     }
  121.     if (u_signal != SIG_DFL)
  122.         return 1;
  123.  
  124.     switch (sig) {
  125.     /* Signals that are discarded by default (see sigvec(2)) */
  126.     case SIGCONT:
  127.     case SIGSTOP:
  128.     case SIGTSTP:
  129.     case SIGTTIN:
  130.     case SIGTTOU:
  131.     case SIGCHLD:
  132.     case SIGIO:
  133.     case SIGURG:
  134.     case SIGWINCH:
  135.         return 1;
  136.     default:
  137.         break;
  138.     }
  139.     return 0;
  140. }
  141.  
  142. int
  143. sys_sigvec(tcp)
  144. struct tcb *tcp;
  145. {
  146.     struct sigvec sv;
  147.     int addr;
  148.  
  149.     if (entering(tcp)) {
  150.         tprintf("%s, ", signals[tcp->u_args[0]]);
  151.         addr = tcp->u_args[1];
  152.     } else {
  153.         addr = tcp->u_args[2];
  154.     }
  155.     if (addr == 0 || umove(tcp->pid, addr, sizeof sv, (char *)&sv) < 0) {
  156.         tprintf("(struct sigvec *)0");
  157.     } else {
  158.         if (tcp->u_args[0] == SIGTRAP) {
  159.             tcp->flags |= TCB_SIGTRAPPED;
  160.             (void)kill(tcp->pid, SIGSTOP);
  161.         }
  162.         switch (sv.sv_handler) {
  163.         case SIG_DFL:
  164.             tprintf("SIG_DFL");
  165.             break;
  166.         case SIG_IGN:
  167.             tprintf("SIG_IGN");
  168.             break;
  169.         case SIG_HOLD:
  170.             tprintf("SIG_HOLD");
  171.             break;
  172.         default:
  173.             tprintf("{%#x, ", sv.sv_handler);
  174.             printsigmask(sv.sv_mask);
  175.             tprintf(", ");
  176.             if (!printflags(sigvec_flags, sv.sv_flags))
  177.                 tprintf("0");
  178.             tprintf("}");
  179.         }
  180.     }
  181.     if (entering(tcp))
  182.         tprintf(", ");
  183.     return 0;
  184. }
  185.  
  186. int
  187. sys_sigsetmask(tcp)
  188. struct tcb *tcp;
  189. {
  190.     if (entering(tcp)) {
  191.         if (tcp->u_args[0])
  192.             printsigmask(tcp->u_args[0]);
  193.         else
  194.             tprintf("0");
  195.         if ((tcp->u_args[0] & sigmask(SIGTRAP))) {
  196.             /* Mark attempt to block SIGTRAP */
  197.             tcp->flags |= TCB_SIGTRAPPED;
  198.             /* Send unblockable signal */
  199.             (void)kill(tcp->pid, SIGSTOP);
  200.         }
  201.     } else {
  202.         if (!syserror(tcp)) {
  203.             if (tcp->u_rval != 0) {
  204.                 tcp->auxstr = sprintsigmask(tcp->u_rval);
  205.                 return RVAL_HEX | RVAL_STR;
  206.             }
  207.             return RVAL_HEX;
  208.         }
  209.     }
  210.     return 0;
  211. }
  212.  
  213. int
  214. sys_sigblock(tcp)
  215. struct tcb *tcp;
  216. {
  217.     return sys_sigsetmask(tcp);
  218. }
  219.  
  220. int
  221. sys_sigpause(tcp)
  222. struct tcb *tcp;
  223. {
  224.     if (entering(tcp)) {
  225.         if (tcp->u_args[0])
  226.             printsigmask(tcp->u_args[0]);
  227.         else
  228.             tprintf("0");
  229.     }
  230.     return 0;
  231. }
  232.  
  233. int
  234. sys_sigstack(tcp)
  235. struct tcb *tcp;
  236. {
  237.     struct sigstack ss;
  238.     int addr;
  239.  
  240.     if (entering(tcp)) {
  241.         addr = tcp->u_args[0];
  242.     } else {
  243.         addr = tcp->u_args[1];
  244.     }
  245.     if (addr == 0 || umove(tcp->pid, addr, sizeof ss, (char *)&ss)) {
  246.         tprintf("(struct sigstack *)0");
  247.     } else {
  248.         tprintf("{sp: %#x,", ss.ss_sp);
  249.         tprintf("%s}", ss.ss_onstack?"ON":"OFF");
  250.     }
  251.     if (entering(tcp))
  252.         tprintf(", ");
  253.     return 0;
  254. }
  255.  
  256. /*ARGSUSED*/
  257. int
  258. sys_sigcleanup(tcp)
  259. struct tcb *tcp;
  260. {
  261.     return 0;
  262. }
  263.  
  264. int
  265. sys_kill(tcp)
  266. struct tcb *tcp;
  267. {
  268.     if (entering(tcp)) {
  269.         tprintf("%d, %s",
  270.                 tcp->u_args[0], signals[tcp->u_args[1]]);
  271.     }
  272.     return 0;
  273. }
  274.  
  275. int
  276. sys_killpg(tcp)
  277. struct tcb *tcp;
  278. {
  279.     return sys_kill(tcp);
  280. }
  281.  
  282. int
  283. sys_sigpending(tcp)
  284. struct tcb *tcp;
  285. {
  286.     sigset_t sigset;
  287.  
  288.     if (exiting(tcp)) {
  289.         if (syserror(tcp) ||
  290.             umove(tcp->pid, tcp->u_args[0],
  291.                 sizeof sigset, (char *)&sigset) < 0)
  292.             tprintf("%#x", tcp->u_args[0]);
  293.         else
  294.             printsigmask(sigset);
  295.     }
  296.     return 0;
  297. }
  298.  
  299. static Xlat sigprocmaskhows[] = {
  300. #ifdef    SIG_BLOCK
  301.     SIG_BLOCK,    "BLOCK",
  302. #endif
  303. #ifdef    SIG_UNBLOCK
  304.     SIG_UNBLOCK,    "UNBLOCK",
  305. #endif
  306. #ifdef    SIG_SETMASK
  307.     SIG_SETMASK,    "SETMASK",
  308. #endif
  309.     0,        NULL,
  310. };
  311.  
  312. /* Not currently a system call */
  313. int
  314. sys_setprocmask(tcp)
  315. struct tcb *tcp;
  316. {
  317.     sigset_t sigset;
  318.  
  319.     if (entering(tcp)) {
  320.         printxval(sigprocmaskhows, tcp->u_args[0], "SIG_???");
  321.         tprintf(", ");
  322.         if (tcp->u_args[1] == 0 || umove(tcp->pid, tcp->u_args[1],
  323.                     sizeof sigset, (char *)&sigset) < 0)
  324.             tprintf("%#x", tcp->u_args[1]);
  325.         else
  326.             printsigmask(sigset);
  327.         tprintf(", ");
  328.     } else {
  329.         if (syserror(tcp) || tcp->u_args[2] == 0 ||
  330.             umove(tcp->pid, tcp->u_args[2],
  331.                 sizeof sigset, (char *)&sigset) < 0)
  332.             tprintf("%#x", tcp->u_args[2]);
  333.         else
  334.             printsigmask(sigset);
  335.     }
  336.     return 0;
  337. }
  338.