home *** CD-ROM | disk | FTP | other *** search
/ Usenet 1994 January / usenetsourcesnewsgroupsinfomagicjanuary1994.iso / sources / unix / volume13 / vn.jan.88 / part03 / sig_set.c < prev    next >
Encoding:
C/C++ Source or Header  |  1988-01-30  |  4.4 KB  |  206 lines

  1. /*
  2. ** vn news reader.
  3. **
  4. ** sig_set.c - signal handler
  5. **
  6. ** see copyright disclaimer / history in vn.c source file
  7. */
  8.  
  9. #include <stdio.h>
  10. #include <sys/signal.h>
  11. #include <sgtty.h>
  12. #include <setjmp.h>
  13. #include "tty.h"
  14. #include "config.h"
  15. #include "brk.h"
  16. #include "tune.h"
  17. #include "node.h"
  18. #include "page.h"
  19.  
  20. extern int L_allow;
  21. extern char *Version;
  22. extern char *Brk_fmt;
  23. extern char *Vns_version;
  24.  
  25. static int Sigflag=BRK_INIT;    /* phase of interaction */
  26. static FILE **Fpseek;        /* article reading file pointer pointer */
  27. static int Foreground;
  28. static jmp_buf Jumploc;        /* for BRK_SESS phase */
  29. static int Need_restart = 0;
  30.  
  31. /*
  32.     interrupt handler - unusual termination (longjmp and printex aborts)
  33.     if not abort, remember to reset signal trap
  34.     CAUTION - the passing of a jump buffer is a little dicey - assumes
  35.     type jump_buf is an array.
  36.  
  37.     sigcatch and sig_set control a lot of i/o on stderr also, since
  38.     it is so intimately related to signal interaction.  Note that the
  39.     SIGTSTP action causes a "stopped on tty output" if raw terminal
  40.     mode is restored by tty_set(RESTORE).  We don't get it if we were
  41.     already cooked since tty_set avoids calling ioctl if it doesn't
  42.     have to.
  43. */
  44. static sigcatch (sig)
  45. int sig;
  46. {
  47.     char buf [MAX_C+1];
  48.     int pgrp;
  49.  
  50.     /* disable signal while processing it */
  51.     signal (sig,SIG_IGN);
  52.  
  53.     switch (sig)
  54.     {
  55.     case SIGINT:
  56.     case SIGQUIT:
  57.         break;
  58.  
  59. #ifdef JOBCONTROL
  60.     case SIGTSTP:
  61.         /* ignore SIGTTOU so we don't get stopped if [kc]sh grabs the tty */
  62.         signal(SIGTTOU, SIG_IGN);
  63.         tty_set (SAVEMODE);
  64.         term_set (MOVE,0,L_allow+RECBIAS-1);
  65.         printf ("\n");
  66.         Foreground = 0;
  67.         fflush (stdout);
  68.         fflush (stderr);
  69.         signal(SIGTTOU, SIG_DFL);
  70.  
  71.         /* Send the TSTP signal to suspend our process group */
  72.         signal(SIGTSTP, SIG_DFL);
  73.         sigsetmask(0);
  74.         kill (0, SIGTSTP);
  75.  
  76.         /* WE ARE NOW STOPPED */
  77.  
  78.         /*
  79.                 WELCOME BACK!
  80.                 if terminals process group is ours, we are foregrounded again
  81.                 and can turn newsgroup name printing back on
  82.             */
  83.         tty_set (RESTORE);
  84.  
  85.         /*
  86.         ** Note concerning RESTART.  If in state BRK_IN, we simply
  87.         ** set a flag to do it upon switch to state BRK_SESS - we
  88.         ** don't want to send i/o to the terminal when we
  89.         ** background during BRK_IN phase ("stopped on tty output")
  90.         */
  91.         switch (Sigflag)
  92.         {
  93.         case BRK_SESS:
  94.             signal (SIGTSTP,sigcatch);
  95.             term_set (RESTART);
  96.             longjmp (Jumploc,1);
  97.         case BRK_IN:
  98.             Need_restart = 1;
  99.             ioctl (1,TIOCGPGRP,&pgrp);
  100.             if (pgrp == getpgrp(0))
  101.                 Foreground = 1;
  102.             break;
  103.         default:
  104.             term_set (RESTART);
  105.             break;
  106.         }
  107.         signal (SIGTSTP,sigcatch);
  108.         return;
  109. #endif
  110.     default:
  111.         printex (Brk_fmt,sig);
  112.     }
  113.  
  114.     /* QUIT and INTERRUPT signals */
  115.     switch (Sigflag)
  116.     {
  117.     case BRK_SESS:
  118.         /* if in session, ask if really a quit, do longjump if not */
  119.         term_set (ERASE);
  120.         tty_set (RAWMODE);
  121.         user_str (buf, BRK_PR, 1, "");
  122.         if (buf[0] == 'y')
  123.             printex (Brk_fmt,sig);
  124.         signal (sig,sigcatch);
  125.         longjmp (Jumploc,1);
  126.     case BRK_READ:
  127.         /* if reading seek file to end to abort page printing */
  128.         printf ("\n");
  129.         if (*Fpseek == NULL || fseek(*Fpseek,0L,2) < 0)
  130.             putchar ('\07');
  131.         break;
  132.     default:
  133.         printex (Brk_fmt,sig);
  134.     }
  135.     signal (sig,sigcatch);
  136. }
  137.  
  138. /*
  139.     sig_set controls what will be done with a signal when picked up by
  140.     sigcatch.  fgprintf is included here to keep knowledge
  141.     of TSTP state localized.
  142. */
  143. /* VARARGS */
  144. sig_set (flag,dat)
  145. int flag, *dat;
  146. {
  147.     int i, *xfer, pgrp;
  148.     if (Sigflag == BRK_INIT)
  149.     {
  150.         signal (SIGINT,sigcatch);
  151.         signal (SIGQUIT,sigcatch);
  152.         signal (SIGTERM,sigcatch);
  153. #ifdef JOBCONTROL
  154.         signal (SIGTSTP,sigcatch);
  155.         ioctl (1,TIOCGPGRP,&pgrp);
  156.         if (pgrp == getpgrp(0))
  157.         {
  158.             Foreground = 1;
  159.             fgprintf ("Visual News, %s(%s), reading:\n",
  160.                     Version, Vns_version);
  161.         }
  162.         else
  163.             Foreground = 0;
  164. #else
  165.         Foreground = NOJOB_FG;
  166. #endif
  167.     }
  168.     switch (flag)
  169.     {
  170.     case BRK_IN:
  171.     case BRK_OUT:
  172.         Sigflag = flag;
  173.         break;
  174.     case BRK_READ:
  175.         if (Sigflag != BRK_SESS)
  176.             printex ("unexpected read state, sig_set\n");
  177.         Fpseek = (FILE **) dat;
  178.         Sigflag = BRK_READ;
  179.         break;
  180.     case BRK_SESS:
  181.         if (Need_restart)
  182.             term_set(RESTART);
  183.         xfer = (int *) Jumploc;
  184.         for (i=0; i < sizeof(Jumploc) / sizeof(int); ++i)
  185.             xfer[i] = dat[i];
  186.         Sigflag = BRK_SESS;
  187.         break;
  188.     case BRK_RFIN:
  189.         if (Sigflag != BRK_READ)
  190.             printex ("unexpected finish state, sig_set\n");
  191.         Sigflag = BRK_SESS;
  192.         break;
  193.     default:
  194.         printex ("bad state %d, sig_set\n",flag);
  195.     }
  196. }
  197.  
  198. fgprintf (fs,a,b,c,d,e)
  199. char *fs;
  200. int a,b,c,d,e;
  201. {
  202.     if (Foreground)
  203.         fprintf (stderr,fs,a,b,c,d,e);
  204.     fflush (stderr);
  205. }
  206.