1 /*
2 **
3 ** gv_signal.c
4 **
5 ** Copyright (C) 1995, 1996, 1997 Johannes Plass
6 ** Copyright (C) 2004 Jose E. Marchesi
7 **
8 ** This program is free software; you can redistribute it and/or modify
9 ** it under the terms of the GNU General Public License as published by
10 ** the Free Software Foundation; either version 3 of the License, or
11 ** (at your option) any later version.
12 **
13 ** This program is distributed in the hope that it will be useful,
14 ** but WITHOUT ANY WARRANTY; without even the implied warranty of
15 ** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 ** GNU General Public License for more details.
17 **
18 ** You should have received a copy of the GNU General Public License
19 ** along with GNU gv; see the file COPYING. If not, write to
20 ** the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
21 ** Boston, MA 02111-1307, USA.
22 **
23 ** Author: Johannes Plass (plass@thep.physik.uni-mainz.de)
24 ** Department of Physics
25 ** Johannes Gutenberg-University
26 ** Mainz, Germany
27 **
28 ** Jose E. Marchesi (jemarch@gnu.org)
29 ** GNU Project
30 **
31 */
32 #include "ac_config.h"
33
34 /*
35 #define MESSAGES
36 */
37 #include <ac_config.h>
38
39 #include "message.h"
40
41 #include <stdio.h>
42 #include <signal.h>
43 #include <sys/stat.h>
44 #include <unistd.h>
45 #include <stdlib.h>
46
47 #include "paths.h"
48 #include INC_X11(Intrinsic.h)
49
50
51 #ifdef USE_SIGNAL_HANDLER
52 # if (XtSpecificationRelease >= 6)
53 # define USE_XT_SIGNAL_HANDLER
54 # else
55 # define USE_DUMMY_SIGNAL_HANDLER
56 # endif
57 #else
58 # define USE_DUMMY_SIGNAL_HANDLER
59 #endif
60
61 #include "types.h"
62 #include "callbacks.h"
63 #include "main_resources.h"
64 #include "main_globals.h"
65 #include "gv_signal.h"
66 #include "actions.h"
67
68 #ifdef SIGNALRETURNSINT
69 # define SIGVAL int
70 # define SIGNAL_RETURN return(0);
71 #else
72 # define SIGVAL void
73 # define SIGNAL_RETURN
74 #endif
75
76
77 #ifdef USE_XT_SIGNAL_HANDLER
78
79
80 static XtSignalId sid_updateFile = 0;
81 static XtSignalId sid_terminate = 0;
82 static int block_terminate = 0;
83 static int block_updateFile = 0;
84 static pid_t gv_pid = (pid_t) 0;
85
86 /*------------------------------------------------------------*/
87 /* signal_signalIsOk */
88 /*------------------------------------------------------------*/
89
signal_signalIsOk(void)90 static int signal_signalIsOk(void)
91 {
92 BEGINMESSAGE(signal_signalIsOk)
93 # ifdef MESSAGES
94 IIMESSAGE(gv_pid,getpid())
95 if (gv_pid == getpid()) { INFMESSAGE(signal is ok) }
96 else { INFMESSAGE(bogus signal) }
97 # endif
98 ENDMESSAGE(signal_signalIsOk)
99 return(gv_pid == getpid() ? 1 : 0);
100 }
101
102 /*------------------------------------------------------------*/
103 /* signal_scb_terminate */
104 /*------------------------------------------------------------*/
105
signal_scb_terminate(XtPointer client_data _GL_UNUSED,XtSignalId * sidP _GL_UNUSED)106 static void signal_scb_terminate(XtPointer client_data _GL_UNUSED, XtSignalId *sidP _GL_UNUSED)
107 {
108 BEGINMESSAGE(signal_scb_terminate)
109 cb_doQuit(NULL,NULL,NULL);
110 ENDMESSAGE(signal_scb_terminate)
111 }
112
113 /*------------------------------------------------------------*/
114 /* signal_sh_terminate */
115 /*------------------------------------------------------------*/
116
signal_sh_terminate(int sig)117 static SIGVAL signal_sh_terminate(int sig)
118 {
119 BEGINMESSAGE(signal_fatalSignalHandler)
120 if (signal_signalIsOk()) {
121 if (!block_terminate) {
122 fprintf(stderr, "gv: terminated by signal %d\n", sig);
123 XtNoticeSignal(sid_terminate);
124 block_terminate = 1;
125 }
126 signal(sig,signal_sh_terminate);
127 } else {
128 INFMESSAGE(forcing bogus caller to die)
129 clean_safe_tempdir();
130 exit(EXIT_STATUS_ERROR);
131 }
132 ENDMESSAGE(signal_sh_terminate)
133 SIGNAL_RETURN
134 }
135
136 /*------------------------------------------------------------*/
137 /* signal_scb_updateFile */
138 /*------------------------------------------------------------*/
139
signal_scb_updateFile(XtPointer client_data _GL_UNUSED,XtSignalId * sidP _GL_UNUSED)140 static void signal_scb_updateFile(XtPointer client_data _GL_UNUSED, XtSignalId *sidP _GL_UNUSED)
141 {
142 BEGINMESSAGE(signal_scb_updateFile)
143 if (gv_filename) {
144 String s;
145 struct stat sbuf;
146 s = XtNewString(gv_filename);
147 if (!stat(s, &sbuf) && mtime != sbuf.st_mtime)
148 cb_checkFile(NULL,(XtPointer)CHECK_FILE_VERSION,NULL);
149 XtFree(s);
150 }
151 block_updateFile = 0;
152 ENDMESSAGE(signal_scb_updateFile)
153 }
154
155 /*------------------------------------------------------------*/
156 /* signal_sh_updateFile */
157 /*------------------------------------------------------------*/
158
signal_sh_updateFile(int sig)159 static SIGVAL signal_sh_updateFile(int sig)
160 {
161 BEGINMESSAGE(signal_sh_updateFile)
162 if (signal_signalIsOk()) {
163 if (!block_updateFile) {
164 block_updateFile=1;
165 XtNoticeSignal(sid_updateFile);
166 }
167 signal(sig,signal_sh_updateFile);
168 } else {
169 INFMESSAGE(forcing bogus caller to die)
170 clean_safe_tempdir();
171 exit(EXIT_STATUS_ERROR);
172 }
173 ENDMESSAGE(signal_sh_updateFile)
174 SIGNAL_RETURN
175 }
176
177 /*############################################################*/
178 /* signal_setSignalHandlers */
179 /*############################################################*/
180
signal_setSignalHandlers(int on)181 void signal_setSignalHandlers(int on)
182 {
183 SIGVAL (*sht)(int),(*shu)(int);
184
185 BEGINMESSAGE(signal_setSignalHandlers)
186
187 if (!gv_pid) gv_pid = getpid();
188
189 if (on) {
190 shu = signal_sh_updateFile;
191 sht = signal_sh_terminate;
192 sid_updateFile = XtAppAddSignal(app_con,signal_scb_updateFile,NULL);
193 sid_terminate = XtAppAddSignal(app_con,signal_scb_terminate,NULL);
194 } else {
195 shu = sht = SIG_DFL;
196 if (sid_updateFile) XtRemoveSignal(sid_updateFile);
197 if (sid_terminate) XtRemoveSignal(sid_terminate);
198 sid_updateFile = sid_terminate = 0;
199 }
200 signal(SIGHUP, shu);
201 signal(SIGQUIT, sht);
202 signal(SIGTERM, sht);
203 #if 0
204 signal(SIGINT, sht);
205 signal(SIGILL, sht);
206 signal(SIGBUS, sht);
207 signal(SIGFPE, sht);
208 signal(SIGSEGV, sht);
209 signal(SIGSYS, sht);
210 #endif
211 ENDMESSAGE(signal_setSignalHandlers)
212 }
213
214 #endif /* USE_XT_SIGNAL_HANDLER */
215
216
217 #ifdef USE_DUMMY_SIGNAL_HANDLER
218
219 int signaldummy;
220
221 #endif /* USE_DUMMY_SIGNAL_HANDLER */
222