signal.c 2.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136
  1. #include "lib.h"
  2. #include "sys9.h"
  3. #include <signal.h>
  4. #include <errno.h>
  5. #include <string.h>
  6. #include <setjmp.h>
  7. extern sigset_t _psigblocked;
  8. static struct {
  9. char *msg; /* just check prefix */
  10. int num;
  11. } sigtab[] = {
  12. {"hangup", SIGHUP},
  13. {"interrupt", SIGINT},
  14. {"quit", SIGQUIT},
  15. {"alarm", SIGALRM},
  16. {"sys: trap: illegal instruction", SIGILL},
  17. {"sys: trap: reserved instruction", SIGILL},
  18. {"sys: trap: reserved", SIGILL},
  19. {"sys: trap: arithmetic overflow", SIGFPE},
  20. {"abort", SIGABRT},
  21. {"sys: fp:", SIGFPE},
  22. {"exit", SIGKILL},
  23. {"die", SIGKILL},
  24. {"kill", SIGKILL},
  25. {"sys: trap: bus error", SIGSEGV},
  26. {"sys: trap: address error", SIGSEGV},
  27. {"sys: trap: TLB", SIGSEGV},
  28. {"sys: write on closed pipe", SIGPIPE},
  29. {"alarm", SIGALRM},
  30. {"term", SIGTERM},
  31. {"usr1", SIGUSR1},
  32. {"usr2", SIGUSR2},
  33. };
  34. #define NSIGTAB ((sizeof sigtab)/(sizeof (sigtab[0])))
  35. void (*_sighdlr[MAXSIG+1])(int, char*, Ureg*); /* 0 initialized: SIG_DFL */
  36. void
  37. (*signal(int sig, void (*func)(int, char*, Ureg*)))(int, char*, Ureg*)
  38. {
  39. void(*oldf)(int, char*, Ureg*);
  40. if(sig <= 0 || sig > MAXSIG){
  41. errno = EINVAL;
  42. return SIG_ERR;
  43. }
  44. oldf = _sighdlr[sig];
  45. if(sig == SIGKILL)
  46. return oldf; /* can't catch or ignore SIGKILL */
  47. _sighdlr[sig] = func;
  48. return oldf;
  49. }
  50. /* BAD CODE - see /sys/src/ape/lib/ap/$objtype/setjmp.s for real code
  51. int
  52. sigsetjmp(sigjmp_buf buf, int savemask)
  53. {
  54. int r;
  55. buf[0] = savemask;
  56. buf[1] = _psigblocked;
  57. return setjmp(&buf[2]);
  58. }
  59. */
  60. /*
  61. * BUG: improper handling of process signal mask
  62. */
  63. int
  64. sigaction(int sig, struct sigaction *act, struct sigaction *oact)
  65. {
  66. if(sig <= 0 || sig > MAXSIG || sig == SIGKILL){
  67. errno = EINVAL;
  68. return -1;
  69. }
  70. if(oact){
  71. oact->sa_handler = _sighdlr[sig];
  72. oact->sa_mask = _psigblocked;
  73. oact->sa_flags = 0;
  74. }
  75. if(act){
  76. _sighdlr[sig] = act->sa_handler;
  77. }
  78. return 0;
  79. }
  80. /* this is registered in _envsetup */
  81. int
  82. _notehandler(Ureg *u, char *msg)
  83. {
  84. int i;
  85. void(*f)(int, char*, Ureg*);
  86. extern void _doatexits(void); /* in stdio/exit.c */
  87. if(_finishing)
  88. _finish(0, 0);
  89. for(i = 0; i<NSIGTAB; i++){
  90. if(strncmp(msg, sigtab[i].msg, strlen(sigtab[i].msg)) == 0){
  91. f = _sighdlr[sigtab[i].num];
  92. if(f == SIG_DFL || f == SIG_ERR)
  93. break;
  94. if(f != SIG_IGN) {
  95. _notetramp(sigtab[i].num, f, u);
  96. /* notetramp is machine-dependent; doesn't return to here */
  97. }
  98. _NOTED(0); /* NCONT */
  99. return;
  100. }
  101. }
  102. _doatexits();
  103. _NOTED(1); /* NDFLT */
  104. }
  105. int
  106. _stringsig(char *nam)
  107. {
  108. int i;
  109. for(i = 0; i<NSIGTAB; i++)
  110. if(strncmp(nam, sigtab[i].msg, strlen(sigtab[i].msg)) == 0)
  111. return sigtab[i].num;
  112. return 0;
  113. }
  114. char *
  115. _sigstring(int sig)
  116. {
  117. int i;
  118. for(i=0; i<NSIGTAB; i++)
  119. if(sigtab[i].num == sig)
  120. return sigtab[i].msg;
  121. return "unknown signal";
  122. }