home *** CD-ROM | disk | FTP | other *** search
/ Usenet 1994 October / usenetsourcesnewsgroupsinfomagicoctober1994disk2.iso / unix / volume18 / mush6.4 / part05 / signals.c < prev    next >
Encoding:
C/C++ Source or Header  |  1989-03-12  |  10.2 KB  |  364 lines

  1. /* @(#)signals.c    (c) copyright 10/18/86 (Dan Heller) */
  2.  
  3. #include "mush.h"
  4.  
  5. #ifndef SYSV
  6. extern char *sys_siglist[];
  7. #else
  8. /* sys-v doesn't have normal sys_siglist */
  9. static char    *sys_siglist[] = {
  10. /* no error */  "no error",
  11. /* SIGHUP */    "hangup",
  12. /* SIGINT */    "interrupt (rubout)",
  13. /* SIGQUIT */    "quit (ASCII FS)",
  14. /* SIGILL */    "illegal instruction (not reset when caught)",
  15. /* SIGTRAP */    "trace trap (not reset when caught)",
  16. /* SIGIOT */    "IOT instruction",
  17. /* SIGEMT */    "EMT instruction",
  18. /* SIGFPE */    "floating point exception",
  19. /* SIGKILL */    "kill (cannot be caught or ignored)",
  20. /* SIGBUS */    "bus error",
  21. /* SIGSEGV */    "segmentation violation",
  22. /* SIGSYS */    "bad argument to system call",
  23. /* SIGPIPE */    "write on a pipe with no one to read it",
  24. /* SIGALRM */    "alarm clock",
  25. /* SIGTERM */    "software termination signal from kill",
  26. /* SIGUSR1 */    "user defined signal 1",
  27. /* SIGUSR2 */    "user defined signal 2",
  28. /* SIGCLD */    "death of a child",
  29. /* SIGPWR */    "power-fail restart"
  30. };
  31. #endif /* SYSV */
  32.  
  33. #ifdef SUNTOOL
  34. msgwin_handlesigwinch()
  35. {
  36.     register struct rect rect;
  37.     if (exec_pid)
  38.     return;
  39.     rect = msg_rect;
  40.     pw_damaged(msg_win);
  41.     /* this prevents old screen from being lost when editor finishes */
  42.     if (isoff(glob_flags, IS_GETTING))
  43.     gfxsw_interpretesigwinch(msg_sw->ts_data);
  44.     gfxsw_handlesigwinch(msg_sw->ts_data);
  45.     pw_repairretained(msg_win);
  46.     pw_donedamaged(msg_win);
  47.     win_getrect(msg_sw->ts_windowfd, &msg_rect);
  48.     crt = msg_rect.r_height / l_height(curfont);
  49.     if (rect.r_height != msg_rect.r_height || rect.r_width != rect.r_width)
  50.     if (getting_opts == 1)
  51.         display_opts(0);
  52.     else if (getting_opts == 2)
  53.         set_fkeys();
  54.     else if (msg_pix)
  55.         scroll_win(0);
  56. }
  57.  
  58. hdrwin_handlesigwinch()
  59. {
  60.     register struct rect rect;
  61.     rect = hdr_rect;
  62.     pw_damaged(hdr_win);
  63.     gfxsw_interpretesigwinch(hdr_sw->ts_data);
  64.     gfxsw_handlesigwinch(hdr_sw->ts_data);
  65.     pw_repairretained(hdr_win);
  66.     pw_donedamaged(hdr_win);
  67.     win_getrect(hdr_sw->ts_windowfd, &hdr_rect);
  68.     if (rect.r_width != hdr_rect.r_width || rect.r_height != hdr_rect.r_height){
  69.     pw_writebackground(hdr_win, 0,0,
  70.                hdr_rect.r_width, hdr_rect.r_height, PIX_CLR);
  71.     screen = hdr_rect.r_height/l_height(DEFAULT);
  72.     (void) do_hdrs(0, DUBL_NULL, NULL);
  73.     }
  74. }
  75.  
  76. print_sigwinch()
  77. {
  78.     pw_damaged(print_win);
  79.     gfxsw_handlesigwinch(print_sw->ts_data);
  80.     pw_writebackground(print_win, 0,0,
  81.         win_getwidth(print_sw->ts_windowfd),
  82.     win_getheight(print_sw->ts_windowfd), PIX_CLR);
  83.     pw_donedamaged(print_win);
  84.     print(NULL);  /* reprint whatever was there before damage */
  85. }
  86.  
  87. SIGRET
  88. sigwinchcatcher()
  89. {
  90.     tool_sigwinch(tool);
  91. }
  92. #endif /* SUNTOOL */
  93.  
  94. SIGRET
  95. intrpt(sig)
  96. {
  97.     Debug("interrupt() caught: %d\n", sig);
  98.     mac_flush();
  99.     turnon(glob_flags, WAS_INTR);
  100. }
  101.  
  102. /*
  103.  * catch signals to reset state of the machine.  Always print signal caught.
  104.  * If signals are ignored, return.  If we're running the shell, longjmp back.
  105.  */
  106. /*ARGSUSED*/
  107. SIGRET
  108. catch(sig)
  109. {
  110.     Debug("Caught signal: %d\n", sig);
  111.     (void) signal(sig, catch);
  112.     if (ison(glob_flags, IGN_SIGS) && sig != SIGTERM && sig != SIGHUP)
  113.     return;
  114.     mac_flush();
  115.     print("%s: %s\n", prog_name, sys_siglist[sig]);
  116.     turnoff(glob_flags, IS_PIPE);
  117.     if (istool || sig == SIGTERM || sig == SIGHUP) {
  118.     if (istool) /* istool is 2 if tool is complete */
  119.         istool = 1;
  120.     (void) setjmp(jmpbuf);
  121.     if (ison(glob_flags, IS_GETTING))
  122.         rm_edfile(-1);
  123.     cleanup(sig);
  124.     }
  125.     if (ison(glob_flags, DO_SHELL)) {
  126.     /* wrapcolumn may have been trashed -- restore it */
  127.     if (ison(glob_flags, IS_GETTING)) {
  128.         char *fix = do_set(set_options, "wrapcolumn");
  129.         if (fix && *fix)
  130.         wrapcolumn = atoi(fix);
  131.     }
  132.     turnoff(glob_flags, IS_GETTING);
  133.     longjmp(jmpbuf, 1);
  134.     } else
  135.     puts("exiting"), cleanup(sig);
  136. }
  137.  
  138. #ifdef SIGCONT
  139. SIGRET
  140. stop_start(sig)
  141. {
  142.     extern FILE *ed_fp;
  143.  
  144.     Debug("Caught signal: %d", sig);
  145.     if (sig == SIGCONT) {
  146.     (void) signal(SIGTSTP, stop_start);
  147.     (void) signal(SIGCONT, stop_start);
  148.     echo_off();
  149.     if (istool || ison(glob_flags, IGN_SIGS) && !iscurses)
  150.         return;
  151.     /* we're not in an editor but we're editing a letter */
  152.     if (ison(glob_flags, IS_GETTING)) {
  153.         if (ed_fp)
  154.         print("(Continue editing letter)\n");
  155.     }
  156. #ifdef CURSES
  157.     else if (iscurses)
  158.         if (ison(glob_flags, IGN_SIGS)) {
  159.         clr_bot_line();
  160.         if (msg_list)
  161.             puts(compose_hdr(current_msg));
  162.         mail_status(1), addstr("...continue... ");
  163.         refresh();
  164.         } else {
  165.         int curlin = max(1, current_msg - n_array[0] + 1);
  166.         redraw();
  167.         print("Continue");
  168.         move(curlin, 0);
  169.         refresh();
  170.         /* make sure we lose reverse video on continuation */
  171.         if (ison(glob_flags, REV_VIDEO) && msg_cnt) {
  172.             char buf[256];
  173.             (void) strncpy(buf, compose_hdr(current_msg), COLS-1);
  174.             buf[COLS-1] = 0; /* strncpy does not null terminate */
  175.             mvaddstr(curlin, 0, buf);
  176.         }
  177.         }
  178. #endif /* CURSES */
  179.       else
  180.         mail_status(1), fflush(stdout);
  181.     } else {
  182. #ifdef CURSES
  183.     if (iscurses) {
  184.         /* when user stops mush, the current header is not in reverse
  185.          * video -- note that a refresh() has not been called in curses.c!
  186.          * so, make sure that when a continue is called, the reverse video
  187.          * for the current message returns.
  188.          */
  189.         turnon(glob_flags, WAS_INTR);
  190.         if (isoff(glob_flags, IGN_SIGS) && ison(glob_flags, REV_VIDEO) &&
  191.             msg_cnt) {
  192.         int curlin = max(1, current_msg - n_array[0] + 1);
  193.         char buf[256];
  194.         scrn_line(curlin, buf);
  195.         STANDOUT(curlin, 0, buf);
  196.         }
  197.         print("Stopping...");
  198.     }
  199. #endif /* CURSES */
  200.     echo_on();
  201.     (void) signal(SIGTSTP, SIG_DFL);
  202.     (void) signal(SIGCONT, stop_start);
  203.     (void) kill(getpid(), sig);
  204.     }
  205. }
  206. #endif /* SIGCONT */
  207.  
  208. /*ARGSUSED*/
  209. void
  210. cleanup(sig)
  211. {
  212.     char buf[128], c;
  213.     if (sig != SIGTERM && sig != SIGHUP && ison(glob_flags, IGN_SIGS))
  214.     c = 'n';
  215.     else
  216.     c = 'y';
  217.  
  218. #ifdef CURSES
  219.     if (iscurses)
  220.     iscurses = FALSE, endwin();
  221. #endif /* CURSES */
  222.  
  223.     echo_on();
  224.  
  225.     if (ison(glob_flags, IS_GETTING))
  226.     turnoff(glob_flags, IS_GETTING), dead_letter();
  227.     if ((sig == SIGSEGV || sig == SIGBUS) && isoff(glob_flags, IGN_SIGS)
  228.     && *tempfile) {
  229.     fprintf(stderr, "remove %s [y]? ", tempfile), fflush(stderr);
  230.     if (fgets(buf, sizeof(buf), stdin))
  231.         c = lower(*buf);
  232.     }
  233.     if (c != 'n' && *tempfile && unlink(tempfile) && !sig && errno != ENOENT)
  234.     error(tempfile);
  235.     if (sig == SIGSEGV || sig == SIGBUS) {
  236.     if (isoff(glob_flags, IGN_SIGS)) {
  237.         fprintf(stderr, "coredump [n]? "), fflush(stderr);
  238.         if (fgets(buf, sizeof(buf), stdin))
  239.         c = lower(*buf);
  240.     }
  241.     if (c == 'y')
  242.         puts("dumping core for debugging"), abort();
  243.     }
  244.     exit(sig);
  245. }
  246.  
  247. long    last_spool_size = -1;    /* declared here cuz it's initialized here */
  248.  
  249. /*
  250.  * if new mail comes in, print who it's from.  sprintf it all into one
  251.  * buffer and print that instead of separate print statements to allow
  252.  * the tool mode to make one print statement. The reason for this is that
  253.  * when the tool is refreshed (caused by a resize, reopen, move, top, etc)
  254.  * the last thing printed is displayed -- display the entire line.
  255.  * return 0 if no new mail, 1 if new mail and -1 if new mail is in system
  256.  * folder, but current mbox is not system mbox.
  257.  */
  258. check_new_mail()
  259. {
  260.     int        ret_value;
  261.     char        buf[BUFSIZ];
  262.     register char  *p = buf;
  263.  
  264. #ifdef SUNTOOL
  265.     static int is_iconic, was_iconic;
  266.  
  267.     if (istool) {
  268.     timerclear(&(mail_timer.it_interval));
  269.     timerclear(&(mail_timer.it_value));
  270.     mail_timer.it_value.tv_sec = time_out;
  271.     setitimer(ITIMER_REAL, &mail_timer, NULL);
  272.     }
  273. #endif /* SUNTOOL */
  274.     /* if fullscreen access in progress (help), don't do anything */
  275.     if (ret_value = mail_size()) {
  276. #ifdef CURSES
  277.     int new_hdrs = last_msg_cnt;
  278. #endif /* CURSES */
  279. #ifdef SUNTOOL
  280.     /* if our status has changed from icon to toolform, then
  281.      * there will already be a message stating number of new
  282.      * messages.  reset `n' to msg_cnt so we don't restate
  283.      * the same # of new messages upon receipt of yet another new message.
  284.      */
  285.     if (istool && !(is_iconic = (tool->tl_flags&TOOL_ICONIC)) && was_iconic)
  286.         last_msg_cnt = msg_cnt;
  287. #endif /* SUNTOOL */
  288.     if (last_spool_size > spool_size) {
  289.         wprint("Someone changed \"%s\"! Reinitializing...\n", mailfile);
  290.         if (isoff(glob_flags, READ_ONLY))
  291.         (void) emptyfile(&tmpf, tempfile);
  292.         msg_cnt = 0;
  293.     }
  294.     (void) load_folder(mailfile, 1, NULL);
  295.     if (msg_cnt < last_msg_cnt)
  296.         turnoff(glob_flags, NEW_MAIL);
  297.     else
  298.         turnon(glob_flags, NEW_MAIL);
  299.     if (istool) {
  300.         mail_status(0);
  301.         (void) do_hdrs(0, DUBL_NULL, NULL);
  302.         bell();
  303.     }
  304.     if (msg_cnt < last_msg_cnt) {
  305.         last_msg_cnt = msg_cnt;
  306.         last_spool_size = spool_size;
  307.         if (!istool)
  308.         mail_status(0);
  309.         return 0;
  310.     }
  311.     p += Strcpy(p, "New mail ");
  312.     if (msg_cnt - last_msg_cnt <= 1)
  313.         p += strlen(sprintf(p, "(#%d) ", msg_cnt));
  314.     else
  315.         p += strlen(sprintf(p, "(#%d thru #%d)\n", last_msg_cnt+1,msg_cnt));
  316. #ifdef SUNTOOL
  317.     /*
  318.      * If mush is in tool mode and in icon form, don't update
  319.      * last_msg_cnt so that when the tool is opened, print() will
  320.      * print the correct number of "new" messages.
  321.      */
  322.     if (!istool || !(was_iconic = tool->tl_flags & TOOL_ICONIC))
  323. #endif /* SUNTOOL */
  324.         if (iscurses && isoff(glob_flags, CNTD_CMD))
  325.         last_msg_cnt = msg_cnt;
  326.         else while (last_msg_cnt < msg_cnt) {
  327.         char *p2 = compose_hdr(last_msg_cnt++) + 9;
  328.         if (strlen(p2) + (p - buf) >= BUFSIZ-5) {
  329.             (void) strcat(p, "...\n");
  330.             /* force a break by setting last_msg_cnt correctly */
  331.             last_msg_cnt = msg_cnt;
  332.         } else
  333.             p += strlen(sprintf(p, " %s\n", p2));
  334.         }
  335. #ifdef CURSES
  336.     if (iscurses && isoff(glob_flags, CNTD_CMD)) {
  337.         if (new_hdrs - n_array[screen-1] < screen)
  338.         (void) do_hdrs(0, DUBL_NULL, NULL);
  339.         print("%s ...", buf);
  340.     } else
  341. #endif /* CURSES */
  342.         print("%s", buf); /* buf might have %'s in them!!! */
  343.     } else
  344. #ifdef SUNTOOL
  345.     if (!istool || !is_iconic)
  346. #endif /* SUNTOOL */
  347.         turnoff(glob_flags, NEW_MAIL);
  348.     if (last_spool_size > -1 && /* handle first case */
  349.         strcmp(mailfile, spoolfile) && last_spool_size < spool_size)
  350.     print("You have new mail in your system mailbox.\n"), ret_value = -1;
  351.     last_spool_size = spool_size;
  352.     return ret_value;
  353. }
  354.  
  355. /*ARGSUSED*/   /* we ignore the sigstack, cpu-usage, etc... */
  356. SIGRET
  357. bus_n_seg(sig)
  358. {
  359.     (void) signal(sig, SIG_DFL);
  360.     fprintf(stderr, "%s: %s\n", prog_name,
  361.     (sig == SIGSEGV)? "Segmentation violation": "Bus error");
  362.     cleanup(sig);
  363. }
  364.