ckusig.c 7.1 KB

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