Imported Upstream version 302
[ckermit.git] / ckusig.c
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
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
79 exception_filter( void )
80 {
81    GetExceptionInformation ;
82    return( EXCEPTION_EXECUTE_HANDLER ) ;
83 }
84 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
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... */
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... */
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 }