signals.c revision 8a355152
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#ifndef X_NOT_POSIX 788108eb18Smrg#define USE_POSIX_WAIT 798108eb18Smrg#endif 808108eb18Smrg 818108eb18Smrg#if defined(linux) || defined(SYSV) 828108eb18Smrg#define USE_SYSV_SIGNALS 838108eb18Smrg#endif 848108eb18Smrg 855977a007Smrg#if defined(SCO) 868108eb18Smrg#undef SIGTSTP /* defined, but not the BSD way */ 878108eb18Smrg#endif 888108eb18Smrg 898108eb18Smrg#if defined(X_NOT_POSIX) && defined(SYSV) 908108eb18Smrg#define SIGNALS_RESET_WHEN_CAUGHT 918108eb18Smrg#endif 928108eb18Smrg 938108eb18Smrg#include <stddef.h> 948108eb18Smrg 951a650d1eSmrg#include "xsm.h" 968108eb18Smrg 971a650d1eSmrgint checkpoint_from_signal = 0; 988108eb18Smrg 998108eb18Smrg 1008a355152Smrgstatic void 1018a355152SmrgSignal(int sig, void (*handler)(int)) 1028108eb18Smrg{ 1038108eb18Smrg#ifndef X_NOT_POSIX 1048108eb18Smrg struct sigaction sigact, osigact; 1058108eb18Smrg sigact.sa_handler = handler; 1068108eb18Smrg sigemptyset(&sigact.sa_mask); 1078108eb18Smrg sigact.sa_flags = 0; 1088108eb18Smrg sigaction(sig, &sigact, &osigact); 1098108eb18Smrg#else 1101a650d1eSmrg signal(sig, handler); 1118108eb18Smrg#endif 1128108eb18Smrg} 1138108eb18Smrg 1148108eb18Smrg 1158108eb18Smrgvoid 1161a650d1eSmrgsig_child_handler (int sig) 1178108eb18Smrg 1188108eb18Smrg{ 1198108eb18Smrg int pid, olderrno = errno; 1208108eb18Smrg 1218a355152Smrg#if !defined(USE_POSIX_WAIT) && defined(USE_SYSV_SIGNALS) && !defined(SIGTSTP) 1228108eb18Smrg wait (NULL); 1238108eb18Smrg#endif 1248108eb18Smrg 1258108eb18Smrg#ifdef SIGNALS_RESET_WHEN_CAUGHT 1268108eb18Smrg Signal (SIGCHLD, sig_child_handler); 1278108eb18Smrg#endif 1288108eb18Smrg 1298108eb18Smrg /* 1308108eb18Smrg * The wait() above must come before re-establishing the signal handler. 1318108eb18Smrg * In between this time, a new child might have died. If we can do 1328108eb18Smrg * a non-blocking wait, we can check for this race condition. If we 1338108eb18Smrg * don't have non-blocking wait, we lose. 1348108eb18Smrg */ 1358108eb18Smrg 1368108eb18Smrg do 1378108eb18Smrg { 1388108eb18Smrg#ifdef USE_POSIX_WAIT 1398108eb18Smrg pid = waitpid (-1, NULL, WNOHANG); 1408108eb18Smrg#else 1418a355152Smrg#if defined(USE_SYSV_SIGNALS) && !defined(SIGTSTP) 1428108eb18Smrg /* cannot do non-blocking wait */ 1438108eb18Smrg pid = 0; 1448108eb18Smrg#else 1458108eb18Smrg union wait status; 1468108eb18Smrg 1478108eb18Smrg pid = wait3 (&status, WNOHANG, (struct rusage *)NULL); 1488108eb18Smrg#endif 1498108eb18Smrg#endif /* USE_POSIX_WAIT else */ 1508108eb18Smrg } 1518108eb18Smrg while (pid > 0); 1528108eb18Smrg errno = olderrno; 1538108eb18Smrg} 1548108eb18Smrg 1558108eb18Smrg 1568108eb18Smrgvoid 1578108eb18Smrgsig_term_handler(int sig) 1588108eb18Smrg{ 1598108eb18Smrg XtNoticeSignal(sig_term_id); 1608108eb18Smrg} 1618108eb18Smrg 1628108eb18Smrgvoid 1638108eb18Smrgxt_sig_term_handler (XtPointer closure, XtSignalId *id) 1648108eb18Smrg 1658108eb18Smrg{ 1668108eb18Smrg wantShutdown = 1; 1678108eb18Smrg checkpoint_from_signal = 1; 1688108eb18Smrg DoSave (SmSaveLocal, SmInteractStyleNone, 1 /* fast */); 1698108eb18Smrg} 1708108eb18Smrg 1718108eb18Smrgvoid sig_usr1_handler(int sig) 1728108eb18Smrg{ 1738108eb18Smrg XtNoticeSignal(sig_usr1_id); 1748108eb18Smrg} 1758108eb18Smrg 1768108eb18Smrgvoid 1778108eb18Smrgxt_sig_usr1_handler (XtPointer closure, XtSignalId *id) 1788108eb18Smrg 1798108eb18Smrg{ 1808108eb18Smrg wantShutdown = 0; 1818108eb18Smrg checkpoint_from_signal = 1; 1828108eb18Smrg DoSave (SmSaveLocal, SmInteractStyleNone, 0 /* fast */); 1838108eb18Smrg} 1848108eb18Smrg 1858108eb18Smrg 1868108eb18Smrg 1878108eb18Smrgvoid 1888108eb18Smrgregister_signals (XtAppContext appContext) 1898108eb18Smrg 1908108eb18Smrg{ 1918108eb18Smrg /* 1928108eb18Smrg * Ignore SIGPIPE 1938108eb18Smrg */ 1948108eb18Smrg 1958108eb18Smrg Signal (SIGPIPE, SIG_IGN); 1968108eb18Smrg 1978108eb18Smrg 1988108eb18Smrg /* 1998108eb18Smrg * If child process dies, call our handler 2008108eb18Smrg */ 2018108eb18Smrg 2028108eb18Smrg Signal (SIGCHLD, sig_child_handler); 2038108eb18Smrg 2048108eb18Smrg 2058108eb18Smrg /* 2068108eb18Smrg * If we get a SIGTERM, do shutdown, fast, local, no interact 2078108eb18Smrg */ 2088108eb18Smrg 2098108eb18Smrg Signal (SIGTERM, sig_term_handler); 2108108eb18Smrg sig_term_id = XtAppAddSignal(appContext, xt_sig_term_handler, NULL); 2118108eb18Smrg 2128108eb18Smrg 2138108eb18Smrg /* 2148108eb18Smrg * If we get a SIGUSR1, do checkpoint, local, no interact 2158108eb18Smrg */ 2168108eb18Smrg 2178108eb18Smrg Signal (SIGUSR1, sig_usr1_handler); 2188108eb18Smrg sig_usr1_id = XtAppAddSignal(appContext, xt_sig_usr1_handler, NULL); 2198108eb18Smrg} 2208108eb18Smrg 2218108eb18Smrg 2228108eb18Smrg 2238108eb18Smrgint 2241a650d1eSmrgexecute_system_command (char *s) 2258108eb18Smrg{ 2268108eb18Smrg int stat; 2278108eb18Smrg 2288108eb18Smrg#ifdef X_NOT_POSIX 2298108eb18Smrg /* 2308108eb18Smrg * Non-POSIX system() uses wait(). We must disable our sig child 2318108eb18Smrg * handler because if it catches the signal, system() will block 2328108eb18Smrg * forever in wait(). 2338108eb18Smrg */ 2348108eb18Smrg 2358108eb18Smrg int pid; 2368108eb18Smrg 2378108eb18Smrg Signal (SIGCHLD, SIG_IGN); 2388108eb18Smrg#endif 2398108eb18Smrg 2408108eb18Smrg stat = system (s); 2418108eb18Smrg 2428108eb18Smrg#ifdef X_NOT_POSIX 2438108eb18Smrg /* 2448108eb18Smrg * Re-enable our sig child handler. We might have missed some signals, 2458108eb18Smrg * so do non-blocking waits until there are no signals left. 2468108eb18Smrg */ 2478108eb18Smrg 2488108eb18Smrg Signal (SIGCHLD, sig_child_handler); 2498108eb18Smrg 2508a355152Smrg#if !(defined(USE_SYSV_SIGNALS) && !defined(SIGTSTP)) 2518108eb18Smrg do 2528108eb18Smrg { 2538108eb18Smrg union wait status; 2548108eb18Smrg 2558108eb18Smrg pid = wait3 (&status, WNOHANG, (struct rusage *)NULL); 2568108eb18Smrg } while (pid > 0); 2578108eb18Smrg#endif 2588108eb18Smrg#endif /* X_NOT_POSIX */ 2598108eb18Smrg 2608108eb18Smrg return (stat); 2618108eb18Smrg} 2628108eb18Smrg 2638108eb18Smrg 264