blob: 30fb8bf63fa510175869c1698204bcce3b585d68 [file] [log] [blame]
/* 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 <windows.h>
#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 */