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