Makefile: Beautify compilation messages
[wmaker-crm.git] / src / monitor.c
blob61fea3a9489edbdf453b6131df34a667aef57448
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,
20 * USA.
23 #include "wconfig.h"
24 #include <unistd.h>
25 #include <stdlib.h>
26 #include <time.h>
27 #include <signal.h>
28 #include <sys/wait.h>
29 #ifdef __FreeBSD__
30 #include <sys/signal.h>
31 #endif
33 #include <X11/Xlib.h>
34 #include <X11/Xutil.h>
35 #include <X11/Xproto.h>
37 #include "WindowMaker.h"
38 #include "screen.h"
39 #include "window.h"
40 #include "dialog.h"
41 #include "funcs.h"
43 /****** Global Variables ******/
45 extern WPreferences wPreferences;
47 extern int wScreenCount;
52 int showCrashDialog(int sig)
54 int crashAction;
56 dpy = XOpenDisplay(NULL);
57 if (dpy) {
58 /* XXX TODO make sure that window states are saved and restored via netwm */
60 XGrabServer(dpy);
61 crashAction = wShowCrashingDialogPanel(sig);
62 XCloseDisplay(dpy);
63 dpy = NULL;
64 } else {
65 wsyserror(_("cannot open connection for crashing dialog panel. Aborting."));
66 crashAction = WMAbort;
69 if (crashAction == WMStartAlternate)
71 int i;
73 wmessage(_("trying to start alternate window manager..."));
75 for (i=0; i<WMGetArrayItemCount(wPreferences.fallbackWMs); i++) {
76 Restart(WMGetFromArray(wPreferences.fallbackWMs, i), False);
79 wfatal(_("failed to start alternate window manager. Aborting."));
81 return 0;
83 else if (crashAction == WMAbort)
84 return 0;
85 else
86 return 1;
90 int MonitorLoop(int argc, char **argv)
92 pid_t pid, exited;
93 char **child_argv= wmalloc(sizeof(char*)*(argc+2));
94 int i, status;
95 time_t last_start;
96 Bool error = False;
98 for (i= 0; i < argc; i++)
99 child_argv[i]= argv[i];
100 child_argv[i++]= "--for-real";
101 child_argv[i]= NULL;
103 for (;;)
105 last_start= time(NULL);
107 /* Start Window Maker */
108 pid = fork();
109 if (pid == 0)
111 execvp(child_argv[0], child_argv);
112 wsyserror(_("Error respawning Window Maker"));
113 exit(1);
115 else if (pid < 0)
117 wsyserror(_("Error respawning Window Maker"));
118 exit(1);
121 do {
122 if ((exited=waitpid(-1, &status, 0)) < 0)
124 wsyserror(_("Error during monitoring of Window Maker process."));
125 error = True;
126 break;
128 } while (exited != pid);
130 if (error)
131 break;
133 child_argv[argc]= "--for-real-";
135 /* Check if the wmaker process exited due to a crash */
136 if (WIFSIGNALED(status) &&
137 (WTERMSIG(status) == SIGSEGV ||
138 WTERMSIG(status) == SIGBUS ||
139 WTERMSIG(status) == SIGILL ||
140 WTERMSIG(status) == SIGABRT ||
141 WTERMSIG(status) == SIGFPE))
143 /* If so, we check when was the last restart.
144 * If it was less than 3s ago, it's a bad sign, so we show
145 * the crash panel and ask the user what to do */
146 if (time(NULL) - last_start < 3)
148 if (showCrashDialog(WTERMSIG(status)) == 0) {
149 return 1;
152 wwarning(_("Window Maker exited due to a crash (signal %i) and will be restarted."),
153 WTERMSIG(status));
155 else
156 break;
158 return 0;