mirror of
https://github.com/gryf/wmaker.git
synced 2025-12-19 20:38:08 +01:00
fixed some signal handling bugs
This commit is contained in:
@@ -7,6 +7,10 @@ Changes since version 0.64.0:
|
|||||||
- added WINDOWS_MENU submenu type for root menu (Bastien Nocera <hadess@hadess.net>)
|
- added WINDOWS_MENU submenu type for root menu (Bastien Nocera <hadess@hadess.net>)
|
||||||
- added kbd shortcuts for icon chooser
|
- added kbd shortcuts for icon chooser
|
||||||
- use Hermes in wrlib
|
- use Hermes in wrlib
|
||||||
|
- removed MOUSE_WS_WHEEL #defines
|
||||||
|
- fixed bug with multibyte text on libc5 systems (Osamu Ajiki <osam-a@astroarts.co.jp>)
|
||||||
|
- fixed race conditions on signal handlers
|
||||||
|
- SIGINT will gently exit, SIGTERM will not be handled
|
||||||
|
|
||||||
Changes since version 0.63.1:
|
Changes since version 0.63.1:
|
||||||
.............................
|
.............................
|
||||||
|
|||||||
@@ -4,6 +4,7 @@ Changes since wmaker 0.64.0:
|
|||||||
- made programmatic scroller changes send notifications
|
- made programmatic scroller changes send notifications
|
||||||
- replaced WMSetBoxExpandsToParent with WMSetViewExpands...
|
- replaced WMSetBoxExpandsToParent with WMSetViewExpands...
|
||||||
- added WMGetLabelFont()
|
- added WMGetLabelFont()
|
||||||
|
- added WMAddEternalTimerHandler()
|
||||||
|
|
||||||
changes since wmaker 0.63.1:
|
changes since wmaker 0.63.1:
|
||||||
............................
|
............................
|
||||||
|
|||||||
@@ -604,7 +604,7 @@ char *WMGetApplicationName();
|
|||||||
char *WMPathForResourceOfType(char *resource, char *ext);
|
char *WMPathForResourceOfType(char *resource, char *ext);
|
||||||
|
|
||||||
|
|
||||||
WMScreen *WMOpenScreen();
|
WMScreen *WMOpenScreen(const char *display);
|
||||||
|
|
||||||
WMScreen *WMCreateScreenWithRContext(Display *display, int screen,
|
WMScreen *WMCreateScreenWithRContext(Display *display, int screen,
|
||||||
RContext *context);
|
RContext *context);
|
||||||
@@ -658,6 +658,9 @@ void WMMaskEvent(Display *dpy, long mask, XEvent *event);
|
|||||||
WMHandlerID WMAddTimerHandler(int milliseconds, WMCallback *callback,
|
WMHandlerID WMAddTimerHandler(int milliseconds, WMCallback *callback,
|
||||||
void *cdata);
|
void *cdata);
|
||||||
|
|
||||||
|
WMHandlerID WMAddEternalTimerHandler(int milliseconds, WMCallback *callback,
|
||||||
|
void *cdata);
|
||||||
|
|
||||||
void WMDeleteTimerWithClientData(void *cdata);
|
void WMDeleteTimerWithClientData(void *cdata);
|
||||||
|
|
||||||
void WMDeleteTimerHandler(WMHandlerID handlerID);
|
void WMDeleteTimerHandler(WMHandlerID handlerID);
|
||||||
|
|||||||
@@ -528,9 +528,9 @@ void W_HandleSelectionEvent(XEvent *event);
|
|||||||
|
|
||||||
void W_HandleDNDClientMessage(WMView *toplevel, XClientMessageEvent *event);
|
void W_HandleDNDClientMessage(WMView *toplevel, XClientMessageEvent *event);
|
||||||
|
|
||||||
void W_FlushASAPNotificationQueue();
|
void W_FlushASAPNotificationQueue(void);
|
||||||
|
|
||||||
void W_FlushIdleNotificationQueue();
|
void W_FlushIdleNotificationQueue(void);
|
||||||
|
|
||||||
struct W_Balloon *W_CreateBalloon(WMScreen *scr);
|
struct W_Balloon *W_CreateBalloon(WMScreen *scr);
|
||||||
|
|
||||||
|
|||||||
@@ -38,6 +38,7 @@ typedef struct TimerHandler {
|
|||||||
struct timeval when; /* when to call the callback */
|
struct timeval when; /* when to call the callback */
|
||||||
void *clientData;
|
void *clientData;
|
||||||
struct TimerHandler *next;
|
struct TimerHandler *next;
|
||||||
|
Bool permanent;
|
||||||
} TimerHandler;
|
} TimerHandler;
|
||||||
|
|
||||||
|
|
||||||
@@ -125,6 +126,9 @@ rightNow(struct timeval *tv) {
|
|||||||
(((t1).tv_sec == (t2).tv_sec) \
|
(((t1).tv_sec == (t2).tv_sec) \
|
||||||
&& ((t1).tv_usec > (t2).tv_usec)))
|
&& ((t1).tv_usec > (t2).tv_usec)))
|
||||||
|
|
||||||
|
#define IS_ZERO(tv) (tv.tv_sec == 0 && tv.tv_usec == 0)
|
||||||
|
|
||||||
|
#define SET_ZERO(tv) tv.tv_sec = 0, tv.tv_usec = 0
|
||||||
|
|
||||||
static void
|
static void
|
||||||
addmillisecs(struct timeval *tv, int milliseconds)
|
addmillisecs(struct timeval *tv, int milliseconds)
|
||||||
@@ -136,19 +140,11 @@ addmillisecs(struct timeval *tv, int milliseconds)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
WMHandlerID
|
static void
|
||||||
WMAddTimerHandler(int milliseconds, WMCallback *callback, void *cdata)
|
enqueueTimerHandler(TimerHandler *handler)
|
||||||
{
|
{
|
||||||
TimerHandler *handler, *tmp;
|
TimerHandler *tmp;
|
||||||
|
|
||||||
handler = malloc(sizeof(TimerHandler));
|
|
||||||
if (!handler)
|
|
||||||
return NULL;
|
|
||||||
|
|
||||||
rightNow(&handler->when);
|
|
||||||
addmillisecs(&handler->when, milliseconds);
|
|
||||||
handler->callback = callback;
|
|
||||||
handler->clientData = cdata;
|
|
||||||
/* insert callback in queue, sorted by time left */
|
/* insert callback in queue, sorted by time left */
|
||||||
if (!timerHandler || !IS_AFTER(handler->when, timerHandler->when)) {
|
if (!timerHandler || !IS_AFTER(handler->when, timerHandler->when)) {
|
||||||
/* first in the queue */
|
/* first in the queue */
|
||||||
@@ -162,6 +158,38 @@ WMAddTimerHandler(int milliseconds, WMCallback *callback, void *cdata)
|
|||||||
handler->next = tmp->next;
|
handler->next = tmp->next;
|
||||||
tmp->next = handler;
|
tmp->next = handler;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
WMHandlerID
|
||||||
|
WMAddTimerHandler(int milliseconds, WMCallback *callback, void *cdata)
|
||||||
|
{
|
||||||
|
TimerHandler *handler;
|
||||||
|
|
||||||
|
handler = malloc(sizeof(TimerHandler));
|
||||||
|
if (!handler)
|
||||||
|
return NULL;
|
||||||
|
|
||||||
|
rightNow(&handler->when);
|
||||||
|
addmillisecs(&handler->when, milliseconds);
|
||||||
|
handler->callback = callback;
|
||||||
|
handler->clientData = cdata;
|
||||||
|
handler->permanent = False;
|
||||||
|
|
||||||
|
enqueueTimerHandler(handler);
|
||||||
|
|
||||||
|
return handler;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
WMHandlerID
|
||||||
|
WMAddEternalTimerHandler(int milliseconds, WMCallback *callback, void *cdata)
|
||||||
|
{
|
||||||
|
TimerHandler *handler = WMAddTimerHandler(milliseconds, callback, cdata);
|
||||||
|
|
||||||
|
if (handler != NULL)
|
||||||
|
handler->permanent = True;
|
||||||
|
|
||||||
return handler;
|
return handler;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -177,12 +205,18 @@ WMDeleteTimerWithClientData(void *cdata)
|
|||||||
|
|
||||||
tmp = timerHandler;
|
tmp = timerHandler;
|
||||||
if (tmp->clientData==cdata) {
|
if (tmp->clientData==cdata) {
|
||||||
|
tmp->permanent = False;
|
||||||
|
if (!IS_ZERO(tmp->when)) {
|
||||||
timerHandler = tmp->next;
|
timerHandler = tmp->next;
|
||||||
wfree(tmp);
|
wfree(tmp);
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
while (tmp->next) {
|
while (tmp->next) {
|
||||||
if (tmp->next->clientData==cdata) {
|
if (tmp->next->clientData==cdata) {
|
||||||
handler = tmp->next;
|
handler = tmp->next;
|
||||||
|
handler->permanent = False;
|
||||||
|
if (IS_ZERO(handler->when))
|
||||||
|
break;
|
||||||
tmp->next = handler->next;
|
tmp->next = handler->next;
|
||||||
wfree(handler);
|
wfree(handler);
|
||||||
break;
|
break;
|
||||||
@@ -203,6 +237,12 @@ WMDeleteTimerHandler(WMHandlerID handlerID)
|
|||||||
return;
|
return;
|
||||||
|
|
||||||
tmp = timerHandler;
|
tmp = timerHandler;
|
||||||
|
|
||||||
|
handler->permanent = False;
|
||||||
|
|
||||||
|
if (IS_ZERO(handler->when))
|
||||||
|
return;
|
||||||
|
|
||||||
if (tmp==handler) {
|
if (tmp==handler) {
|
||||||
timerHandler = handler->next;
|
timerHandler = handler->next;
|
||||||
wfree(handler);
|
wfree(handler);
|
||||||
@@ -241,7 +281,6 @@ WMAddIdleHandler(WMCallback *callback, void *cdata)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
void
|
void
|
||||||
WMDeleteIdleHandler(WMHandlerID handlerID)
|
WMDeleteIdleHandler(WMHandlerID handlerID)
|
||||||
{
|
{
|
||||||
@@ -306,6 +345,7 @@ checkIdleHandlers()
|
|||||||
WMBag *handlerCopy;
|
WMBag *handlerCopy;
|
||||||
WMBagIterator iter;
|
WMBagIterator iter;
|
||||||
|
|
||||||
|
|
||||||
if (!idleHandler || WMGetBagItemCount(idleHandler)==0) {
|
if (!idleHandler || WMGetBagItemCount(idleHandler)==0) {
|
||||||
W_FlushIdleNotificationQueue();
|
W_FlushIdleNotificationQueue();
|
||||||
/* make sure an observer in queue didn't added an idle handler */
|
/* make sure an observer in queue didn't added an idle handler */
|
||||||
@@ -349,13 +389,25 @@ checkTimerHandlers()
|
|||||||
|
|
||||||
rightNow(&now);
|
rightNow(&now);
|
||||||
|
|
||||||
while (timerHandler && IS_AFTER(now, timerHandler->when)) {
|
handler = timerHandler;
|
||||||
|
while (handler && IS_AFTER(now, handler->when)) {
|
||||||
|
SET_ZERO(handler->when);
|
||||||
|
(*handler->callback)(handler->clientData);
|
||||||
|
handler = handler->next;
|
||||||
|
}
|
||||||
|
|
||||||
|
while (timerHandler && IS_ZERO(handler->when)) {
|
||||||
handler = timerHandler;
|
handler = timerHandler;
|
||||||
timerHandler = timerHandler->next;
|
timerHandler = timerHandler->next;
|
||||||
handler->next = NULL;
|
|
||||||
(*handler->callback)(handler->clientData);
|
if (handler->permanent) {
|
||||||
|
rightNow(&handler->when);
|
||||||
|
addmillisecs(&handler->when, milliseconds);
|
||||||
|
enqueueTimerHandler(handler);
|
||||||
|
} else {
|
||||||
wfree(handler);
|
wfree(handler);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
W_FlushASAPNotificationQueue();
|
W_FlushASAPNotificationQueue();
|
||||||
}
|
}
|
||||||
@@ -932,7 +984,7 @@ WMNextEvent(Display *dpy, XEvent *event)
|
|||||||
while (XPending(dpy) == 0) {
|
while (XPending(dpy) == 0) {
|
||||||
/* Do idle stuff */
|
/* Do idle stuff */
|
||||||
/* Do idle and timer stuff while there are no timer or X events */
|
/* Do idle and timer stuff while there are no timer or X events */
|
||||||
while (!XPending(dpy) && checkIdleHandlers()) {
|
while (XPending(dpy) == 0 && checkIdleHandlers()) {
|
||||||
/* dispatch timer events */
|
/* dispatch timer events */
|
||||||
checkTimerHandlers();
|
checkTimerHandlers();
|
||||||
}
|
}
|
||||||
@@ -942,7 +994,7 @@ WMNextEvent(Display *dpy, XEvent *event)
|
|||||||
* timer/idle stuff. Or we might block forever waiting for
|
* timer/idle stuff. Or we might block forever waiting for
|
||||||
* an event that already arrived.
|
* an event that already arrived.
|
||||||
*/
|
*/
|
||||||
/* wait to something happen */
|
/* wait for something to happen or a timer to expire */
|
||||||
W_WaitForEvent(dpy, 0);
|
W_WaitForEvent(dpy, 0);
|
||||||
|
|
||||||
/* Check any expired timers */
|
/* Check any expired timers */
|
||||||
|
|||||||
@@ -42,9 +42,10 @@ generalize_xlfd (const char *xlfd)
|
|||||||
char *slant = xlfd_get_element(xlfd, 4);
|
char *slant = xlfd_get_element(xlfd, 4);
|
||||||
char *pxlsz = xlfd_get_element(xlfd, 7);
|
char *pxlsz = xlfd_get_element(xlfd, 7);
|
||||||
|
|
||||||
len = snprintf(NULL, 0, "%s,-*-*-%s-%s-*-*-%s-*-*-*-*-*-*-*,"
|
#define Xstrlen(A) ((A)?strlen(A):0)
|
||||||
"-*-*-*-*-*-*-%s-*-*-*-*-*-*-*,*",
|
len = Xstrlen(xlfd)+Xstrlen(weight)+Xstrlen(slant)+Xstrlen(pxlsz)*2+50;
|
||||||
xlfd, weight, slant, pxlsz, pxlsz);
|
#undef Xstrlen
|
||||||
|
|
||||||
buf = wmalloc(len + 1);
|
buf = wmalloc(len + 1);
|
||||||
snprintf(buf, len + 1, "%s,-*-*-%s-%s-*-*-%s-*-*-*-*-*-*-*,"
|
snprintf(buf, len + 1, "%s,-*-*-%s-%s-*-*-%s-*-*-*-*-*-*-*,"
|
||||||
"-*-*-*-*-*-*-%s-*-*-*-*-*-*-*,*",
|
"-*-*-*-*-*-*-%s-*-*-*-*-*-*-*,*",
|
||||||
|
|||||||
@@ -516,13 +516,13 @@ loadPixmaps(WMScreen *scr)
|
|||||||
|
|
||||||
|
|
||||||
WMScreen*
|
WMScreen*
|
||||||
WMOpenScreen()
|
WMOpenScreen(const char *display)
|
||||||
{
|
{
|
||||||
Display *dpy = XOpenDisplay("");
|
Display *dpy = XOpenDisplay(display);
|
||||||
|
|
||||||
if (!dpy) {
|
if (!dpy) {
|
||||||
wwarning("WINGs: could not open display %s",
|
wwarning("WINGs: could not open display %s",
|
||||||
XDisplayName(""));
|
XDisplayName(display));
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -247,10 +247,22 @@ typedef enum {
|
|||||||
|
|
||||||
|
|
||||||
#define WCHECK_STATE(state) (state == WProgramState)
|
#define WCHECK_STATE(state) (state == WProgramState)
|
||||||
#define WCHANGE_STATE(nstate) \
|
|
||||||
|
|
||||||
|
#define WCHANGE_STATE(nstate) {\
|
||||||
if (WProgramState == WSTATE_NORMAL\
|
if (WProgramState == WSTATE_NORMAL\
|
||||||
|| nstate != WSTATE_MODAL)\
|
|| nstate != WSTATE_MODAL)\
|
||||||
WProgramState = (nstate)
|
WProgramState = (nstate); \
|
||||||
|
if (WProgramSigState != 0)\
|
||||||
|
WProgramState = WProgramSigState;\
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* only call inside signal handlers, with signals blocked */
|
||||||
|
#define SIG_WCHANGE_STATE(nstate) {\
|
||||||
|
WProgramSigState = (nstate);\
|
||||||
|
WProgramState = (nstate);\
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/* notifications */
|
/* notifications */
|
||||||
|
|||||||
@@ -1062,8 +1062,7 @@ handleLogoPush(XEvent *event, void *data)
|
|||||||
static char *msgs[] = {
|
static char *msgs[] = {
|
||||||
"Have a nice day!",
|
"Have a nice day!",
|
||||||
"Focus follow mouse users will burn in hell!!!",
|
"Focus follow mouse users will burn in hell!!!",
|
||||||
"F'ck Canada!!!!",
|
"Mooo Canada!!!!",
|
||||||
"F'ck Bastard Imperialists!!!",
|
|
||||||
"Hi! My name is bobby...",
|
"Hi! My name is bobby...",
|
||||||
"AHH! The neurotic monkeys are after me!",
|
"AHH! The neurotic monkeys are after me!",
|
||||||
"WHAT YOU SAY??",
|
"WHAT YOU SAY??",
|
||||||
|
|||||||
@@ -138,9 +138,11 @@ int wXkbEventBase;
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
/* special flags */
|
/* special flags */
|
||||||
|
char WProgramSigState = 0;
|
||||||
char WProgramState = WSTATE_NORMAL;
|
char WProgramState = WSTATE_NORMAL;
|
||||||
char WDelayedActionSet = 0;
|
char WDelayedActionSet = 0;
|
||||||
|
|
||||||
|
|
||||||
/* temporary stuff */
|
/* temporary stuff */
|
||||||
int wVisualID = -1;
|
int wVisualID = -1;
|
||||||
|
|
||||||
|
|||||||
150
src/startup.c
150
src/startup.c
@@ -228,6 +228,8 @@ handleXIO(Display *xio_dpy)
|
|||||||
static void
|
static void
|
||||||
delayedAction(void *cdata)
|
delayedAction(void *cdata)
|
||||||
{
|
{
|
||||||
|
if (WDelatedActionSet == 0)
|
||||||
|
return;
|
||||||
WDelayedActionSet = 0;
|
WDelayedActionSet = 0;
|
||||||
/*
|
/*
|
||||||
* Make the event dispatcher do whatever it needs to do,
|
* Make the event dispatcher do whatever it needs to do,
|
||||||
@@ -238,6 +240,58 @@ delayedAction(void *cdata)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
*----------------------------------------------------------------------
|
||||||
|
* handleExitSig--
|
||||||
|
* User generated exit signal handler.
|
||||||
|
*----------------------------------------------------------------------
|
||||||
|
*/
|
||||||
|
static RETSIGTYPE
|
||||||
|
handleExitSig(int sig)
|
||||||
|
{
|
||||||
|
sigset_t sigs;
|
||||||
|
|
||||||
|
sigfillset(&sigs);
|
||||||
|
sigprocmask(SIG_BLOCK, &sigs, NULL);
|
||||||
|
|
||||||
|
if (sig == SIGUSR1) {
|
||||||
|
#ifdef SYS_SIGLIST_DECLARED
|
||||||
|
wwarning(_("got signal %i (%s) - restarting\n"), sig, sys_siglist[sig]);
|
||||||
|
#else
|
||||||
|
wwarning(_("got signal %i - restarting\n"), sig);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
SIG_WCHANGE_STATE(WSTATE_NEED_RESTART);
|
||||||
|
/* setup idle handler, so that this will be handled when
|
||||||
|
* the select() is returned becaused of the signal, even if
|
||||||
|
* there are no X events in the queue */
|
||||||
|
WDelayedActionSet = 1;
|
||||||
|
} else if (sig == SIGUSR2) {
|
||||||
|
#ifdef SYS_SIGLIST_DECLARED
|
||||||
|
wwarning(_("got signal %i (%s) - rereading defaults\n"), sig, sys_siglist[sig]);
|
||||||
|
#else
|
||||||
|
wwarning(_("got signal %i - rereading defaults\n"), sig);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
SIG_WCHANGE_STATE(WSTATE_NEED_REREAD);
|
||||||
|
/* setup idle handler, so that this will be handled when
|
||||||
|
* the select() is returned becaused of the signal, even if
|
||||||
|
* there are no X events in the queue */
|
||||||
|
WDelayedActionSet = 1;
|
||||||
|
} else if (sig == SIGINT || sig == SIGHUP) {
|
||||||
|
#ifdef SYS_SIGLIST_DECLARED
|
||||||
|
wwarning(_("got signal %i (%s) - exiting...\n"), sig, sys_siglist[sig]);
|
||||||
|
#else
|
||||||
|
wwarning(_("got signal %i - exiting...\n"), sig);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
SIG_WCHANGE_STATE(WSTATE_NEED_EXIT);
|
||||||
|
|
||||||
|
WDelayedActionSet = 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
sigprocmask(SIG_UNBLOCK, &sigs, NULL);
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
*----------------------------------------------------------------------
|
*----------------------------------------------------------------------
|
||||||
@@ -262,53 +316,6 @@ handleSig(int sig)
|
|||||||
* here. Xlib calls are not reentrant so the integrity of Xlib is
|
* here. Xlib calls are not reentrant so the integrity of Xlib is
|
||||||
* not guaranteed if a Xlib call is made from a signal handler.
|
* not guaranteed if a Xlib call is made from a signal handler.
|
||||||
*/
|
*/
|
||||||
if (sig == SIGUSR1) {
|
|
||||||
#ifdef SYS_SIGLIST_DECLARED
|
|
||||||
wwarning(_("got signal %i (%s) - restarting\n"), sig, sys_siglist[sig]);
|
|
||||||
#else
|
|
||||||
wwarning(_("got signal %i - restarting\n"), sig);
|
|
||||||
#endif
|
|
||||||
|
|
||||||
WCHANGE_STATE(WSTATE_NEED_RESTART);
|
|
||||||
/* setup idle handler, so that this will be handled when
|
|
||||||
* the select() is returned becaused of the signal, even if
|
|
||||||
* there are no X events in the queue */
|
|
||||||
if (!WDelayedActionSet) {
|
|
||||||
WDelayedActionSet = 1;
|
|
||||||
WMAddIdleHandler(delayedAction, NULL);
|
|
||||||
}
|
|
||||||
return;
|
|
||||||
} else if (sig == SIGUSR2) {
|
|
||||||
#ifdef SYS_SIGLIST_DECLARED
|
|
||||||
wwarning(_("got signal %i (%s) - rereading defaults\n"), sig, sys_siglist[sig]);
|
|
||||||
#else
|
|
||||||
wwarning(_("got signal %i - rereading defaults\n"), sig);
|
|
||||||
#endif
|
|
||||||
|
|
||||||
WCHANGE_STATE(WSTATE_NEED_REREAD);
|
|
||||||
/* setup idle handler, so that this will be handled when
|
|
||||||
* the select() is returned becaused of the signal, even if
|
|
||||||
* there are no X events in the queue */
|
|
||||||
if (!WDelayedActionSet) {
|
|
||||||
WDelayedActionSet = 1;
|
|
||||||
WMAddIdleHandler(delayedAction, NULL);
|
|
||||||
}
|
|
||||||
return;
|
|
||||||
} else if (sig == SIGTERM || sig == SIGHUP) {
|
|
||||||
#ifdef SYS_SIGLIST_DECLARED
|
|
||||||
wwarning(_("got signal %i (%s) - exiting...\n"), sig, sys_siglist[sig]);
|
|
||||||
#else
|
|
||||||
wwarning(_("got signal %i - exiting...\n"), sig);
|
|
||||||
#endif
|
|
||||||
|
|
||||||
WCHANGE_STATE(WSTATE_NEED_EXIT);
|
|
||||||
|
|
||||||
if (!WDelayedActionSet) {
|
|
||||||
WDelayedActionSet = 1;
|
|
||||||
WMAddIdleHandler(delayedAction, NULL);
|
|
||||||
}
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
#ifdef SYS_SIGLIST_DECLARED
|
#ifdef SYS_SIGLIST_DECLARED
|
||||||
wfatal(_("got signal %i (%s)\n"), sig, sys_siglist[sig]);
|
wfatal(_("got signal %i (%s)\n"), sig, sys_siglist[sig]);
|
||||||
@@ -333,6 +340,10 @@ handleSig(int sig)
|
|||||||
|
|
||||||
dumpcore = 1;
|
dumpcore = 1;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Yeah, we shouldn't do this, but it's already crashed anyway :P
|
||||||
|
*/
|
||||||
|
|
||||||
#ifndef NO_EMERGENCY_AUTORESTART
|
#ifndef NO_EMERGENCY_AUTORESTART
|
||||||
/* Close the X connection and open a new one. This is to avoid messing
|
/* Close the X connection and open a new one. This is to avoid messing
|
||||||
* Xlib because we call to Xlib functions in a signal handler.
|
* Xlib because we call to Xlib functions in a signal handler.
|
||||||
@@ -384,18 +395,17 @@ handleSig(int sig)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static RETSIGTYPE
|
|
||||||
ignoreSig(int signal)
|
|
||||||
{
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
static RETSIGTYPE
|
static RETSIGTYPE
|
||||||
buryChild(int foo)
|
buryChild(int foo)
|
||||||
{
|
{
|
||||||
pid_t pid;
|
pid_t pid;
|
||||||
int status;
|
int status;
|
||||||
|
int save_errno = errno;
|
||||||
|
sigset_t sigs;
|
||||||
|
|
||||||
|
sigfillset(&sigs);
|
||||||
|
/* Block signals so that NotifyDeadProcess() doesn't get fux0red */
|
||||||
|
sigprocmask(SIG_BLOCK, &sigs, NULL);
|
||||||
|
|
||||||
/* R.I.P. */
|
/* R.I.P. */
|
||||||
/* If 2 or more kids exit in a small time window, before this handler gets
|
/* If 2 or more kids exit in a small time window, before this handler gets
|
||||||
@@ -406,15 +416,13 @@ buryChild(int foo)
|
|||||||
*/
|
*/
|
||||||
while ((pid=waitpid(-1, &status, WNOHANG))>0 || (pid<0 && errno==EINTR)) {
|
while ((pid=waitpid(-1, &status, WNOHANG))>0 || (pid<0 && errno==EINTR)) {
|
||||||
NotifyDeadProcess(pid, WEXITSTATUS(status));
|
NotifyDeadProcess(pid, WEXITSTATUS(status));
|
||||||
/*
|
}
|
||||||
* Make sure that the kid will be buried even if there are
|
|
||||||
* no events in the X event queue
|
|
||||||
*/
|
|
||||||
if (!WDelayedActionSet) {
|
|
||||||
WDelayedActionSet = 1;
|
WDelayedActionSet = 1;
|
||||||
WMAddIdleHandler(delayedAction, NULL);
|
|
||||||
}
|
sigprocmask(SIG_UNBLOCK, &sigs, NULL);
|
||||||
}
|
|
||||||
|
errno = save_errno;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -790,32 +798,34 @@ StartUp(Bool defaultScreenOnly)
|
|||||||
wCursor[WCUR_TEXT] = XCreateFontCursor(dpy, XC_xterm); /* odd name???*/
|
wCursor[WCUR_TEXT] = XCreateFontCursor(dpy, XC_xterm); /* odd name???*/
|
||||||
wCursor[WCUR_SELECT] = XCreateFontCursor(dpy, XC_cross);
|
wCursor[WCUR_SELECT] = XCreateFontCursor(dpy, XC_cross);
|
||||||
|
|
||||||
|
/* signal handler stuff that gets called when a signal is caught */
|
||||||
|
WMAddEternalTimerHandler(500, delayedAction, NULL);
|
||||||
|
|
||||||
/* emergency exit... */
|
/* emergency exit... */
|
||||||
sig_action.sa_handler = handleSig;
|
sig_action.sa_handler = handleSig;
|
||||||
sigemptyset(&sig_action.sa_mask);
|
sigemptyset(&sig_action.sa_mask);
|
||||||
|
|
||||||
/* Here we don't care about SA_RESTART since these signals will close
|
sig_action.sa_flags = SA_RESTART;
|
||||||
* wmaker anyway.
|
|
||||||
* -Dan */
|
|
||||||
sig_action.sa_flags = 0;
|
|
||||||
sigaction(SIGINT, &sig_action, NULL);
|
|
||||||
sigaction(SIGTERM, &sig_action, NULL);
|
|
||||||
sigaction(SIGHUP, &sig_action, NULL);
|
|
||||||
sigaction(SIGQUIT, &sig_action, NULL);
|
sigaction(SIGQUIT, &sig_action, NULL);
|
||||||
sigaction(SIGSEGV, &sig_action, NULL);
|
sigaction(SIGSEGV, &sig_action, NULL);
|
||||||
sigaction(SIGBUS, &sig_action, NULL);
|
sigaction(SIGBUS, &sig_action, NULL);
|
||||||
sigaction(SIGFPE, &sig_action, NULL);
|
sigaction(SIGFPE, &sig_action, NULL);
|
||||||
sigaction(SIGABRT, &sig_action, NULL);
|
sigaction(SIGABRT, &sig_action, NULL);
|
||||||
|
|
||||||
|
sig_action.sa_handler = handleExitSig;
|
||||||
|
|
||||||
/* Here we set SA_RESTART for safety, because SIGUSR1 may not be handled
|
/* Here we set SA_RESTART for safety, because SIGUSR1 may not be handled
|
||||||
* immediately.
|
* immediately.
|
||||||
* -Dan */
|
* -Dan */
|
||||||
sig_action.sa_flags = SA_RESTART;
|
sig_action.sa_flags = SA_RESTART;
|
||||||
|
/* sigaction(SIGTERM, &sig_action, NULL);*/
|
||||||
|
sigaction(SIGINT, &sig_action, NULL);
|
||||||
|
sigaction(SIGHUP, &sig_action, NULL);
|
||||||
sigaction(SIGUSR1, &sig_action, NULL);
|
sigaction(SIGUSR1, &sig_action, NULL);
|
||||||
sigaction(SIGUSR2, &sig_action, NULL);
|
sigaction(SIGUSR2, &sig_action, NULL);
|
||||||
|
|
||||||
/* ignore dead pipe */
|
/* ignore dead pipe */
|
||||||
sig_action.sa_handler = ignoreSig;
|
sig_action.sa_handler = SIG_IGN;
|
||||||
sig_action.sa_flags = SA_RESTART;
|
sig_action.sa_flags = SA_RESTART;
|
||||||
sigaction(SIGPIPE, &sig_action, NULL);
|
sigaction(SIGPIPE, &sig_action, NULL);
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user