1 /* monitor.c - monitors the wmaker process
3 * Window Maker window manager
5 * Copyright (c) 1997-2004 Alfredo K. Kojima
7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License as published by
9 * the Free Software Foundation; either version 2 of the License, or
10 * (at your option) any later version.
12 * This program is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 * GNU General Public License for more details.
17 * You should have received a copy of the GNU General Public License
18 * along with this program; if not, write to the Free Software
19 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307,
30 #include <sys/signal.h>
34 #include <X11/Xutil.h>
35 #include <X11/Xproto.h>
37 #include "WindowMaker.h"
43 /****** Global Variables ******/
45 extern WPreferences wPreferences
;
47 extern int wScreenCount
;
49 int showCrashDialog(int sig
)
53 dpy
= XOpenDisplay(NULL
);
55 /* XXX TODO make sure that window states are saved and restored via netwm */
58 crashAction
= wShowCrashingDialogPanel(sig
);
62 wsyserror(_("cannot open connection for crashing dialog panel. Aborting."));
63 crashAction
= WMAbort
;
66 if (crashAction
== WMStartAlternate
) {
69 wmessage(_("trying to start alternate window manager..."));
71 for (i
= 0; i
< WMGetArrayItemCount(wPreferences
.fallbackWMs
); i
++) {
72 Restart(WMGetFromArray(wPreferences
.fallbackWMs
, i
), False
);
75 wfatal(_("failed to start alternate window manager. Aborting."));
78 } else if (crashAction
== WMAbort
)
84 int MonitorLoop(int argc
, char **argv
)
87 char **child_argv
= wmalloc(sizeof(char *) * (argc
+ 2));
92 for (i
= 0; i
< argc
; i
++)
93 child_argv
[i
] = argv
[i
];
94 child_argv
[i
++] = "--for-real";
98 last_start
= time(NULL
);
100 /* Start Window Maker */
103 execvp(child_argv
[0], child_argv
);
104 wsyserror(_("Error respawning Window Maker"));
106 } else if (pid
< 0) {
107 wsyserror(_("Error respawning Window Maker"));
112 if ((exited
= waitpid(-1, &status
, 0)) < 0) {
113 wsyserror(_("Error during monitoring of Window Maker process."));
117 } while (exited
!= pid
);
122 child_argv
[argc
] = "--for-real-";
124 /* Check if the wmaker process exited due to a crash */
125 if (WIFSIGNALED(status
) &&
126 (WTERMSIG(status
) == SIGSEGV
||
127 WTERMSIG(status
) == SIGBUS
||
128 WTERMSIG(status
) == SIGILL
|| WTERMSIG(status
) == SIGABRT
|| WTERMSIG(status
) == SIGFPE
)) {
129 /* If so, we check when was the last restart.
130 * If it was less than 3s ago, it's a bad sign, so we show
131 * the crash panel and ask the user what to do */
132 if (time(NULL
) - last_start
< 3) {
133 if (showCrashDialog(WTERMSIG(status
)) == 0) {
137 wwarning(_("Window Maker exited due to a crash (signal %i) and will be restarted."),