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#include <sys/types.h> 408108eb18Smrg 418108eb18Smrg#ifdef X_POSIX_C_SOURCE 428108eb18Smrg#define _POSIX_C_SOURCE X_POSIX_C_SOURCE 438108eb18Smrg#include <signal.h> 448108eb18Smrg#include <sys/wait.h> 458108eb18Smrg#undef _POSIX_C_SOURCE 468108eb18Smrg#else 478108eb18Smrg#if defined(X_NOT_POSIX) || defined(_POSIX_SOURCE) 488108eb18Smrg#include <signal.h> 498108eb18Smrg#include <sys/wait.h> 508108eb18Smrg#else 518108eb18Smrg#define _POSIX_SOURCE 528108eb18Smrg#include <signal.h> 538108eb18Smrg#include <sys/wait.h> 548108eb18Smrg#undef _POSIX_SOURCE 558108eb18Smrg#endif 568108eb18Smrg#endif 578108eb18Smrg#include "list.h" 588108eb18Smrg#include "save.h" 598108eb18Smrg 608108eb18Smrg#ifndef X_NOT_POSIX 618108eb18Smrg#define USE_POSIX_WAIT 628108eb18Smrg#endif 638108eb18Smrg 648d1e6323Smrg#ifdef linux 658108eb18Smrg#define USE_SYSV_SIGNALS 668108eb18Smrg#endif 678108eb18Smrg 688108eb18Smrg#include <stddef.h> 698108eb18Smrg 701a650d1eSmrg#include "xsm.h" 718108eb18Smrg 721a650d1eSmrgint checkpoint_from_signal = 0; 738108eb18Smrg 748108eb18Smrg 758a355152Smrgstatic void 768a355152SmrgSignal(int sig, void (*handler)(int)) 778108eb18Smrg{ 788108eb18Smrg#ifndef X_NOT_POSIX 798108eb18Smrg struct sigaction sigact, osigact; 808108eb18Smrg sigact.sa_handler = handler; 818108eb18Smrg sigemptyset(&sigact.sa_mask); 828108eb18Smrg sigact.sa_flags = 0; 838108eb18Smrg sigaction(sig, &sigact, &osigact); 848108eb18Smrg#else 851a650d1eSmrg signal(sig, handler); 868108eb18Smrg#endif 878108eb18Smrg} 888108eb18Smrg 898108eb18Smrg 908108eb18Smrgvoid 911a650d1eSmrgsig_child_handler (int sig) 928108eb18Smrg 938108eb18Smrg{ 948108eb18Smrg int pid, olderrno = errno; 958108eb18Smrg 968a355152Smrg#if !defined(USE_POSIX_WAIT) && defined(USE_SYSV_SIGNALS) && !defined(SIGTSTP) 978108eb18Smrg wait (NULL); 988108eb18Smrg#endif 998108eb18Smrg 1008108eb18Smrg /* 1018108eb18Smrg * The wait() above must come before re-establishing the signal handler. 1028108eb18Smrg * In between this time, a new child might have died. If we can do 1038108eb18Smrg * a non-blocking wait, we can check for this race condition. If we 1048108eb18Smrg * don't have non-blocking wait, we lose. 1058108eb18Smrg */ 1068108eb18Smrg 1078108eb18Smrg do 1088108eb18Smrg { 1098108eb18Smrg#ifdef USE_POSIX_WAIT 1108108eb18Smrg pid = waitpid (-1, NULL, WNOHANG); 1118108eb18Smrg#else 1128a355152Smrg#if defined(USE_SYSV_SIGNALS) && !defined(SIGTSTP) 1138108eb18Smrg /* cannot do non-blocking wait */ 1148108eb18Smrg pid = 0; 1158108eb18Smrg#else 1168108eb18Smrg union wait status; 1178108eb18Smrg 1188108eb18Smrg pid = wait3 (&status, WNOHANG, (struct rusage *)NULL); 1198108eb18Smrg#endif 1208108eb18Smrg#endif /* USE_POSIX_WAIT else */ 1218108eb18Smrg } 1228108eb18Smrg while (pid > 0); 1238108eb18Smrg errno = olderrno; 1248108eb18Smrg} 1258108eb18Smrg 1268108eb18Smrg 1278108eb18Smrgvoid 1288108eb18Smrgsig_term_handler(int sig) 1298108eb18Smrg{ 1308108eb18Smrg XtNoticeSignal(sig_term_id); 1318108eb18Smrg} 1328108eb18Smrg 1338108eb18Smrgvoid 1348108eb18Smrgxt_sig_term_handler (XtPointer closure, XtSignalId *id) 1358108eb18Smrg 1368108eb18Smrg{ 1378108eb18Smrg wantShutdown = 1; 1388108eb18Smrg checkpoint_from_signal = 1; 1398108eb18Smrg DoSave (SmSaveLocal, SmInteractStyleNone, 1 /* fast */); 1408108eb18Smrg} 1418108eb18Smrg 1428108eb18Smrgvoid sig_usr1_handler(int sig) 1438108eb18Smrg{ 1448108eb18Smrg XtNoticeSignal(sig_usr1_id); 1458108eb18Smrg} 1468108eb18Smrg 1478108eb18Smrgvoid 1488108eb18Smrgxt_sig_usr1_handler (XtPointer closure, XtSignalId *id) 1498108eb18Smrg 1508108eb18Smrg{ 1518108eb18Smrg wantShutdown = 0; 1528108eb18Smrg checkpoint_from_signal = 1; 1538108eb18Smrg DoSave (SmSaveLocal, SmInteractStyleNone, 0 /* fast */); 1548108eb18Smrg} 1558108eb18Smrg 1568108eb18Smrg 1578108eb18Smrg 1588108eb18Smrgvoid 1598108eb18Smrgregister_signals (XtAppContext appContext) 1608108eb18Smrg 1618108eb18Smrg{ 1628108eb18Smrg /* 1638108eb18Smrg * Ignore SIGPIPE 1648108eb18Smrg */ 1658108eb18Smrg 1668108eb18Smrg Signal (SIGPIPE, SIG_IGN); 1678108eb18Smrg 1688108eb18Smrg 1698108eb18Smrg /* 1708108eb18Smrg * If child process dies, call our handler 1718108eb18Smrg */ 1728108eb18Smrg 1738108eb18Smrg Signal (SIGCHLD, sig_child_handler); 1748108eb18Smrg 1758108eb18Smrg 1768108eb18Smrg /* 1778108eb18Smrg * If we get a SIGTERM, do shutdown, fast, local, no interact 1788108eb18Smrg */ 1798108eb18Smrg 1808108eb18Smrg Signal (SIGTERM, sig_term_handler); 1818108eb18Smrg sig_term_id = XtAppAddSignal(appContext, xt_sig_term_handler, NULL); 1828108eb18Smrg 1838108eb18Smrg 1848108eb18Smrg /* 1858108eb18Smrg * If we get a SIGUSR1, do checkpoint, local, no interact 1868108eb18Smrg */ 1878108eb18Smrg 1888108eb18Smrg Signal (SIGUSR1, sig_usr1_handler); 1898108eb18Smrg sig_usr1_id = XtAppAddSignal(appContext, xt_sig_usr1_handler, NULL); 1908108eb18Smrg} 1918108eb18Smrg 1928108eb18Smrg 1938108eb18Smrg 1948108eb18Smrgint 1951a650d1eSmrgexecute_system_command (char *s) 1968108eb18Smrg{ 1978108eb18Smrg int stat; 1988108eb18Smrg 1998108eb18Smrg#ifdef X_NOT_POSIX 2008108eb18Smrg /* 2018108eb18Smrg * Non-POSIX system() uses wait(). We must disable our sig child 2028108eb18Smrg * handler because if it catches the signal, system() will block 2038108eb18Smrg * forever in wait(). 2048108eb18Smrg */ 2058108eb18Smrg 2068108eb18Smrg int pid; 2078108eb18Smrg 2088108eb18Smrg Signal (SIGCHLD, SIG_IGN); 2098108eb18Smrg#endif 2108108eb18Smrg 2118108eb18Smrg stat = system (s); 2128108eb18Smrg 2138108eb18Smrg#ifdef X_NOT_POSIX 2148108eb18Smrg /* 2158108eb18Smrg * Re-enable our sig child handler. We might have missed some signals, 2168108eb18Smrg * so do non-blocking waits until there are no signals left. 2178108eb18Smrg */ 2188108eb18Smrg 2198108eb18Smrg Signal (SIGCHLD, sig_child_handler); 2208108eb18Smrg 2218a355152Smrg#if !(defined(USE_SYSV_SIGNALS) && !defined(SIGTSTP)) 2228108eb18Smrg do 2238108eb18Smrg { 2248108eb18Smrg union wait status; 2258108eb18Smrg 2268108eb18Smrg pid = wait3 (&status, WNOHANG, (struct rusage *)NULL); 2278108eb18Smrg } while (pid > 0); 2288108eb18Smrg#endif 2298108eb18Smrg#endif /* X_NOT_POSIX */ 2308108eb18Smrg 2318108eb18Smrg return (stat); 2328108eb18Smrg} 2338108eb18Smrg 2348108eb18Smrg 235