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