ecusighdl.c 21 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806
  1. /*+-----------------------------------------------------------------------
  2. ecusighdl.c - xmtr/rcvr individual process signal handlers
  3. wht@wht.net
  4. Defined functions:
  5. child_signals()
  6. ck_sigint()
  7. gag_me()
  8. kill_rcvr_process(sig)
  9. rcvr_SIGUSR2_handler(sig)
  10. rcvr_common_signal_handler(sig)
  11. rcvr_death_handler(sig)
  12. rcvr_signals()
  13. sig_report(sig)
  14. termecu(code)
  15. termecu_code_text(code)
  16. xmtr_SIGCLD_handler(sig)
  17. xmtr_SIGHUP_handler(sig)
  18. xmtr_SIGINT_handler(sig)
  19. xmtr_SIGTERM_handler(sig)
  20. xmtr_SIGUSR2_handler(sig)
  21. xmtr_death_handler(sig)
  22. xmtr_signals()
  23. ------------------------------------------------------------------------*/
  24. /*+:EDITS:*/
  25. /*:04-26-2000-11:15-wht@bob-RELEASE 4.42 */
  26. /*:01-24-1997-02:37-wht@yuriatin-SOURCE RELEASE 4.00 */
  27. /*:10-29-1996-18:27-wht@yuriatin-immediate SIG_IGN upon termecu entry */
  28. /*:09-11-1996-19:59-wht@yuriatin-3.48-major telnet,curses,structural overhaul */
  29. /*:08-25-1996-02:15-wht@fep-fix MOTSVR4 SIGTTOU */
  30. /*:08-11-1996-02:10-wht@kepler-rename ecu_log_event to logevent */
  31. /*:08-10-1996-13:44-wht@kepler-harden telnet close */
  32. /*:07-03-1996-14:54-wht@kepler-amplify TERMECU_CURSES_ERROR message */
  33. /*:07-03-1996-14:49-wht@kepler-do not print termecu errno if normal */
  34. /*:07-03-1996-14:29-wht@kepler-tcap_curbotleft used made permanent */
  35. /*:01-27-1996-20:26-wht@n4hgf-use child_pid decl in ecu.h */
  36. /*:12-11-1995-17:43-wht@kepler-kill any child in child_pid on termecu */
  37. /*:12-06-1995-13:30-wht@n4hgf-termecu w/errno -1 consideration */
  38. /*:11-23-1995-11:20-wht@kepler-source control 3.37 for tsx-11 */
  39. /*:11-14-1995-10:23-wht@kepler-3.37.80-source control point: SOCKETS */
  40. /*:11-13-1995-16:02-wht@kepler-restore placing cursor at bot/left on exit */
  41. /*:11-13-1995-12:26-wht@kepler-start_rcvr_process moved to ecurcvr.c */
  42. /*:11-12-1995-01:52-wht@gyro-use shmr_notify_termecu instead of SIGHUP xmtr */
  43. /*:11-04-1995-14:40-wht@wwtp1-telnet termecu fixes: omit DCE_hangup */
  44. /*:09-17-1995-16:25-wht@kepler-belated add TERMECU_XMTR_WRITE_ERROR text */
  45. /*:05-11-1995-15:55-wht@n4hgf-ck_sigint fools optimizing compilers */
  46. /*:05-04-1994-04:39-wht@n4hgf-ECU release 3.30 */
  47. /*:11-25-1993-14:47-wht@n4hgf-call shm_done AFTER restore_initial_colors */
  48. /*:10-04-1993-03:57-wht@n4hgf-simplify rcvr signal service + better reporting */
  49. /*:10-04-1993-01:58-wht@n4hgf-spice up term diags + report sigs for 1st time */
  50. /*:08-30-1993-12:39-wht@n4hgf-revert WHT to catch SEGV */
  51. /*:08-07-1993-20:25-wht@n4hgf-if WHT, do not catch SEGV, etc. */
  52. /*:06-26-1993-16:33-wht@n4hgf-check for rcvr active in rcvr death test */
  53. /*:10-18-1992-14:11-wht@n4hgf-FAS 2.10 users getting SIGUSR1 on xmtr */
  54. /*:09-16-1992-13:29-wht@n4hgf-add TERMECU_UNRECOVERABLE text */
  55. /*:09-10-1992-13:59-wht@n4hgf-ECU release 3.20 */
  56. /*:08-22-1992-15:38-wht@n4hgf-ECU release 3.20 BETA */
  57. /*:08-17-1992-04:55-wht@n4hgf-keep rcvr pid in shm for friend code */
  58. /*:08-16-1992-03:08-wht@n4hgf-head off another POSIX plot */
  59. /*:08-16-1992-01:54-wht@n4hgf-job control signals get SIG_IGN */
  60. /*:04-29-1992-19:04-wht@n4hgf-make a pass at handling job control signals */
  61. /*:04-29-1992-13:46-wht@n4hgf-ignore SIGQUIT */
  62. /*:04-23-1992-16:20-wht@n4hgf-disable mysterious rcvr SIGCLD events */
  63. /*:02-16-1992-01:42-wht@n4hgf-turn off xterm_title + add _terminate.ep */
  64. /*:08-25-1991-23:56-wht@n4hgf2-handle xmtr core dump gracefully */
  65. /*:07-25-1991-12:56-wht@n4hgf-ECU release 3.10 */
  66. /*:07-17-1991-07:04-wht@n4hgf-avoid SCO UNIX nap bug */
  67. /*:06-29-1991-15:42-wht@n4hgf-if WHT and xterm, play with title bar */
  68. /*:01-29-1991-12:57-wht@n4hgf-on exit, restore setcolor colors if possible */
  69. /*:12-18-1990-20:02-wht@n4hgf-add rcvr_death_handler */
  70. /*:09-19-1990-19:36-wht@n4hgf-logevent now gets pid for log from caller */
  71. /*:08-14-1990-20:40-wht@n4hgf-ecu3.00-flush old edit history */
  72. #include "ecu.h"
  73. #include "ecufork.h"
  74. extern int windows_active;
  75. extern int current_ttymode;
  76. extern int ttymode_termecu_on_sigint;
  77. extern int rcvr_log;
  78. extern FILE *rcvr_log_fp;
  79. extern char rcvr_log_file[]; /* if rcvr_log!= 0,log filename */
  80. extern int rcvr_log_append;
  81. int sigint = 0; /* interrupt indicator */
  82. int proc_interrupt = 0; /* procedure interrupt indicator */
  83. int last_child_wait_status;
  84. int last_child_wait_pid;
  85. int xmtr_killed_rcvr;
  86. char *signal_name_text();
  87. void xmtr_signals();
  88. void rcvr_signals();
  89. void child_signals();
  90. CFG_SigType kill_rcvr_process();
  91. CFG_SigType rcvr_SIGUSR2_handler();
  92. CFG_SigType xmtr_SIGINT_handler();
  93. CFG_SigType xmtr_SIGHUP_handler();
  94. CFG_SigType xmtr_SIGTERM_handler();
  95. CFG_SigType xmtr_SIGCLD_handler();
  96. CFG_SigType xmtr_death_handler();
  97. CFG_SigType rcvr_common_signal_handler();
  98. CFG_SigType rcvr_death_handler();
  99. /*
  100. * macros for wait() status ... in case they aren't defined
  101. */
  102. #undef WIFEXITED /* in case they were */
  103. #undef WEXITSTATUS
  104. #undef WIFSIGNALED
  105. #undef WTERMSIG
  106. #undef WIFSTOPPED
  107. #undef WSTOPSIG
  108. #define WIFEXITED(status) ((status & 0xFF) == 0)
  109. #define WEXITSTATUS(status) ((status >> 8) & 0xFF)
  110. #define WIFSIGNALED(status) ((status) && ((status & 0x00FF) == 0xFF))
  111. #define WTERMSIG(status) (status & 0x7F)
  112. #define WIFSTOPPED(status) ((status & 0xFF) == 0xFF)
  113. #define WSTOPSIG(status) ((status >> 8) & 0xFF)
  114. /*+-------------------------------------------------------------------------
  115. termecu_code_text(code)
  116. --------------------------------------------------------------------------*/
  117. char *
  118. termecu_code_text(code)
  119. int code;
  120. {
  121. static char errant[16];
  122. char *signal_name_text();
  123. if ((code >= TERMECU_SIG1) && (code <= TERMECU_SIGN))
  124. return (signal_name_text(code));
  125. switch (code)
  126. {
  127. case TERMECU_BSD4_IOCTL:
  128. return ("BSD4 ioctl error");
  129. case TERMECU_CONFIG_ERROR:
  130. return ("configuration error");
  131. case TERMECU_CURSES_ERROR:
  132. return ("error in curses use/terminal configuration");
  133. case TERMECU_GEOMETRY:
  134. return ("unsupported screen geometry");
  135. case TERMECU_INIT_PROC_ERROR:
  136. return ("error during initial procedure");
  137. case TERMECU_IPC_ERROR:
  138. return ("IPC (shm/sem) init failed");
  139. case TERMECU_LINE_OPEN_ERROR:
  140. return ("line open error");
  141. case TERMECU_LINE_READ_ERROR:
  142. return ("line read error");
  143. case TERMECU_LOGIC_ERROR:
  144. return ("internal logic error");
  145. case TERMECU_MALLOC:
  146. return ("critical memory allocation failure");
  147. case TERMECU_NO_FORK_FOR_RCVR:
  148. return ("can't fork for RCVR");
  149. case TERMECU_PWENT_ERROR:
  150. return ("password entry error");
  151. case TERMECU_RCVR_FATAL_ERROR:
  152. return ("detected RCVR FATAL ERROR");
  153. case TERMECU_SHM_ABL:
  154. return ("SHM ABL error");
  155. case TERMECU_SHM_RTL:
  156. return ("SHM RTL error");
  157. case TERMECU_SVC_NOT_AVAIL:
  158. return ("service not available");
  159. case TERMECU_TTYIN_READ_ERROR:
  160. return ("keyboard read error");
  161. case TERMECU_UNRECOVERABLE:
  162. return ("unrecoverable error");
  163. case TERMECU_USAGE:
  164. return ("usage");
  165. case TERMECU_XMTR_FATAL_ERROR:
  166. return ("detected XMTR FATAL ERROR");
  167. case TERMECU_XMTR_WRITE_ERROR:
  168. return ("XMTR could not write to line");
  169. default:
  170. sprintf(errant, "code %u?", code);
  171. return (errant);
  172. }
  173. } /* end of termecu_code_text */
  174. /*+-------------------------------------------------------------------------
  175. gag_me() - adb/sdb/gdb/dbx/dbxtra hack for catching trauma
  176. --------------------------------------------------------------------------*/
  177. void
  178. gag_me()
  179. {
  180. char *x = (char *)0xffff0000;
  181. *x = 1;
  182. } /* end of gag_me */
  183. /*+-----------------------------------------------------------------------
  184. termecu(code) -- terminate program (with cleanup)
  185. see termecu.h for a list of codes
  186. Separate processing for rcvr and xmtr processes; rcvr entry
  187. is only upon some kind of serious error and it more less just dies,
  188. causing xmtr process to wake up with SIGCLD and come in here.
  189. Upon entry by xmtr process:
  190. close comm line
  191. run any _terminate.ep procedure
  192. return any ungetty'd line
  193. return user's console to normal status
  194. remove shm segment
  195. terminate program
  196. ------------------------------------------------------------------------*/
  197. void
  198. termecu(code)
  199. int code;
  200. {
  201. static int already_in_termecu = 0; /* one per fork */
  202. int isig;
  203. int save_errno = errno;
  204. char s256[256];
  205. extern char initial_procedure[];
  206. char *signal_name_text();
  207. for (isig = 1; isig < NSIG; isig++)
  208. signal(isig, SIG_IGN);
  209. if (already_in_termecu)
  210. {
  211. gag_me();
  212. pprintf("\n\n\n%s REENTERED TERMECU ... CANNOT RECOVER\n",
  213. (getpid() == xmtr_pid) ? "XMTR" : "RCVR");
  214. ttymode(0); /* normal tty status */
  215. exit(255);
  216. }
  217. already_in_termecu = 1;
  218. if (shm) /* tell friends goodbye */
  219. shm->terminating = 1;
  220. if (xmtr_pid == getpid())/* if we are xmtr */
  221. {
  222. kill_rcvr_process(SIGUSR1);
  223. if (child_pid > 0)
  224. kill(child_pid, SIGKILL);
  225. if (windows_active)
  226. windows_end_signal();
  227. tcap_curbotleft();
  228. tcap_eeod();
  229. if (shm && (shm->Liofd != -1))
  230. lclose();
  231. #if defined(CFG_TelnetOption)
  232. if (shm && !shm->Ltelnet)
  233. #endif
  234. {
  235. if (shm && shm->Lconnected)
  236. DCE_hangup();
  237. }
  238. if (find_procedure("_terminate"))
  239. {
  240. char code_str[16];
  241. char *_doproc_args[2];
  242. _doproc_args[0] = "_terminate"; /* _terminate.ep */
  243. sprintf(code_str, "%d", code);
  244. _doproc_args[1] = code_str;
  245. (void)do_proc(2, _doproc_args);
  246. }
  247. /*
  248. * make SURE we release any line(s) acquired from getty
  249. */
  250. ungetty_return_line((char *)0, "terminating");
  251. ttymode(0); /* normal tty status */
  252. if (!code)
  253. ;
  254. else if (code <= TERMECU_SIGN)
  255. {
  256. pprintf("## XMTR caught signal %d (%s)\n",
  257. code, signal_name_text(code));
  258. }
  259. else
  260. {
  261. setcolor(colors_error);
  262. if (code == TERMECU_INIT_PROC_ERROR)
  263. pprintf("initial procedure '%s' failed\n", initial_procedure);
  264. else if ((code > TERMECU_INIT_PROC_ERROR) &&
  265. (code <= TERMECU_INIT_PROC_ERROR + 32))
  266. {
  267. pprintf("procedure command: exit %d\n",
  268. code - TERMECU_INIT_PROC_ERROR);
  269. }
  270. else
  271. {
  272. sprintf(s256, "## XMTR: %s", termecu_code_text(code));
  273. pputs(s256);
  274. if (save_errno > 0)
  275. {
  276. char *cp = s256 + strlen(s256);
  277. sprintf(cp, ", errno = %d", save_errno);
  278. pputs(cp);
  279. }
  280. pputs("\n");
  281. if (lopen_err_str[0])
  282. {
  283. pputs(lopen_err_str);
  284. pputs("\n");
  285. }
  286. logevent(getpid(), s256);
  287. errno = save_errno;
  288. if (errno > 0)
  289. pperror("errno may not apply, but");
  290. }
  291. }
  292. restore_initial_colors();
  293. shm_done();
  294. }
  295. else
  296. {
  297. /* * we are in the rcvr */
  298. if (code <= TERMECU_SIGN)
  299. {
  300. pprintf("## RCVR caught signal %d (%s)\n",
  301. code, signal_name_text(code));
  302. }
  303. else
  304. {
  305. sprintf(s256, "## RCVR: %s", termecu_code_text(code));
  306. pputs(s256);
  307. if (save_errno > 0)
  308. {
  309. char *cp = s256 + strlen(s256);
  310. sprintf(cp, ", errno = %d", save_errno);
  311. pputs(cp);
  312. }
  313. pputs("\n");
  314. logevent(getpid(), s256);
  315. errno = save_errno;
  316. if (errno > 1)
  317. pperror("errno may not apply, but");
  318. }
  319. ttymode(0); /* normal tty status */
  320. restore_initial_colors();
  321. shmr_notify_termecu();
  322. }
  323. exit(code);
  324. /* NOTREACHED */
  325. } /* end of termecu */
  326. /*+-----------------------------------------------------------------------
  327. kill_rcvr_process(sig) -- kill rcvr process with signal 'sig'
  328. ------------------------------------------------------------------------*/
  329. CFG_SigType
  330. kill_rcvr_process(sig)
  331. int sig;
  332. {
  333. int wait_count = 70;
  334. if (shm->rcvr_pid > 0) /* if we have forked a rcvr process */
  335. {
  336. xmtr_killed_rcvr = 1;
  337. rcvr_log_fp = (FILE *) 0;
  338. xmtr_signals();
  339. kill(shm->rcvr_pid, sig);
  340. if (sig != SIGUSR2) /* rcvr does not die on SIGUSR2 */
  341. {
  342. errno = 0;
  343. while (wait_count)
  344. {
  345. if (kill(shm->rcvr_pid, 0) && (errno == ESRCH))
  346. break;
  347. errno = 0;
  348. Nap(40L);
  349. wait_count--;
  350. }
  351. if (!wait_count)
  352. {
  353. while (!kill(shm->rcvr_pid, SIGKILL))
  354. {
  355. wait((int *)0);
  356. Nap(40L);
  357. }
  358. }
  359. shm->rcvr_pid = -1; /* no receiver active */
  360. if (rcvr_log && rcvr_log_file[0])
  361. rcvr_log_fp = fopen(rcvr_log_file, "a");
  362. rcvrdisp_actual(); /* write any buffered screen data */
  363. }
  364. }
  365. } /* end of kill_rcvr_process */
  366. /*+-------------------------------------------------------------------------
  367. rcvr_common_signal_handler(sig)
  368. --------------------------------------------------------------------------*/
  369. CFG_SigType
  370. rcvr_common_signal_handler(sig)
  371. int sig;
  372. {
  373. extern int rcvr_log;
  374. extern int rcvr_log_raw;
  375. extern FILE *rcvr_log_fp;
  376. if (rcvr_log)
  377. {
  378. if (!rcvr_log_raw)
  379. fputs("\n", rcvr_log_fp);
  380. fclose(rcvr_log_fp);
  381. }
  382. if (sig == SIGUSR1)
  383. _exit(0);
  384. termecu(sig - 1 + TERMECU_SIG1);
  385. } /* end of rcvr_common_signal_handler */
  386. /*+-------------------------------------------------------------------------
  387. rcvr_SIGUSR2_handler(sig)
  388. --------------------------------------------------------------------------*/
  389. CFG_SigType
  390. rcvr_SIGUSR2_handler(sig)
  391. int sig;
  392. {
  393. signal(SIGUSR2, rcvr_SIGUSR2_handler);
  394. shmr_process_rcvr_SIGUSR2(sig);
  395. } /* end of rcvr_SIGUSR2_handler */
  396. /*+-------------------------------------------------------------------------
  397. rcvr_death_handler(sig) - unexpected signal; try to dump core
  398. --------------------------------------------------------------------------*/
  399. CFG_SigType
  400. rcvr_death_handler(sig)
  401. int sig;
  402. {
  403. int itmp;
  404. #ifdef WHT
  405. int *open_elevator_shaft = (int *)0xb0000001;
  406. #endif
  407. ttymode(0);
  408. pprintf("\nreceiver process caught signal %d (%s)\n",
  409. sig, signal_name_text(sig));
  410. pprintf("screen cursor (y,x) = (%u,%u)\n", shm->cursor_y, shm->cursor_x);
  411. for (itmp = 1; itmp < NSIG; itmp++)
  412. signal(itmp, SIG_DFL);
  413. #ifdef WHT
  414. signal(SIGSEGV, SIG_DFL);
  415. printf("trapping at 08lx\n", (unsigned long)open_elevator_shaft);
  416. fflush(stdout);
  417. *open_elevator_shaft = itmp;
  418. #else
  419. rcvr_common_signal_handler(sig);
  420. #endif
  421. _exit(-1);
  422. } /* end of rcvr_death_handler */
  423. /*+-------------------------------------------------------------------------
  424. ck_sigint() - return 'sigint' value to fool optimizers
  425. Some optimizing compilers elide if(sigint) checks
  426. --------------------------------------------------------------------------*/
  427. int
  428. ck_sigint()
  429. {
  430. return (sigint);
  431. } /* end of ck_sigint */
  432. /*+-------------------------------------------------------------------------
  433. xmtr_SIGINT_handler()
  434. --------------------------------------------------------------------------*/
  435. CFG_SigType
  436. xmtr_SIGINT_handler(sig)
  437. int sig;
  438. {
  439. if (ttymode_termecu_on_sigint)
  440. termecu(SIGINT);
  441. signal(sig, xmtr_SIGINT_handler);
  442. sigint = 1;
  443. proc_interrupt = 1;
  444. } /* end of xmtr_SIGINT_handler */
  445. /*+-------------------------------------------------------------------------
  446. xmtr_SIGHUP_handler(sig)
  447. --------------------------------------------------------------------------*/
  448. CFG_SigType
  449. xmtr_SIGHUP_handler(sig)
  450. int sig;
  451. {
  452. errno = -1;
  453. termecu(sig - 1 + TERMECU_SIG1);
  454. } /* end of xmtr_SIGHUP_handler */
  455. /*+-------------------------------------------------------------------------
  456. xmtr_SIGTERM_handler(sig)
  457. --------------------------------------------------------------------------*/
  458. CFG_SigType
  459. xmtr_SIGTERM_handler(sig)
  460. int sig;
  461. {
  462. errno = -1;
  463. termecu(sig - 1 + TERMECU_SIG1);
  464. } /* end of xmtr_SIGTERM_handler */
  465. /*+-------------------------------------------------------------------------
  466. xmtr_SIGUSR2_handler()
  467. --------------------------------------------------------------------------*/
  468. CFG_SigType
  469. xmtr_SIGUSR2_handler(sig)
  470. int sig;
  471. {
  472. CFG_SigType xmtr_SIGUSR2_handler();
  473. signal(sig, xmtr_SIGUSR2_handler);
  474. shmx_process_xmtr_SIGUSR2();
  475. } /* end of xmtr_SIGUSR2_handler */
  476. /*+-------------------------------------------------------------------------
  477. xmtr_death_handler(sig) - unexpected signal; try to dump core
  478. --------------------------------------------------------------------------*/
  479. CFG_SigType
  480. xmtr_death_handler(sig)
  481. int sig;
  482. {
  483. int itmp;
  484. #ifdef WHT
  485. int *open_elevator_shaft = (int *)0xb0000000;
  486. #endif
  487. ttymode(0);
  488. pprintf("\ntransmitter process caught signal %d (%s)\n",
  489. sig, signal_name_text(sig));
  490. kill_rcvr_process(SIGUSR1);
  491. for (itmp = 1; itmp < NSIG; itmp++)
  492. signal(itmp, SIG_DFL);
  493. #ifdef WHT
  494. signal(SIGSEGV, SIG_DFL);
  495. printf("trapping @ %08lx\n", (unsigned long)open_elevator_shaft);
  496. fflush(stdout);
  497. *open_elevator_shaft = itmp;
  498. #else
  499. kill((CFG_PidType) getpid(), SIGIOT);
  500. #endif
  501. errno = -1;
  502. termecu(sig - 1 + TERMECU_SIG1);
  503. } /* end of xmtr_death_handler */
  504. /*+-------------------------------------------------------------------------
  505. xmtr_SIGCLD_handler(sig)
  506. --------------------------------------------------------------------------*/
  507. CFG_SigType
  508. xmtr_SIGCLD_handler(sig)
  509. int sig;
  510. {
  511. int itmp;
  512. #if defined(FORK_DEBUG)
  513. char s512[512];
  514. #endif
  515. WAIT:
  516. errno = 0;
  517. if ((last_child_wait_pid = wait(&last_child_wait_status)) < 0)
  518. {
  519. if (errno == EINTR)
  520. goto WAIT;
  521. }
  522. #if defined(FORK_DEBUG)
  523. sprintf(s512, "XMTR SIGCLD pid %d (%s) s=%04x ",
  524. last_child_wait_pid,
  525. (last_child_wait_pid == shm->rcvr_pid) ? "RCVR!" : "AUXOP",
  526. last_child_wait_status);
  527. if (WIFEXITED(last_child_wait_status))
  528. {
  529. sprintf(s512 + strlen(s512), "exit status=%d ",
  530. WEXITSTATUS(last_child_wait_status));
  531. }
  532. if (WIFSIGNALED(last_child_wait_status))
  533. {
  534. sprintf(s512 + strlen(s512), "signal=%d ",
  535. WTERMSIG(last_child_wait_status));
  536. }
  537. logevent(getpid(), s512);/* xmtr_SIGCLD_handler() */
  538. #endif
  539. if ((last_child_wait_pid == shm->rcvr_pid) && (shm->rcvr_pid > 0) &&
  540. !xmtr_killed_rcvr)
  541. {
  542. pprintf("\nECU receiver unexpectedly: wait status=0x%04x\n",
  543. last_child_wait_status);
  544. itmp = 0;
  545. if (WIFEXITED(last_child_wait_status))
  546. {
  547. itmp = 1;
  548. pprintf("exit status=%d ", WEXITSTATUS(last_child_wait_status));
  549. }
  550. if (WIFSIGNALED(last_child_wait_status))
  551. {
  552. itmp = 1;
  553. pprintf("signal=%d (%s)",
  554. signal_name_text(WTERMSIG(last_child_wait_status)));
  555. }
  556. if (itmp)
  557. pputs("\n");
  558. termecu(TERMECU_RCVR_FATAL_ERROR);
  559. }
  560. signal(sig, xmtr_SIGCLD_handler);
  561. } /* end of xmtr_SIGCLD_handler */
  562. /*+-------------------------------------------------------------------------
  563. sig_report(sig)
  564. --------------------------------------------------------------------------*/
  565. #if 0
  566. CFG_SigType
  567. sig_report(sig)
  568. int sig;
  569. {
  570. signal(sig, sig_report);
  571. } /* end of sig_report */
  572. #endif
  573. /*+-------------------------------------------------------------------------
  574. child_signals() - signal() calls for children processes
  575. --------------------------------------------------------------------------*/
  576. void
  577. child_signals()
  578. {
  579. int isig;
  580. for (isig = 0; isig < NSIG; isig++)
  581. signal(isig, SIG_DFL);
  582. } /* end of child_signals */
  583. /*+-------------------------------------------------------------------------
  584. xmtr_signals()
  585. --------------------------------------------------------------------------*/
  586. void
  587. xmtr_signals()
  588. {
  589. int sig;
  590. for (sig = 1; sig < NSIG; sig++)
  591. {
  592. switch (sig)
  593. {
  594. #ifdef WHT
  595. case SIGSEGV:
  596. break;
  597. #endif
  598. case SIGHUP:
  599. signal(sig, xmtr_SIGHUP_handler);
  600. break;
  601. #if defined(SIGSTOP)
  602. /*
  603. * call Roto-Rooter on POSIX plots
  604. */
  605. case SIGSTOP:
  606. case SIGTSTP:
  607. case SIGCONT:
  608. case SIGTTIN:
  609. signal(sig, SIG_IGN);
  610. break;
  611. /*
  612. * ditto, except on Motorola SVR4, we get a funky SIGTTOU
  613. * after fork/exec/wait child exits; this happens to ECU
  614. * when Motorola's csh and to most anybody else upon
  615. * executing any shell
  616. */
  617. case SIGTTOU:
  618. #if defined(SVR4)
  619. signal(sig, SIG_DFL);
  620. #else
  621. signal(sig, SIG_IGN);
  622. #endif
  623. break;
  624. #endif
  625. #ifdef SIGWINCH
  626. case SIGWINCH:
  627. signal(sig, SIG_DFL);
  628. break;
  629. #endif
  630. #ifndef WHT
  631. case SIGQUIT:
  632. signal(sig, SIG_IGN);
  633. break;
  634. #endif
  635. case SIGINT:
  636. signal(sig, xmtr_SIGINT_handler);
  637. break;
  638. case SIGTERM:
  639. signal(sig, xmtr_SIGTERM_handler);
  640. break;
  641. case SIGCLD:
  642. signal(sig, xmtr_SIGCLD_handler);
  643. break;
  644. case SIGUSR1:
  645. signal(sig, SIG_IGN);
  646. break;
  647. case SIGUSR2:
  648. signal(sig, xmtr_SIGUSR2_handler);
  649. break;
  650. default:
  651. #ifndef WHT /* I want the bloody crash */
  652. signal(sig, xmtr_death_handler);
  653. #endif
  654. break;
  655. }
  656. }
  657. } /* end of xmtr_signals */
  658. /*+-------------------------------------------------------------------------
  659. rcvr_signals()
  660. --------------------------------------------------------------------------*/
  661. void
  662. rcvr_signals()
  663. {
  664. int sig;
  665. for (sig = 1; sig < NSIG; sig++)
  666. {
  667. switch (sig)
  668. {
  669. #if defined(SIGSTOP)
  670. case SIGSTOP:
  671. case SIGTSTP:
  672. case SIGCONT:
  673. case SIGTTIN:
  674. signal(sig, SIG_IGN);
  675. break;
  676. /*
  677. * ditto, except on Motorola SVR4, we get a funky SIGTTOU
  678. * after fork/exec/wait child exits; this happens to ECU
  679. * when Motorola's csh and to most anybody else upon
  680. * executing any shell
  681. */
  682. case SIGTTOU:
  683. #if defined(SVR4)
  684. signal(sig, SIG_DFL);
  685. #else
  686. signal(sig, SIG_IGN);
  687. #endif
  688. break;
  689. #endif
  690. #ifdef SIGWINCH
  691. case SIGWINCH:
  692. #endif
  693. case SIGCLD:
  694. signal(sig, SIG_DFL);
  695. break;
  696. case SIGQUIT:
  697. signal(sig, SIG_IGN);
  698. break;
  699. case SIGHUP:
  700. case SIGINT:
  701. case SIGTERM:
  702. case SIGUSR1:
  703. signal(sig, rcvr_common_signal_handler);
  704. break;
  705. case SIGUSR2:
  706. signal(sig, rcvr_SIGUSR2_handler);
  707. break;
  708. default:
  709. #ifndef WHT /* I want the bloody crash */
  710. signal(sig, rcvr_death_handler);
  711. #endif
  712. break;
  713. }
  714. }
  715. } /* end of rcvr_signals */
  716. /* vi: set tabstop=4 shiftwidth=4: */