signals.c revision 1a650d1e
18108eb18Smrg/* $Xorg: signals.c,v 1.4 2001/02/09 02:06:01 xorgcvs Exp $ */ 28108eb18Smrg/****************************************************************************** 38108eb18Smrg 48108eb18SmrgCopyright 1994, 1998 The Open Group 58108eb18Smrg 68108eb18SmrgPermission to use, copy, modify, distribute, and sell this software and its 78108eb18Smrgdocumentation for any purpose is hereby granted without fee, provided that 88108eb18Smrgthe above copyright notice appear in all copies and that both that 98108eb18Smrgcopyright notice and this permission notice appear in supporting 108108eb18Smrgdocumentation. 118108eb18Smrg 128108eb18SmrgThe above copyright notice and this permission notice shall be included in 138108eb18Smrgall copies or substantial portions of the Software. 148108eb18Smrg 158108eb18SmrgTHE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 168108eb18SmrgIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 178108eb18SmrgFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 188108eb18SmrgOPEN GROUP BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN 198108eb18SmrgAN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN 208108eb18SmrgCONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 218108eb18Smrg 228108eb18SmrgExcept as contained in this notice, the name of The Open Group shall not be 238108eb18Smrgused in advertising or otherwise to promote the sale, use or other dealings 248108eb18Smrgin this Software without prior written authorization from The Open Group. 258108eb18Smrg******************************************************************************/ 268108eb18Smrg/* $XFree86: xc/programs/xsm/signals.c,v 3.5 2001/12/08 18:33:45 herrb Exp $ */ 278108eb18Smrg 288108eb18Smrg#include <stdlib.h> 298108eb18Smrg 308108eb18Smrg#include <X11/Xos.h> 318108eb18Smrg#include <X11/Xfuncs.h> 328108eb18Smrg#include <X11/Intrinsic.h> 338108eb18Smrg 348108eb18Smrg#include <X11/SM/SMlib.h> 358108eb18Smrg 368108eb18Smrg#include "save.h" 378108eb18Smrg 388108eb18Smrg#include <errno.h> 398108eb18Smrg#ifdef USG 408108eb18Smrg#ifndef __TYPES__ 418108eb18Smrg#include <sys/types.h> /* forgot to protect it... */ 428108eb18Smrg#define __TYPES__ 438108eb18Smrg#endif /* __TYPES__ */ 448108eb18Smrg#else 458108eb18Smrg#if defined(_POSIX_SOURCE) && defined(MOTOROLA) 468108eb18Smrg#undef _POSIX_SOURCE 478108eb18Smrg#include <sys/types.h> 488108eb18Smrg#define _POSIX_SOURCE 498108eb18Smrg#else 508108eb18Smrg#include <sys/types.h> 518108eb18Smrg#endif 528108eb18Smrg#endif /* USG */ 538108eb18Smrg 548108eb18Smrg#ifdef X_POSIX_C_SOURCE 558108eb18Smrg#define _POSIX_C_SOURCE X_POSIX_C_SOURCE 568108eb18Smrg#include <signal.h> 578108eb18Smrg#include <sys/wait.h> 588108eb18Smrg#undef _POSIX_C_SOURCE 598108eb18Smrg#else 608108eb18Smrg#if defined(X_NOT_POSIX) || defined(_POSIX_SOURCE) 618108eb18Smrg#include <signal.h> 628108eb18Smrg#include <sys/wait.h> 638108eb18Smrg#else 648108eb18Smrg#define _POSIX_SOURCE 658108eb18Smrg#include <signal.h> 668108eb18Smrg#ifdef SCO325 678108eb18Smrg#include <sys/procset.h> 688108eb18Smrg#include <sys/siginfo.h> 698108eb18Smrg#endif 708108eb18Smrg#include <sys/wait.h> 718108eb18Smrg#undef _POSIX_SOURCE 728108eb18Smrg#endif 738108eb18Smrg#endif 748108eb18Smrg#include "list.h" 758108eb18Smrg#include "save.h" 768108eb18Smrg 778108eb18Smrg#if defined(X_NOT_POSIX) && defined(SIGNALRETURNSINT) 788108eb18Smrg#define SIGVAL int 798108eb18Smrg#else 808108eb18Smrg#define SIGVAL void 818108eb18Smrg#endif 828108eb18Smrg 838108eb18Smrg#ifndef X_NOT_POSIX 848108eb18Smrg#define USE_POSIX_WAIT 858108eb18Smrg#endif 868108eb18Smrg 878108eb18Smrg#if defined(linux) || defined(SYSV) 888108eb18Smrg#define USE_SYSV_SIGNALS 898108eb18Smrg#endif 908108eb18Smrg 918108eb18Smrg#if defined(SCO) || defined(ISC) 928108eb18Smrg#undef SIGTSTP /* defined, but not the BSD way */ 938108eb18Smrg#endif 948108eb18Smrg 958108eb18Smrg#if defined(X_NOT_POSIX) && defined(SYSV) 968108eb18Smrg#define SIGNALS_RESET_WHEN_CAUGHT 978108eb18Smrg#endif 988108eb18Smrg 998108eb18Smrg#include <stddef.h> 1008108eb18Smrg 1011a650d1eSmrg#include "xsm.h" 1028108eb18Smrg 1031a650d1eSmrgint checkpoint_from_signal = 0; 1048108eb18Smrg 1058108eb18Smrg 1061a650d1eSmrgstatic SIGVAL 1071a650d1eSmrgSignal(int sig, SIGVAL (*handler)(int)) 1088108eb18Smrg{ 1098108eb18Smrg#ifndef X_NOT_POSIX 1108108eb18Smrg struct sigaction sigact, osigact; 1118108eb18Smrg sigact.sa_handler = handler; 1128108eb18Smrg sigemptyset(&sigact.sa_mask); 1138108eb18Smrg sigact.sa_flags = 0; 1148108eb18Smrg sigaction(sig, &sigact, &osigact); 1151a650d1eSmrg# if defined(SIGNALRETURNSINT) 1168108eb18Smrg return osigact.sa_handler; 1171a650d1eSmrg# endif 1188108eb18Smrg#else 1191a650d1eSmrg# if defined(SIGNALRETURNSINT) 1201a650d1eSmrg return 1211a650d1eSmrg# endif 1221a650d1eSmrg signal(sig, handler); 1238108eb18Smrg#endif 1248108eb18Smrg} 1258108eb18Smrg 1268108eb18Smrg 1278108eb18Smrgvoid 1281a650d1eSmrgsig_child_handler (int sig) 1298108eb18Smrg 1308108eb18Smrg{ 1318108eb18Smrg int pid, olderrno = errno; 1328108eb18Smrg 1338108eb18Smrg#if !defined(USE_POSIX_WAIT) && (defined(USE_SYSV_SIGNALS) && \ 1348108eb18Smrg (defined(CRAY) || !defined(SIGTSTP))) 1358108eb18Smrg wait (NULL); 1368108eb18Smrg#endif 1378108eb18Smrg 1388108eb18Smrg#ifdef SIGNALS_RESET_WHEN_CAUGHT 1398108eb18Smrg Signal (SIGCHLD, sig_child_handler); 1408108eb18Smrg#endif 1418108eb18Smrg 1428108eb18Smrg /* 1438108eb18Smrg * The wait() above must come before re-establishing the signal handler. 1448108eb18Smrg * In between this time, a new child might have died. If we can do 1458108eb18Smrg * a non-blocking wait, we can check for this race condition. If we 1468108eb18Smrg * don't have non-blocking wait, we lose. 1478108eb18Smrg */ 1488108eb18Smrg 1498108eb18Smrg do 1508108eb18Smrg { 1518108eb18Smrg#ifdef USE_POSIX_WAIT 1528108eb18Smrg pid = waitpid (-1, NULL, WNOHANG); 1538108eb18Smrg#else 1548108eb18Smrg#if defined(USE_SYSV_SIGNALS) && (defined(CRAY) || !defined(SIGTSTP)) 1558108eb18Smrg /* cannot do non-blocking wait */ 1568108eb18Smrg pid = 0; 1578108eb18Smrg#else 1588108eb18Smrg union wait status; 1598108eb18Smrg 1608108eb18Smrg pid = wait3 (&status, WNOHANG, (struct rusage *)NULL); 1618108eb18Smrg#endif 1628108eb18Smrg#endif /* USE_POSIX_WAIT else */ 1638108eb18Smrg } 1648108eb18Smrg while (pid > 0); 1658108eb18Smrg errno = olderrno; 1668108eb18Smrg} 1678108eb18Smrg 1688108eb18Smrg 1698108eb18Smrgvoid 1708108eb18Smrgsig_term_handler(int sig) 1718108eb18Smrg{ 1728108eb18Smrg XtNoticeSignal(sig_term_id); 1738108eb18Smrg} 1748108eb18Smrg 1758108eb18Smrgvoid 1768108eb18Smrgxt_sig_term_handler (XtPointer closure, XtSignalId *id) 1778108eb18Smrg 1788108eb18Smrg{ 1798108eb18Smrg wantShutdown = 1; 1808108eb18Smrg checkpoint_from_signal = 1; 1818108eb18Smrg DoSave (SmSaveLocal, SmInteractStyleNone, 1 /* fast */); 1828108eb18Smrg} 1838108eb18Smrg 1848108eb18Smrgvoid sig_usr1_handler(int sig) 1858108eb18Smrg{ 1868108eb18Smrg XtNoticeSignal(sig_usr1_id); 1878108eb18Smrg} 1888108eb18Smrg 1898108eb18Smrgvoid 1908108eb18Smrgxt_sig_usr1_handler (XtPointer closure, XtSignalId *id) 1918108eb18Smrg 1928108eb18Smrg{ 1938108eb18Smrg wantShutdown = 0; 1948108eb18Smrg checkpoint_from_signal = 1; 1958108eb18Smrg DoSave (SmSaveLocal, SmInteractStyleNone, 0 /* fast */); 1968108eb18Smrg} 1978108eb18Smrg 1988108eb18Smrg 1998108eb18Smrg 2008108eb18Smrgvoid 2018108eb18Smrgregister_signals (XtAppContext appContext) 2028108eb18Smrg 2038108eb18Smrg{ 2048108eb18Smrg /* 2058108eb18Smrg * Ignore SIGPIPE 2068108eb18Smrg */ 2078108eb18Smrg 2088108eb18Smrg Signal (SIGPIPE, SIG_IGN); 2098108eb18Smrg 2108108eb18Smrg 2118108eb18Smrg /* 2128108eb18Smrg * If child process dies, call our handler 2138108eb18Smrg */ 2148108eb18Smrg 2158108eb18Smrg Signal (SIGCHLD, sig_child_handler); 2168108eb18Smrg 2178108eb18Smrg 2188108eb18Smrg /* 2198108eb18Smrg * If we get a SIGTERM, do shutdown, fast, local, no interact 2208108eb18Smrg */ 2218108eb18Smrg 2228108eb18Smrg Signal (SIGTERM, sig_term_handler); 2238108eb18Smrg sig_term_id = XtAppAddSignal(appContext, xt_sig_term_handler, NULL); 2248108eb18Smrg 2258108eb18Smrg 2268108eb18Smrg /* 2278108eb18Smrg * If we get a SIGUSR1, do checkpoint, local, no interact 2288108eb18Smrg */ 2298108eb18Smrg 2308108eb18Smrg Signal (SIGUSR1, sig_usr1_handler); 2318108eb18Smrg sig_usr1_id = XtAppAddSignal(appContext, xt_sig_usr1_handler, NULL); 2328108eb18Smrg} 2338108eb18Smrg 2348108eb18Smrg 2358108eb18Smrg 2368108eb18Smrgint 2371a650d1eSmrgexecute_system_command (char *s) 2388108eb18Smrg{ 2398108eb18Smrg int stat; 2408108eb18Smrg 2418108eb18Smrg#ifdef X_NOT_POSIX 2428108eb18Smrg /* 2438108eb18Smrg * Non-POSIX system() uses wait(). We must disable our sig child 2448108eb18Smrg * handler because if it catches the signal, system() will block 2458108eb18Smrg * forever in wait(). 2468108eb18Smrg */ 2478108eb18Smrg 2488108eb18Smrg int pid; 2498108eb18Smrg 2508108eb18Smrg Signal (SIGCHLD, SIG_IGN); 2518108eb18Smrg#endif 2528108eb18Smrg 2538108eb18Smrg stat = system (s); 2548108eb18Smrg 2558108eb18Smrg#ifdef X_NOT_POSIX 2568108eb18Smrg /* 2578108eb18Smrg * Re-enable our sig child handler. We might have missed some signals, 2588108eb18Smrg * so do non-blocking waits until there are no signals left. 2598108eb18Smrg */ 2608108eb18Smrg 2618108eb18Smrg Signal (SIGCHLD, sig_child_handler); 2628108eb18Smrg 2638108eb18Smrg#if !(defined(USE_SYSV_SIGNALS) && (defined(CRAY) || !defined(SIGTSTP))) 2648108eb18Smrg do 2658108eb18Smrg { 2668108eb18Smrg union wait status; 2678108eb18Smrg 2688108eb18Smrg pid = wait3 (&status, WNOHANG, (struct rusage *)NULL); 2698108eb18Smrg } while (pid > 0); 2708108eb18Smrg#endif 2718108eb18Smrg#endif /* X_NOT_POSIX */ 2728108eb18Smrg 2738108eb18Smrg return (stat); 2748108eb18Smrg} 2758108eb18Smrg 2768108eb18Smrg 277