/* C K C S I G . H */ /* Definitions and prototypes for signal handling */ /* Author: Jeffrey E Altman (jaltman@secure-endpoints.com), Secure Endpoints Inc., New York City. Copyright (C) 1985, 2004, Trustees of Columbia University in the City of New York. All rights reserved. See the C-Kermit COPYING.TXT file or the copyright text in the ckcmai.c module for disclaimer and permissions. */ #ifdef OS2 #ifndef NT #ifndef __HEV__ /* INCL_SEMAPHORE may also define HEV */ #define __HEV__ typedef ULONG HEV; /* hev */ typedef HEV *PHEV; #endif /* __HEV__ */ #endif /* NT */ struct _threadinfo { int inuse; int child; int sibling; #ifdef NT HANDLE id; HANDLE handle; HANDLE parent; HANDLE CompletionSem ; HANDLE DieSem ; #else /* NT */ TID id; TID parent; HEV CompletionSem; HEV DieSem; #endif /* NT */ }; #endif /* OS2 */ #ifdef CK_ANSIC typedef SIGTYP (*ck_sigfunc)(void *); typedef SIGTYP (*ck_sighand)(int); #else typedef SIGTYP (*ck_sigfunc)(); typedef SIGTYP (*ck_sighand)(); #endif /* CK_ANSIC */ /* Macros for POSIX vs old-style signal handling. */ #ifdef CK_POSIX_SIG typedef sigjmp_buf ckjmpbuf; #else #ifdef NT #define NOCRYPT #include #ifdef NTASM typedef struct { CONTEXT context; DWORD retcode; } ckjmpbuf; #else /* NTASM */ typedef jmp_buf ckjmpbuf; #endif /* NTASM */ #else typedef jmp_buf ckjmpbuf; #endif #endif /* CK_POSIX_SIG */ /* Suppose you want to pass the address of a jmp_buf bar to a function foo. Since jmp_buf is normally defined (typedef'd) as an array, you would do it like this: foo(bar), where foo = foo(jmp_buf bar). But suppose a jmp_buf is (say) a struct rather than an array. Then you must do foo(&bar) where foo is foo(jmp_buf * bar). This is controlled here in the traditional fashion, by ifdefs. By default, we assume that jmp_buf is an array. Define the symbol JBNOTARRAY if jmp_buf is not an array. */ #ifndef JBNOTARRAY #ifdef NT #define JBNOTARRAY #endif /* NT */ #endif /* JBNOTARRAY */ #ifdef JBNOTARRAY typedef ckjmpbuf * ckjptr; #define ckjaddr(x) & x #define ckjdref(x) * x #ifdef CK_POSIX_SIG #define cksetjmp(x) sigsetjmp(x,1) #define cklongjmp(x,y) siglongjmp(x,y) #else #ifdef NT __inline int ck_ih(void) { extern int TlsIndex; #ifdef NTSIG struct _threadinfo * threadinfo; threadinfo = (struct _threadinfo *) TlsGetValue(TlsIndex); if (threadinfo) { if (WaitAndResetSem(threadinfo->DieSem,0)) { ckThreadDie(threadinfo); return 1; /* This should never execute */ } } #ifdef COMMENT else debug( F100, "ck_ih() threadinfo is NULL","",0); #endif /* COMMENT */ #endif /* NTSIG */ return 0; } #ifdef NTSIG #define cksetjmp(x) setjmp(x) #define cklongjmp(x,y) longjmp(x,y) #else /* NTSIG */ #ifdef NTASM __inline DWORD cksetjmp( ckjptr jmp ) { extern int isinterrupted; jmp->retcode = 0; memset( &jmp->context, 0, sizeof(CONTEXT) ); jmp->context.ContextFlags = CONTEXT_FULL ; if ( !GetThreadContext( GetCurrentThread(), &jmp->context ) ) debug( F101, "cksetjmp GetThreadContext failed","",GetLastError()); debug(F101,"cksetjmp returns","",jmp->retcode); isinterrupted = 0; return (jmp->retcode); } __inline void cklongjmp( ckjptr jmp, int retval ) { extern HANDLE tidCommand; extern int ttyfd, mdmtyp ; extern DWORD CommandID; extern int isinterrupted; connoi(); isinterrupted = 1; jmp->retcode = ( retval ? retval : 1 ); debug(F101,"about to SetThreadContext for thread","", CommandID); debug(F101,"from Thread","",GetCurrentThreadId()); if ( mdmtyp >= 0 ) { PurgeComm( (HANDLE) ttyfd, PURGE_TXABORT | PURGE_RXABORT ); } if (SetThreadContext( tidCommand, &jmp->context )) debug(F100,"cklongjmp SetThreadContext success","",0); else debug(F101,"cklongjmp SetThreadContext failed","",GetLastError()); msleep(50); cmini(1); /* Reset command parser */ putkey(13); /* Stuff a carriage return */ /* PostEventAvailSem(); */ } #else /* NTASM */ void crash( void ) ; #define cksetjmp(x) setjmp(x) __inline void cklongjmp( ckjptr jmp, int retval ) { extern HANDLE tidCommand; extern int ttyfd, mdmtyp; extern DWORD CommandID; CONTEXT context; if ( mdmtyp >= 0 ) { PurgeComm( (HANDLE) ttyfd, PURGE_TXABORT | PURGE_RXABORT ) ; } memset( &context, 0, sizeof(CONTEXT) ); context.ContextFlags = CONTEXT_FULL; if ( !GetThreadContext( tidCommand, &context ) ) debug( F101, "cklongjmp GetThreadContext failed","",GetLastError()); /* Invalidate the instruction pointer */ context.Eip = (unsigned long) crash; debug(F101,"about to SetThreadContext for thread","", CommandID); debug(F101,"from Thread","",GetCurrentThreadId()); if (SetThreadContext( tidCommand, &context )) debug(F100,"cklongjmp SetThreadContext success","",0); else debug(F101,"cklongjmp SetThreadContext failed","",GetLastError()); } #endif /* NTASM */ #endif /* NTSIG */ #else /* NT */ #define cksetjmp(x) setjmp(x) #define cklongjmp(x,y) longjmp(x,y) #endif /* NT */ #endif /* CK_POSIX_SIG */ #else /* jmp_buf is an array */ typedef ckjmpbuf ckjptr; #define ckjaddr(x) x #define ckjdref(x) x #ifdef CK_POSIX_SIG #define cksetjmp(x) sigsetjmp(x,1) #define cklongjmp(x,y) siglongjmp(x,y) #else #define cksetjmp(x) setjmp(x) #define cklongjmp(x,y) longjmp(x,y) #endif /* CK_POSIX_SIG */ #endif /* JBNOTARRAY */ _PROTOTYP( int cc_execute, (ckjptr, ck_sigfunc, ck_sigfunc) ); _PROTOTYP( int alrm_execute, (ckjptr, int /* timo */, ck_sighand /* handler */, ck_sigfunc, ck_sigfunc) ); _PROTOTYP( int cc_alrm_execute, (ckjptr, int /* timo */, ck_sighand /* handler */, ck_sigfunc, ck_sigfunc) ); /* End of ckusig.h */