Diff for /gforth/Attic/io.c between versions 1.8 and 1.18

version 1.8, 1995/03/13 09:17:29 version 1.18, 1996/10/06 22:24:17
Line 1 Line 1
 /*      direct key io driver  /* direct key io driver; signal handler
   
         The following is stolen from the readline library for bash    Copyright (C) 1995 Free Software Foundation, Inc.
   
     This file is part of Gforth.
   
     Gforth is free software; you can redistribute it and/or
     modify it under the terms of the GNU General Public License
     as published by the Free Software Foundation; either version 2
     of the License, or (at your option) any later version.
   
     This program is distributed in the hope that it will be useful,
     but WITHOUT ANY WARRANTY; without even the implied warranty of
     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
     GNU General Public License for more details.
   
     You should have received a copy of the GNU General Public License
     along with this program; if not, write to the Free Software
     Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
   
     The following is stolen from the readline library for bash
 */  */
   
 /*  /*
    Use -D_POSIX_VERSION for POSIX systems.     Use -D_POSIX_VERSION for POSIX systems.
 */  */
   
   #include "config.h"
 #include <unistd.h>  #include <unistd.h>
   
 #ifdef apollo  #ifdef apollo
Line 15 Line 34
   
 #include <stdio.h>  #include <stdio.h>
 #include <signal.h>  #include <signal.h>
   #include <string.h>
 #include <sys/types.h>  #include <sys/types.h>
 #ifndef apollo  #if !defined(apollo) && !defined(MSDOS)
 #include <sys/ioctl.h>  #include <sys/ioctl.h>
 #endif  #endif
 #include <fcntl.h>  #include <fcntl.h>
Line 25 Line 45
 #include "forth.h"  #include "forth.h"
 #include "io.h"  #include "io.h"
   
   #ifndef MSDOS
 #if defined (__GNUC__)  #if defined (__GNUC__)
 #  define alloca __builtin_alloca  #  define alloca __builtin_alloca
 #else  #else
Line 50 Line 71
   
 /* System V machines use termio. */  /* System V machines use termio. */
 #if !defined (_POSIX_VERSION)  #if !defined (_POSIX_VERSION)
 #  if defined (USG) || defined (hpux) || defined (Xenix) || defined (sgi) || defined (DGUX) || defined (ultrix) || defined (Solaris)  #  if defined (USG) || defined (hpux) || defined (Xenix) || defined (sgi) || defined (DGUX) || defined (ultrix) || defined (Solaris) || defined(_WIN32)
 #    undef NEW_TTY_DRIVER  #    undef NEW_TTY_DRIVER
 #    define TERMIO_TTY_DRIVER  #    define TERMIO_TTY_DRIVER
 #    include <termio.h>  #    include <termio.h>
Line 91 Line 112
 #endif /* !NEW_TTY_DRIVER && !_POSIX_VDISABLE */  #endif /* !NEW_TTY_DRIVER && !_POSIX_VDISABLE */
   
 #include <errno.h>  #include <errno.h>
 extern int errno;  /* extern int errno; */
   
 #if defined (SHELL)  #if defined (SHELL)
 #  include <posixstat.h>  #  include <posixstat.h>
Line 163  static int eof_char = CTRL ('D'); Line 184  static int eof_char = CTRL ('D');
 /* **************************************************************** */  /* **************************************************************** */
   
 /* Non-zero means that the terminal is in a prepped state. */  /* Non-zero means that the terminal is in a prepped state. */
 static int terminal_prepped = 0;  int terminal_prepped = 0;
   
 #if defined (NEW_TTY_DRIVER)  #if defined (NEW_TTY_DRIVER)
   
Line 263  void prep_terminal () Line 284  void prep_terminal ()
   if (terminal_prepped)    if (terminal_prepped)
     return;      return;
   
     if (!isatty(tty)) {      /* added by MdG */
       terminal_prepped = 1;      /* added by MdG */
       return;      /* added by MdG */
     }      /* added by MdG */
      
   oldmask = sigblock (sigmask (SIGINT));    oldmask = sigblock (sigmask (SIGINT));
   
   /* We always get the latest tty values.  Maybe stty changed them. */    /* We always get the latest tty values.  Maybe stty changed them. */
