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