Added option to 'configure' to control debug information for compilation
[wmaker-crm.git] / src / monitor.c
blobecf05b97c0debdaa1237517aece8b96078eab34f
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 along
18 * with this program; if not, write to the Free Software Foundation, Inc.,
19 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
22 #include "wconfig.h"
23 #include <unistd.h>
24 #include <stdlib.h>
25 #include <time.h>
26 #include <signal.h>
27 #include <sys/wait.h>
28 #ifdef __FreeBSD__
29 #include <sys/signal.h>
30 #endif
32 #include <X11/Xlib.h>
33 #include <X11/Xutil.h>
34 #include <X11/Xproto.h>
36 #include "WindowMaker.h"
37 #include "screen.h"
38 #include "window.h"
39 #include "dialog.h"
40 #include "main.h"
42 /****** Global Variables ******/
43 extern WPreferences wPreferences;
45 int showCrashDialog(int sig)
47 int crashAction;
49 dpy = XOpenDisplay(NULL);
50 if (dpy) {
51 /* XXX TODO make sure that window states are saved and restored via netwm */
53 XGrabServer(dpy);
54 crashAction = wShowCrashingDialogPanel(sig);
55 XCloseDisplay(dpy);
56 dpy = NULL;
57 } else {
58 werror(_("cannot open connection for crashing dialog panel. Aborting."));
59 crashAction = WMAbort;
62 if (crashAction == WMStartAlternate) {
63 int i;
65 wmessage(_("trying to start alternate window manager..."));
67 for (i = 0; i < WMGetArrayItemCount(wPreferences.fallbackWMs); i++) {
68 Restart(WMGetFromArray(wPreferences.fallbackWMs, i), False);
71 wfatal(_("failed to start alternate window manager. Aborting."));
73 return 0;
74 } else if (crashAction == WMAbort)
75 return 0;
76 else
77 return 1;
80 int MonitorLoop(int argc, char **argv)
82 pid_t pid, exited;
83 char **child_argv = wmalloc(sizeof(char *) * (argc + 2));
84 int i, status;
85 time_t last_start;
86 Bool error = False;
88 for (i = 0; i < argc; i++)
89 child_argv[i] = argv[i];
90 child_argv[i++] = "--for-real";
91 child_argv[i] = NULL;
93 for (;;) {
94 last_start = time(NULL);
96 /* Start Window Maker */
97 pid = fork();
98 if (pid == 0) {
99 execvp(child_argv[0], child_argv);
100 werror(_("Error respawning Window Maker"));
101 exit(1);
102 } else if (pid < 0) {
103 werror(_("Error respawning Window Maker"));
104 exit(1);
107 do {
108 if ((exited = waitpid(-1, &status, 0)) < 0) {
109 werror(_("Error during monitoring of Window Maker process."));
110 error = True;
111 break;
113 } while (exited != pid);
115 if (error)
116 break;
118 child_argv[argc] = "--for-real-";
120 /* Check if the wmaker process exited due to a crash */
121 if (WIFSIGNALED(status) &&
122 (WTERMSIG(status) == SIGSEGV ||
123 WTERMSIG(status) == SIGBUS ||
124 WTERMSIG(status) == SIGILL || WTERMSIG(status) == SIGABRT || WTERMSIG(status) == SIGFPE)) {
125 /* If so, we check when was the last restart.
126 * If it was less than 3s ago, it's a bad sign, so we show
127 * the crash panel and ask the user what to do */
128 if (time(NULL) - last_start < 3) {
129 if (showCrashDialog(WTERMSIG(status)) == 0) {
130 return 1;
133 wwarning(_("Window Maker exited due to a crash (signal %i) and will be restarted."),
134 WTERMSIG(status));
135 } else
136 break;
138 return 0;