#include <stdlib.h>
#include <X11/Xos.h>
#include <X11/Xfuncs.h>
#include <X11/Intrinsic.h>
#include <X11/SM/SMlib.h>
#include "save.h"
#include <errno.h>
#ifdef USG
#ifndef __TYPES__
#include <sys/types.h>
#define __TYPES__
#endif
#else
#if defined(_POSIX_SOURCE) && defined(MOTOROLA)
#undef _POSIX_SOURCE
#include <sys/types.h>
#define _POSIX_SOURCE
#else
#include <sys/types.h>
#endif
#endif
#ifdef X_POSIX_C_SOURCE
#define _POSIX_C_SOURCE X_POSIX_C_SOURCE
#include <signal.h>
#include <sys/wait.h>
#undef _POSIX_C_SOURCE
#else
#if defined(X_NOT_POSIX) || defined(_POSIX_SOURCE)
#include <signal.h>
#include <sys/wait.h>
#else
#define _POSIX_SOURCE
#include <signal.h>
#ifdef SCO325
#include <sys/procset.h>
#include <sys/siginfo.h>
#endif
#include <sys/wait.h>
#undef _POSIX_SOURCE
#endif
#endif
#include "list.h"
#include "save.h"
#if defined(X_NOT_POSIX) && defined(SIGNALRETURNSINT)
#define SIGVAL int
#else
#define SIGVAL void
#endif
#ifndef X_NOT_POSIX
#define USE_POSIX_WAIT
#endif
#if defined(linux) || defined(SYSV)
#define USE_SYSV_SIGNALS
#endif
#if defined(SCO) || defined(ISC)
#undef SIGTSTP
#endif
#if defined(X_NOT_POSIX) && defined(SYSV)
#define SIGNALS_RESET_WHEN_CAUGHT
#endif
#include <stddef.h>
int checkpoint_from_signal = 0;
extern XtSignalId sig_term_id, sig_usr1_id;
extern Bool wantShutdown;
SIGVAL (*Signal (sig, handler))()
int sig;
SIGVAL (*handler)();
{
#ifndef X_NOT_POSIX
struct sigaction sigact, osigact;
sigact.sa_handler = handler;
sigemptyset(&sigact.sa_mask);
sigact.sa_flags = 0;
sigaction(sig, &sigact, &osigact);
return osigact.sa_handler;
#else
return signal(sig, handler);
#endif
}
void
sig_child_handler (XtPointer closure, XtSignalId id)
{
int pid, olderrno = errno;
#if !defined(USE_POSIX_WAIT) && (defined(USE_SYSV_SIGNALS) && \
(defined(CRAY) || !defined(SIGTSTP)))
wait (NULL);
#endif
#ifdef SIGNALS_RESET_WHEN_CAUGHT
Signal (SIGCHLD, sig_child_handler);
#endif
do
{
#ifdef USE_POSIX_WAIT
pid = waitpid (-1, NULL, WNOHANG);
#else
#if defined(USE_SYSV_SIGNALS) && (defined(CRAY) || !defined(SIGTSTP))
pid = 0;
#else
union wait status;
pid = wait3 (&status, WNOHANG, (struct rusage *)NULL);
#endif
#endif
}
while (pid > 0);
errno = olderrno;
}
void
sig_term_handler(int sig)
{
XtNoticeSignal(sig_term_id);
}
void
xt_sig_term_handler (XtPointer closure, XtSignalId *id)
{
wantShutdown = 1;
checkpoint_from_signal = 1;
DoSave (SmSaveLocal, SmInteractStyleNone, 1 );
}
void sig_usr1_handler(int sig)
{
XtNoticeSignal(sig_usr1_id);
}
void
xt_sig_usr1_handler (XtPointer closure, XtSignalId *id)
{
wantShutdown = 0;
checkpoint_from_signal = 1;
DoSave (SmSaveLocal, SmInteractStyleNone, 0 );
}
void
register_signals (XtAppContext appContext)
{
Signal (SIGPIPE, SIG_IGN);
Signal (SIGCHLD, sig_child_handler);
Signal (SIGTERM, sig_term_handler);
sig_term_id = XtAppAddSignal(appContext, xt_sig_term_handler, NULL);
Signal (SIGUSR1, sig_usr1_handler);
sig_usr1_id = XtAppAddSignal(appContext, xt_sig_usr1_handler, NULL);
}
int
execute_system_command (s)
char *s;
{
int stat;
#ifdef X_NOT_POSIX
int pid;
Signal (SIGCHLD, SIG_IGN);
#endif
stat = system (s);
#ifdef X_NOT_POSIX
Signal (SIGCHLD, sig_child_handler);
#if !(defined(USE_SYSV_SIGNALS) && (defined(CRAY) || !defined(SIGTSTP)))
do
{
union wait status;
pid = wait3 (&status, WNOHANG, (struct rusage *)NULL);
} while (pid > 0);
#endif
#endif
return (stat);
}