1 char *ckusigv = "Signal support, 9.0.100, 16 Oct 2009";
2
3 /* C K U S I G -- Kermit signal handling for Unix and OS/2 systems */
4
5 /*
6 Author: Jeffrey Altman (jaltman@secure-endpoints.com),
7 Secure Endpoints Inc., New York City.
8
9 Copyright (C) 1985, 2009,
10 Trustees of Columbia University in the City of New York.
11 All rights reserved. See the C-Kermit COPYING.TXT file or the
12 copyright text in the ckcmai.c module for disclaimer and permissions.
13 */
14 #include "ckcsym.h"
15 #include "ckcasc.h" /* ASCII character symbols */
16 #include "ckcdeb.h" /* Debug & other symbols */
17 #include "ckcker.h" /* Kermit symbols */
18 #include "ckcnet.h" /* Network symbols */
19 #ifndef NOSPL
20 #include "ckuusr.h"
21 #endif /* NOSPL */
22
23 #include <signal.h>
24 #ifdef NT
25 #include <setjmpex.h>
26 #include <excpt.h>
27 #else /* NT */
28 #include <setjmp.h>
29 #endif /* NT */
30 #include "ckcsig.h"
31
32 #ifdef NOCCTRAP
33 extern ckjmpbuf cmjbuf;
34 #endif /* NOCCTRAP */
35
36 #ifdef MAC
37 #define signal msignal
38 #define SIGTYP long
39 #define alarm malarm
40 #define SIG_IGN 0
41 #define SIGALRM 1
42 #define SIGINT 2
43 SIGTYP (*msignal(int type, SIGTYP (*func)(int)))(int);
44 #endif /* MAC */
45
46 #ifdef STRATUS
47 /* We know these are set here. MUST unset them before the definitions. */
48 #define signal vsignal
49 #define alarm valarm
50 SIGTYP (*vsignal(int type, SIGTYP (*func)(int)))(int);
51 int valarm(int interval);
52 #endif /* STRATUS */
53
54 #ifdef AMIGA
55 #define signal asignal
56 #define alarm aalarm
57 #define SIGALRM (_NUMSIG+1)
58 #define SIGTYP void
59 SIGTYP (*asignal(int type, SIGTYP (*func)(int)))(int);
60 unsigned aalarm(unsigned);
61 #endif /* AMIGA */
62
63 #ifdef NTASM
64 DWORD
ckgetIP(void)65 ckgetIP(void)
66 {
67 __asm
68 {
69 mov eax, dword ptr [esp+0x10]
70 jmp ckgetIP + 0x18
71 }
72 return 1;
73
74 }
75 #endif /* NTASM */
76
77 #ifdef NT
78 DWORD
exception_filter(void)79 exception_filter( void )
80 {
81 GetExceptionInformation ;
82 return( EXCEPTION_EXECUTE_HANDLER ) ;
83 }
84 void
crash(void)85 crash( void )
86 {
87 int x = 0, y = 0 ;
88 x / y ;
89 }
90 #endif /* NT */
91
92 #ifndef NOCCTRAP
93 int
94 #ifdef CK_ANSIC
cc_execute(ckjptr (sj_buf),ck_sigfunc dofunc,ck_sigfunc failfunc)95 cc_execute( ckjptr(sj_buf), ck_sigfunc dofunc, ck_sigfunc failfunc )
96 #else
97 cc_execute( sj_buf, dofunc, failfunc)
98 ckjptr(sj_buf);
99 ck_sigfunc dofunc;
100 ck_sigfunc failfunc;
101 #endif /* CK_ANSIC */
102 /* cc_execute */ {
103 int rc = 0 ;
104 #ifdef NTASM
105 DWORD Eip, Esp ;
106 isinterrupted = 0;
107 sj_buf->retcode = 0 ;
108 sj_buf->Id = GetCurrentThreadId() ;
109 memset( &sj_buf->context, 0, sizeof(CONTEXT) );
110 sj_buf->context.ContextFlags = CONTEXT_FULL ;
111 #ifndef COMMENT
112 GetThreadContext(GetCurrentThread(), &(sj_buf->context) ) ;
113 __asm
114 {
115 mov ecx,dword ptr [sj_buf]
116 mov dword ptr [ecx+0xc4],esp
117 }
118 sj_buf->context.EFlags = 530 ;
119 sj_buf->context.Eip = ckgetIP()+0x0C ;
120 #else /* COMMENT */
121 __asm
122 {
123 mov eax, dword ptr [sj_buf]
124 push eax
125 mov eax, 0xfffffffe
126 push eax
127 mov eax, 0x00000039
128 mov edx,esp
129 int 0x2e
130 pop eax
131 pop eax
132 }
133 #endif /* COMMENT */
134 #endif /* NTASM */
135 if (
136 #ifdef NTASM
137 isinterrupted
138 #else
139 cksetjmp(ckjdref(sj_buf))
140 #endif /* NTASM */
141 ) {
142 #ifdef NTASM
143 __asm
144 {
145 mov esp, ESPToRestore
146 }
147 isinterrupted = 0 ;
148 #endif /* NTASM */
149 (*failfunc)(NULL) ;
150 #ifdef NTASM
151 rc = sj_buf->retcode ;
152 #else /* NTASM */
153 rc = -1 ;
154 #endif /* NTASM */
155 } else {
156 #ifdef NT
157 __try {
158 (*dofunc)(NULL);
159 }
160 __except(exception_filter())
161 {
162 debug(F100,"cc_execute __except","",0);
163 debug(F111,
164 "exception_filter",
165 "_exception_code",
166 etExceptionCode()
167 );
168 longjmp(ckjdref(sj_buf),SIGINT);
169 }
170 #else /* NT */
171 (*dofunc)(NULL);
172 #endif /* NT */
173 }
174 return rc ;
175 }
176 #endif /* NOCCTRAP */
177
178 int
179 #ifdef CK_ANSIC /* ANSIC C declaration... */
alrm_execute(ckjptr (sj_buf),int timo,ck_sighand handler,ck_sigfunc dofunc,ck_sigfunc failfunc)180 alrm_execute(ckjptr(sj_buf),
181 int timo,
182 ck_sighand handler,
183 ck_sigfunc dofunc,
184 ck_sigfunc failfunc
185 )
186
187 #else /* Not ANSIC C ... */
188
189 alrm_execute(sj_buf,
190 timo,
191 handler,
192 dofunc,
193 failfunc
194 )
195 ckjptr(sj_buf);
196 int timo;
197 ck_sighand handler;
198 ck_sigfunc dofunc;
199 ck_sigfunc failfunc;
200 #endif /* CK_ANSIC */
201
202 /* alrm_execute */ {
203
204 int rc = 0;
205 int savalrm = 0;
206 _PROTOTYP(SIGTYP (*savhandler), (int));
207
208 savalrm = alarm(timo);
209 savhandler = signal(SIGALRM, handler);
210
211 #ifdef NTASM
212 sj_buf->retcode = 0 ;
213 sj_buf->Id = GetCurrentThreadId();
214 memset(&sj_buf->context, 0, sizeof(CONTEXT));
215 sj_buf->context.ContextFlags = CONTEXT_FULL;
216 #ifndef COMMENT
217 GetThreadContext(GetCurrentThread(), &(sj_buf->context));
218 #else
219 __asm
220 {
221 mov eax, dword ptr [sj_buf]
222 push eax
223 mov eax, 0xfffffffe
224 push eax
225 mov eax, 0x00000039
226 mov edx,esp
227 int 0x2e
228 pop eax
229 pop eax
230 }
231 #endif
232 isinterrupted = 0;
233 #endif /* NTASM */
234 if (
235 #ifdef NTASM
236 sj_buf->retcode
237 #else
238 cksetjmp(ckjdref(sj_buf))
239 #endif /* NTASM */
240 ) {
241 (*failfunc)(NULL) ;
242 rc = -1 ;
243 } else {
244 #ifdef NT
245 __try {
246 (*dofunc)(NULL) ;
247 }
248 __except( exception_filter() )
249 {
250 debug(F100,"alrm_execute __except","",0);
251 debug(F111,"exception_filter",
252 "_exception_code",
253 GetExceptionCode()
254 );
255 longjmp(ckjdref(sj_buf),SIGINT);
256 }
257 #else /* NT */
258 (*dofunc)(NULL) ;
259 #endif /* NT */
260 }
261 alarm(savalrm) ;
262 if ( savhandler )
263 signal( SIGALRM, savhandler ) ;
264 return rc ;
265 }
266
267 int
268 #ifdef CK_ANSIC /* ANSIC C declaration... */
cc_alrm_execute(ckjptr (sj_buf),int timo,ck_sighand handler,ck_sigfunc dofunc,ck_sigfunc failfunc)269 cc_alrm_execute(ckjptr(sj_buf),
270 int timo,
271 ck_sighand handler,
272 ck_sigfunc dofunc,
273 ck_sigfunc failfunc
274 )
275
276 #else /* Not ANSIC C ... */
277
278 cc_alrm_execute(sj_buf,
279 timo,
280 handler,
281 dofunc,
282 failfunc
283 )
284 ckjptr(sj_buf);
285 int timo;
286 ck_sighand handler;
287 ck_sigfunc dofunc;
288 ck_sigfunc failfunc;
289 #endif /* CK_ANSIC */
290
291 /* cc_alrm_execute */ {
292
293 int rc = 0;
294 int savalrm = 0;
295 _PROTOTYP(SIGTYP (*savhandler), (int));
296 savalrm = alarm(timo);
297 savhandler = signal( SIGALRM, handler );
298
299 #ifdef NTASM
300 sj_buf->retcode = 0 ;
301 sj_buf->Id = GetCurrentThreadId() ;
302 memset( &sj_buf->context, 0, sizeof(CONTEXT) );
303 sj_buf->context.ContextFlags = CONTEXT_FULL ;
304 #ifndef COMMENT
305 GetThreadContext( GetCurrentThread(), &(sj_buf->context) ) ;
306 #else
307 __asm
308 {
309 mov eax, dword ptr [sj_buf]
310 push eax
311 mov eax, 0xfffffffe
312 push eax
313 mov eax, 0x00000039
314 mov edx,esp
315 int 0x2e
316 pop eax
317 pop eax
318 }
319 #endif
320 isinterrupted = 0;
321 #endif /* NTASM */
322 if (
323 #ifdef NTASM
324 sj_buf->retcode
325 #else
326 cksetjmp(ckjdref(sj_buf))
327 #endif /* NTASM */
328 ) {
329 (*failfunc)(NULL) ;
330 rc = -1 ;
331 } else {
332 #ifdef NT
333 __try {
334 (*dofunc)(NULL) ;
335 }
336 __except( exception_filter() )
337 {
338 debug(F100,"cc_alrm_execute __except","",0);
339 debug(F111,
340 "exception_filter",
341 "_exception_code",
342 GetExceptionCode()
343 );
344 longjmp(ckjdref(sj_buf),SIGINT) ;
345 }
346 #else /* NT */
347 (*dofunc)(NULL) ;
348 #endif /* NT */
349 }
350 alarm(savalrm);
351 if (savhandler)
352 signal(SIGALRM,savhandler);
353 return(rc);
354 }
355