Line 369  void deprep_terminal () Line 395  void deprep_terminal ()
   if (!terminal_prepped)    if (!terminal_prepped)
     return;      return;
   
   /* Added by MdG */
     if (!isatty(tty)) {
       terminal_prepped = 0;
       return;
     }
      
   oldmask = sigblock (sigmask (SIGINT));    oldmask = sigblock (sigmask (SIGINT));
   
   the_ttybuff.sg_flags = original_tty_flags;    the_ttybuff.sg_flags = original_tty_flags;
Line 423  void prep_terminal () Line 455  void prep_terminal ()
   if (terminal_prepped)    if (terminal_prepped)
     return;      return;
   
     if (!isatty(tty))  {     /* added by MdG */
       terminal_prepped = 1;      /* added by MdG */
       return;      /* added by MdG */
     }      /* added by MdG */
      
   /* Try to keep this function from being INTerrupted.  We can do it    /* Try to keep this function from being INTerrupted.  We can do it
      on POSIX and systems with BSD-like signal handling. */       on POSIX and systems with BSD-like signal handling. */
 #if defined (HAVE_POSIX_SIGNALS)  #if defined (HAVE_POSIX_SIGNALS)
Line 527  void deprep_terminal () Line 564  void deprep_terminal ()
   if (!terminal_prepped)    if (!terminal_prepped)
     return;      return;
   
   /* Added by MdG */
     if (!isatty(tty)) {
       terminal_prepped = 0;
       return;
     }
   
 #if defined (HAVE_POSIX_SIGNALS)  #if defined (HAVE_POSIX_SIGNALS)
   sigemptyset (&set);    sigemptyset (&set);
   sigemptyset (&oset);    sigemptyset (&oset);
Line 570  long key_avail (stream) Line 613  long key_avail (stream)
   long chars_avail = pending;    long chars_avail = pending;
   int result;    int result;
   
     if(!terminal_prepped)  prep_terminal();
   
 #if defined (FIONREAD)  #if defined (FIONREAD)
   result = ioctl (tty, FIONREAD, &chars_avail);    result = ioctl (tty, FIONREAD, &chars_avail);
 #endif  #endif
