signals.c 5.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277
  1. /* $Xorg: signals.c,v 1.4 2001/02/09 02:06:01 xorgcvs Exp $ */
  2. /******************************************************************************
  3. Copyright 1994, 1998 The Open Group
  4. Permission to use, copy, modify, distribute, and sell this software and its
  5. documentation for any purpose is hereby granted without fee, provided that
  6. the above copyright notice appear in all copies and that both that
  7. copyright notice and this permission notice appear in supporting
  8. documentation.
  9. The above copyright notice and this permission notice shall be included in
  10. all copies or substantial portions of the Software.
  11. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
  12. IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
  13. FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
  14. OPEN GROUP BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
  15. AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
  16. CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
  17. Except as contained in this notice, the name of The Open Group shall not be
  18. used in advertising or otherwise to promote the sale, use or other dealings
  19. in this Software without prior written authorization from The Open Group.
  20. ******************************************************************************/
  21. /* $XFree86: xc/programs/xsm/signals.c,v 3.5 2001/12/08 18:33:45 herrb Exp $ */
  22. #include <stdlib.h>
  23. #include <X11/Xos.h>
  24. #include <X11/Xfuncs.h>
  25. #include <X11/Intrinsic.h>
  26. #include <X11/SM/SMlib.h>
  27. #include "save.h"
  28. #include <errno.h>
  29. #ifdef USG
  30. #ifndef __TYPES__
  31. #include <sys/types.h> /* forgot to protect it... */
  32. #define __TYPES__
  33. #endif /* __TYPES__ */
  34. #else
  35. #if defined(_POSIX_SOURCE) && defined(MOTOROLA)
  36. #undef _POSIX_SOURCE
  37. #include <sys/types.h>
  38. #define _POSIX_SOURCE
  39. #else
  40. #include <sys/types.h>
  41. #endif
  42. #endif /* USG */
  43. #ifdef X_POSIX_C_SOURCE
  44. #define _POSIX_C_SOURCE X_POSIX_C_SOURCE
  45. #include <signal.h>
  46. #include <sys/wait.h>
  47. #undef _POSIX_C_SOURCE
  48. #else
  49. #if defined(X_NOT_POSIX) || defined(_POSIX_SOURCE)
  50. #include <signal.h>
  51. #include <sys/wait.h>
  52. #else
  53. #define _POSIX_SOURCE
  54. #include <signal.h>
  55. #ifdef SCO325
  56. #include <sys/procset.h>
  57. #include <sys/siginfo.h>
  58. #endif
  59. #include <sys/wait.h>
  60. #undef _POSIX_SOURCE
  61. #endif
  62. #endif
  63. #include "list.h"
  64. #include "save.h"
  65. #if defined(X_NOT_POSIX) && defined(SIGNALRETURNSINT)
  66. #define SIGVAL int
  67. #else
  68. #define SIGVAL void
  69. #endif
  70. #ifndef X_NOT_POSIX
  71. #define USE_POSIX_WAIT
  72. #endif
  73. #if defined(linux) || defined(SYSV)
  74. #define USE_SYSV_SIGNALS
  75. #endif
  76. #if defined(SCO)
  77. #undef SIGTSTP /* defined, but not the BSD way */
  78. #endif
  79. #if defined(X_NOT_POSIX) && defined(SYSV)
  80. #define SIGNALS_RESET_WHEN_CAUGHT
  81. #endif
  82. #include <stddef.h>
  83. #include "xsm.h"
  84. int checkpoint_from_signal = 0;
  85. static SIGVAL
  86. Signal(int sig, SIGVAL (*handler)(int))
  87. {
  88. #ifndef X_NOT_POSIX
  89. struct sigaction sigact, osigact;
  90. sigact.sa_handler = handler;
  91. sigemptyset(&sigact.sa_mask);
  92. sigact.sa_flags = 0;
  93. sigaction(sig, &sigact, &osigact);
  94. # if defined(SIGNALRETURNSINT)
  95. return osigact.sa_handler;
  96. # endif
  97. #else
  98. # if defined(SIGNALRETURNSINT)
  99. return
  100. # endif
  101. signal(sig, handler);
  102. #endif
  103. }
  104. void
  105. sig_child_handler (int sig)
  106. {
  107. int pid, olderrno = errno;
  108. #if !defined(USE_POSIX_WAIT) && (defined(USE_SYSV_SIGNALS) && \
  109. (defined(CRAY) || !defined(SIGTSTP)))
  110. wait (NULL);
  111. #endif
  112. #ifdef SIGNALS_RESET_WHEN_CAUGHT
  113. Signal (SIGCHLD, sig_child_handler);
  114. #endif
  115. /*
  116. * The wait() above must come before re-establishing the signal handler.
  117. * In between this time, a new child might have died. If we can do
  118. * a non-blocking wait, we can check for this race condition. If we
  119. * don't have non-blocking wait, we lose.
  120. */
  121. do
  122. {
  123. #ifdef USE_POSIX_WAIT
  124. pid = waitpid (-1, NULL, WNOHANG);
  125. #else
  126. #if defined(USE_SYSV_SIGNALS) && (defined(CRAY) || !defined(SIGTSTP))
  127. /* cannot do non-blocking wait */
  128. pid = 0;
  129. #else
  130. union wait status;
  131. pid = wait3 (&status, WNOHANG, (struct rusage *)NULL);
  132. #endif
  133. #endif /* USE_POSIX_WAIT else */
  134. }
  135. while (pid > 0);
  136. errno = olderrno;
  137. }
  138. void
  139. sig_term_handler(int sig)
  140. {
  141. XtNoticeSignal(sig_term_id);
  142. }
  143. void
  144. xt_sig_term_handler (XtPointer closure, XtSignalId *id)
  145. {
  146. wantShutdown = 1;
  147. checkpoint_from_signal = 1;
  148. DoSave (SmSaveLocal, SmInteractStyleNone, 1 /* fast */);
  149. }
  150. void sig_usr1_handler(int sig)
  151. {
  152. XtNoticeSignal(sig_usr1_id);
  153. }
  154. void
  155. xt_sig_usr1_handler (XtPointer closure, XtSignalId *id)
  156. {
  157. wantShutdown = 0;
  158. checkpoint_from_signal = 1;
  159. DoSave (SmSaveLocal, SmInteractStyleNone, 0 /* fast */);
  160. }
  161. void
  162. register_signals (XtAppContext appContext)
  163. {
  164. /*
  165. * Ignore SIGPIPE
  166. */
  167. Signal (SIGPIPE, SIG_IGN);
  168. /*
  169. * If child process dies, call our handler
  170. */
  171. Signal (SIGCHLD, sig_child_handler);
  172. /*
  173. * If we get a SIGTERM, do shutdown, fast, local, no interact
  174. */
  175. Signal (SIGTERM, sig_term_handler);
  176. sig_term_id = XtAppAddSignal(appContext, xt_sig_term_handler, NULL);
  177. /*
  178. * If we get a SIGUSR1, do checkpoint, local, no interact
  179. */
  180. Signal (SIGUSR1, sig_usr1_handler);
  181. sig_usr1_id = XtAppAddSignal(appContext, xt_sig_usr1_handler, NULL);
  182. }
  183. int
  184. execute_system_command (char *s)
  185. {
  186. int stat;
  187. #ifdef X_NOT_POSIX
  188. /*
  189. * Non-POSIX system() uses wait(). We must disable our sig child
  190. * handler because if it catches the signal, system() will block
  191. * forever in wait().
  192. */
  193. int pid;
  194. Signal (SIGCHLD, SIG_IGN);
  195. #endif
  196. stat = system (s);
  197. #ifdef X_NOT_POSIX
  198. /*
  199. * Re-enable our sig child handler. We might have missed some signals,
  200. * so do non-blocking waits until there are no signals left.
  201. */
  202. Signal (SIGCHLD, sig_child_handler);
  203. #if !(defined(USE_SYSV_SIGNALS) && (defined(CRAY) || !defined(SIGTSTP)))
  204. do
  205. {
  206. union wait status;
  207. pid = wait3 (&status, WNOHANG, (struct rusage *)NULL);
  208. } while (pid > 0);
  209. #endif
  210. #endif /* X_NOT_POSIX */
  211. return (stat);
  212. }