slsignal.c 2.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138
  1. #include "config.h"
  2. #include <stdio.h>
  3. #include <signal.h>
  4. #ifdef HAVE_STDLIB_H
  5. # include <stdlib.h>
  6. #endif
  7. #ifdef HAVE_UNISTD_H
  8. # include <unistd.h>
  9. #endif
  10. #include <errno.h>
  11. #include "_slang.h"
  12. /* This function will cause system calls to be restarted after signal if possible */
  13. SLSig_Fun_Type *SLsignal (int sig, SLSig_Fun_Type *f)
  14. {
  15. #ifdef SLANG_POSIX_SIGNALS
  16. struct sigaction old_sa, new_sa;
  17. # ifdef SIGALRM
  18. /* We want system calls to be interrupted by SIGALRM. */
  19. if (sig == SIGALRM) return SLsignal_intr (sig, f);
  20. # endif
  21. sigemptyset (&new_sa.sa_mask);
  22. new_sa.sa_handler = f;
  23. new_sa.sa_flags = 0;
  24. # ifdef SA_RESTART
  25. new_sa.sa_flags |= SA_RESTART;
  26. # endif
  27. if (-1 == sigaction (sig, &new_sa, &old_sa))
  28. return (SLSig_Fun_Type *) SIG_ERR;
  29. return old_sa.sa_handler;
  30. #else
  31. /* Not POSIX. */
  32. return signal (sig, f);
  33. #endif
  34. }
  35. /* This function will NOT cause system calls to be restarted after
  36. * signal if possible
  37. */
  38. SLSig_Fun_Type *SLsignal_intr (int sig, SLSig_Fun_Type *f)
  39. {
  40. #ifdef SLANG_POSIX_SIGNALS
  41. struct sigaction old_sa, new_sa;
  42. sigemptyset (&new_sa.sa_mask);
  43. new_sa.sa_handler = f;
  44. new_sa.sa_flags = 0;
  45. # ifdef SA_INTERRUPT
  46. new_sa.sa_flags |= SA_INTERRUPT;
  47. # endif
  48. if (-1 == sigaction (sig, &new_sa, &old_sa))
  49. return (SLSig_Fun_Type *) SIG_ERR;
  50. return old_sa.sa_handler;
  51. #else
  52. /* Not POSIX. */
  53. return signal (sig, f);
  54. #endif
  55. }
  56. /* We are primarily interested in blocking signals that would cause the
  57. * application to reset the tty. These include suspend signals and
  58. * possibly interrupt signals.
  59. */
  60. #ifdef SLANG_POSIX_SIGNALS
  61. static sigset_t Old_Signal_Mask;
  62. #endif
  63. static volatile unsigned int Blocked_Depth;
  64. int SLsig_block_signals (void)
  65. {
  66. #ifdef SLANG_POSIX_SIGNALS
  67. sigset_t new_mask;
  68. #endif
  69. Blocked_Depth++;
  70. if (Blocked_Depth != 1)
  71. {
  72. return 0;
  73. }
  74. #ifdef SLANG_POSIX_SIGNALS
  75. sigemptyset (&new_mask);
  76. # ifdef SIGQUIT
  77. sigaddset (&new_mask, SIGQUIT);
  78. # endif
  79. # ifdef SIGTSTP
  80. sigaddset (&new_mask, SIGTSTP);
  81. # endif
  82. # ifdef SIGINT
  83. sigaddset (&new_mask, SIGINT);
  84. # endif
  85. # ifdef SIGTTIN
  86. sigaddset (&new_mask, SIGTTIN);
  87. # endif
  88. # ifdef SIGTTOU
  89. sigaddset (&new_mask, SIGTTOU);
  90. # endif
  91. (void) sigprocmask (SIG_BLOCK, &new_mask, &Old_Signal_Mask);
  92. return 0;
  93. #else
  94. /* Not implemented. */
  95. return -1;
  96. #endif
  97. }
  98. int SLsig_unblock_signals (void)
  99. {
  100. if (Blocked_Depth == 0)
  101. return -1;
  102. Blocked_Depth--;
  103. if (Blocked_Depth != 0)
  104. return 0;
  105. #ifdef SLANG_POSIX_SIGNALS
  106. (void) sigprocmask (SIG_SETMASK, &Old_Signal_Mask, NULL);
  107. return 0;
  108. #else
  109. return -1;
  110. #endif
  111. }