Line 605  unsigned char getkey(stream) Line 650  unsigned char getkey(stream)
   int result;    int result;
   unsigned char c;    unsigned char c;
   
     if(!terminal_prepped)  prep_terminal();
   
   while (pending < 0)    while (pending < 0)
     {      {
       result = read (fileno (stream), &c, sizeof (char));        result = read (fileno (stream), &c, sizeof (char));
Line 615  unsigned char getkey(stream) Line 662  unsigned char getkey(stream)
       /* If zero characters are returned, then the file that we are        /* If zero characters are returned, then the file that we are
          reading from is empty!  Return EOF in that case. */           reading from is empty!  Return EOF in that case. */
       if (result == 0)        if (result == 0)
         return (0);          return CTRL('D');
   
       /* If the error that we received was SIGINT, then try again,        /* If the error that we received was SIGINT, then try again,
          this is simply an interrupted system call to read ().           this is simply an interrupted system call to read ().
Line 669  int main() Line 716  int main()
         puts("");          puts("");
 }  }
 #endif  #endif
   #endif /* MSDOS */
   
 /* signal handling taken from pfe by Dirk Zoller (Copylefted) - anton */  /* signal handling adapted from pfe by Dirk Zoller (Copylefted) - anton */
 /* !! needs cleanup */  
 char *  
 sigmsg (int sig)  
 {  
         static char buf [25];  
         static char *msg [] =  
         {  
                 "Hangup",       /* These strings are cited from */  
                 "Interrupt",    /* Rochkind: Advanced UNIX programming */  
                 "Quit",  
                 "Illegal Instruction",  
                 "Trace Trap",  
                 "IOT instruction",  
                 "EMT instruction",  
                 "Floating point exception",  
                 "Kill",  
                 "Bus error",  
                 "Segmentation Violation",  
                 "Bad arg to system call",  
                 "Broken pipe",  
                 "Alarm clock",  
                 "Terminate signal",  
                 "User signal 1",  
                 "User signal 2",  
         };  
   
         if ((unsigned)sig <= 17)  
                 return msg [sig - 1];  
         sprintf (buf, "signal %d received", sig);  
         return buf;  
 }  
   
 static void  static void
 graceful_exit (int sig)  graceful_exit (int sig)
 {  {
   deprep_terminal();    deprep_terminal();
   if ((unsigned)sig <= 17)    fprintf (stderr, "\n\n%s.\n", strsignal (sig));
     fprintf (stderr, "\n\n%s.\n", sigmsg (sig));  
   else  
     fprintf (stderr, "\n\nSignal %d received, terminated.\n", sig);  
   exit (0x80|sig);    exit (0x80|sig);
 }  }
   
Line 719  jmp_buf throw_jmp_buf; Line 733  jmp_buf throw_jmp_buf;
 static void   static void 
 signal_throw(int sig)  signal_throw(int sig)
 {  {
   static int throw_codes[] = {    int code;
     -256,    struct {
     -28,      int signal;
     -257,      int throwcode;
     -258,    } *p, throwtable[] = {
     -259,      { SIGINT, -28 },
     -260,      { SIGFPE, -55 },
     -261,  #ifdef SIGBUS
     -55,      { SIGBUS, -23 },
     -262,  #endif
     -23,      { SIGSEGV, -9 },
     -9,  
     -263,  
     -264,  
     -265,  
     -266,  
     -267,  
     -268,  
   };    };
   signal(sig,signal_throw);    signal(sig,signal_throw);
   longjmp(throw_jmp_buf,throw_codes[sig-1]); /* or use siglongjmp ? */    for (code=-256-sig, p=throwtable; p<throwtable+(sizeof(throwtable)/sizeof(*p)); p++)
       if (sig == p->signal) {
         code = p->throwcode;
         break;
       }
     longjmp(throw_jmp_buf,code); /* or use siglongjmp ? */
 }  }
   
 static void  UCell cols=80;
 termprep (int sig)  #if defined(MSDOS) || defined (_WIN32)
   UCell rows=25;
   #else
   UCell rows=24;
   #endif
   
   #ifdef SIGCONT
   static void termprep (int sig)
 {  {
   terminal_prepped=0; prep_terminal();  
   signal(sig,termprep);    signal(sig,termprep);
     terminal_prepped=0;
   }
   #endif
   
   #ifdef SIGWINCH
   void get_winsize()
   {
   #ifdef TIOCGWINSZ
     struct winsize size;
     
     if (ioctl (1, TIOCGWINSZ, (char *) &size) >= 0) {
       rows = size.ws_row;
       cols = size.ws_col;
     }
   #else
     char *s, *ends;
     unsigned long ul;
     if (s=getenv("LINES")) {
       rows=atoi(s);
       if (rows==0)
         rows=24;
     }
     if (s=getenv("COLUMNS")) {
       rows=atoi(s);
       if (rows==0)
         cols=80;
     }
   #endif
 }  }
   
 void  static void change_winsize(int sig)
 install_signal_handlers (void)  
 {  {
 /* !! These definitions seem to be system dependent    signal(sig,change_winsize);
    We could have them in the machine.h file,  #ifdef TIOCGWINSZ
    but I would like something more automatic - anton */    get_winsize();
 #define SIGS_TO_IGNORE  SIGCHLD  #endif
 #define SIGS_TO_ABORT   SIGINT, SIGILL, SIGFPE, SIGUSR1, SIGSEGV, SIGUSR2, \  }
                         SIGALRM,  SIGBUS  #endif
 #define SIGS_TO_QUIT    SIGHUP, SIGQUIT, SIGABRT, SIGPIPE, \  
                         SIGTERM   void install_signal_handlers (void)
 #define SIGS_TO_TERMPREP    SIGCONT  {
   
   static short sigs_to_ignore [] = { SIGS_TO_IGNORE };  #if 0
   static short sigs_to_abort [] = { SIGS_TO_ABORT };  /* these signals are handled right by default, no need to handle them;
   static short sigs_to_quit [] = { SIGS_TO_QUIT };     they are listed here just for fun */
   static short sigs_to_termprep [] = { SIGS_TO_TERMPREP };    static short sigs_to_default [] = {
   #ifdef SIGCHLD
       SIGCHLD,
   #endif
   #ifdef SIGINFO
       SIGINFO,
   #endif
   #ifdef SIGIO
       SIGIO,
   #endif
   #ifdef SIGLOST
       SIGLOST,
   #endif
   #ifdef SIGKILL
       SIGKILL,
   #endif
   #ifdef SIGSTOP
       SIGSTOP,
   #endif
   #ifdef SIGPWR
       SIGPWR,
   #endif
   #ifdef SIGMSG
       SIGMSG,
   #endif
   #ifdef SIGDANGER
       SIGDANGER,
   #endif
   #ifdef SIGMIGRATE
       SIGMIGRATE,
   #endif
   #ifdef SIGPRE
       SIGPRE,
   #endif
   #ifdef SIGVIRT
       SIGVIRT,
   #endif
   #ifdef SIGGRANT
       SIGGRANT,
   #endif
   #ifdef SIGRETRACT
       SIGRETRACT,
   #endif
   #ifdef SIGSOUND
       SIGSOUND,
   #endif
   #ifdef SIGSAK
       SIGSAK,
   #endif
   #ifdef SIGTSTP
       SIGTSTP,
   #endif
   #ifdef SIGTTIN
       SIGTTIN,
   #endif
   #ifdef SIGTTOU
       SIGTTOU,
   #endif
   #ifdef SIGSTKFLT
       SIGSTKFLT,
   #endif
   #ifdef SIGUNUSED
       SIGUNUSED,
   #endif
     };
   #endif
   
     static short sigs_to_throw [] = {
   #ifdef SIGBREAK
       SIGBREAK,
   #endif
   #ifdef SIGINT
       SIGINT,
   #endif
   #ifdef SIGILL
       SIGILL,
   #endif
   #ifdef SIGEMT
       SIGEMT,
   #endif
   #ifdef SIGFPE
       SIGFPE,
   #endif
   #ifdef SIGIOT
       SIGIOT,
   #endif
   #ifdef SIGSEGV
       SIGSEGV,
   #endif
   #ifdef SIGALRM
       SIGALRM,
   #endif
   #ifdef SIGPIPE
       SIGPIPE,
   #endif
   #ifdef SIGPOLL
       SIGPOLL,
   #endif
   #ifdef SIGPROF
       SIGPROF,
   #endif
   #ifdef SIGBUS
       SIGBUS,
   #endif
   #ifdef SIGSYS
       SIGSYS,
   #endif
   #ifdef SIGTRAP
       SIGTRAP,
   #endif
   #ifdef SIGURG
       SIGURG,
   #endif
   #ifdef SIGUSR1
       SIGUSR1,
   #endif
   #ifdef SIGUSR2
       SIGUSR2,
   #endif
   #ifdef SIGVTALRM
       SIGVTALRM,
   #endif
   #ifdef SIGXFSZ
       SIGXFSZ,
   #endif
     };
     static short sigs_to_quit [] = {
   #ifdef SIGHUP
       SIGHUP,
   #endif
   #ifdef SIGQUIT
       SIGQUIT,
   #endif
   #ifdef SIGABRT
       SIGABRT,
   #endif
   #ifdef SIGTERM
       SIGTERM,
   #endif
   #ifdef SIGXCPU
       SIGXCPU,
   #endif
     };
   int i;    int i;
   
 #define DIM(X)          (sizeof (X) / sizeof *(X))  #define DIM(X)          (sizeof (X) / sizeof *(X))
   /*
   for (i = 0; i < DIM (sigs_to_ignore); i++)    for (i = 0; i < DIM (sigs_to_ignore); i++)
     if (sigs_to_ignore [i])      signal (sigs_to_ignore [i], SIG_IGN);
       signal (sigs_to_ignore [i], SIG_IGN);  */
   for (i = 0; i < DIM (sigs_to_abort); i++)    for (i = 0; i < DIM (sigs_to_throw); i++)
     signal (sigs_to_abort [i], signal_throw); /* !! change to throw */      signal (sigs_to_throw [i], signal_throw);
   for (i = 0; i < DIM (sigs_to_quit); i++)    for (i = 0; i < DIM (sigs_to_quit); i++)
     signal (sigs_to_quit [i], graceful_exit);      signal (sigs_to_quit [i], graceful_exit);
   for (i = 0; i < DIM (sigs_to_termprep); i++)  #ifdef SIGCONT
     signal (sigs_to_termprep [i], termprep);      signal (SIGCONT, termprep);
   #endif
   #ifdef SIGWINCH
       signal (SIGWINCH, change_winsize);
   #endif
 }  }
 /* end signal handling */  /* end signal handling */

Removed from v.1.8  
changed lines
  Added in v.1.18


FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>