Diff for /gforth/engine/io.c between versions 1.7 and 1.21

version 1.7, 1998/10/18 23:16:52 version 1.21, 2006/04/09 07:44:13
Line 1 Line 1
 /* direct key io driver; signal handler  /* direct key io driver
   
   Copyright (C) 1995 Free Software Foundation, Inc.    Copyright (C) 1995,1996,1997,1998,1999,2002,2003 Free Software Foundation, Inc.
   
   This file is part of Gforth.    This file is part of Gforth.
   
Line 16 Line 16
   
   You should have received a copy of the GNU General Public License    You should have received a copy of the GNU General Public License
   along with this program; if not, write to the Free Software    along with this program; if not, write to the Free Software
   Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.    Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111, USA.
   
   The following is stolen from the readline library for bash    The following is stolen from the readline library for bash
 */  */
Line 26 Line 26
 */  */
   
 #include "config.h"  #include "config.h"
   #include "forth.h"
 #include <sys/time.h>  #include <sys/time.h>
 #include <sys/types.h>  #include <sys/types.h>
 #include <unistd.h>  #include <unistd.h>
Line 51  typedef unsigned int uint32_t; Line 52  typedef unsigned int uint32_t;
 #include <sys/filio.h>  #include <sys/filio.h>
 #endif  #endif
 #include <setjmp.h>  #include <setjmp.h>
 #include "forth.h"  
 #include "io.h"  #include "io.h"
   
 #ifndef MSDOS  #ifndef MSDOS
Line 447  void deprep_terminal () Line 447  void deprep_terminal ()
 #define VTIME VEOL  #define VTIME VEOL
 #endif  #endif
   
   #include <locale.h>
   
 void prep_terminal ()  void prep_terminal ()
 {  {
   int tty = fileno (stdin);    int tty = fileno (stdin);
Line 472  void prep_terminal () Line 474  void prep_terminal ()
     return;      /* added by MdG */      return;      /* added by MdG */
   }      /* added by MdG */    }      /* added by MdG */
         
     setlocale(LC_ALL, "");
   
   /* 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 613  void deprep_terminal () Line 617  void deprep_terminal ()
 }  }
 #endif  /* NEW_TTY_DRIVER */  #endif  /* NEW_TTY_DRIVER */
   
 /* If a character is available to be read, then read it  
    and stuff it into IBUFFER.  Otherwise, just return. */  
   
 long pending = -1L;  
   
 long key_avail (FILE * stream)  long key_avail (FILE * stream)
 {  {
   int tty = fileno (stream);    int tty = fileno (stream);
   int chars_avail = pending;    fd_set selin;
   int result;    static int now[2] = { 0 , 0 };
     int res;
   if(!terminal_prepped)  prep_terminal();  
     if(!terminal_prepped && stream == stdin)
 #ifndef _WIN32      prep_terminal();
   if(isatty (tty)) {  
     result = ioctl (tty, FIONREAD, &chars_avail);    FD_ZERO(&selin);
   }    FD_SET(tty, &selin);
 #else    return select(1, &selin, NULL, NULL, now);
   {  
     fd_set selin;  
     static int now[2] = { 0 , 0 };  
     int res;  
       
     FD_ZERO(&selin);  
     FD_SET(tty, &selin);  
     chars_avail=select(1, &selin, NULL, NULL, now);  
   }  
 #endif  
     
   if(chars_avail == -1L) {  
     unsigned char inchar;  
       
     fcntl(tty, F_SETFL, O_NDELAY);  
     result = read(tty, &inchar, sizeof(char));  
     if(result == sizeof(char)) {  
       chars_avail = 1;  
       pending = (long)inchar;  
     } else {  
       chars_avail = 0;  
     }  
     fcntl(tty, F_SETFL, 0);  
   }  
   
   return chars_avail;  
 }  }
   
 /* Get a key from the buffer of characters to be read.  /* Get a key from the buffer of characters to be read.
Line 666  long key_avail (FILE * stream) Line 639  long key_avail (FILE * stream)
 /* When compiling and running in the `Posix' environment, Ultrix does  /* When compiling and running in the `Posix' environment, Ultrix does
    not restart system calls, so this needs to do it. */     not restart system calls, so this needs to do it. */
   
 unsigned char getkey(FILE * stream)  Cell getkey(FILE * stream)
 {  {
   int result;    Cell result;
   unsigned char c;    unsigned char c;
   
   if(!terminal_prepped)  prep_terminal();    if(!terminal_prepped)
       prep_terminal();
   
   while (pending < 0)    while (1)
     {      {
       result = read (fileno (stream), &c, sizeof (char));        result = read (fileno (stream), &c, sizeof (char));
   
Line 683  unsigned char getkey(FILE * stream) Line 657  unsigned char getkey(FILE * 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 CTRL('D');          return (EOF);
   
       /* 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 691  unsigned char getkey(FILE * stream) Line 665  unsigned char getkey(FILE * stream)
       if (errno != EINTR)        if (errno != EINTR)
         return (EOF);          return (EOF);
     }      }
   
   result = (int) pending;  
   pending = -1L;  
   
   return result;  
 }  }
   
 #ifdef TEST  #ifdef TEST
Line 739  int main() Line 708  int main()
 #endif  #endif
 #endif /* MSDOS */  #endif /* MSDOS */
   
 /* signal handling adapted from pfe by Dirk Zoller (Copylefted) - anton */  
   
 static void  
 graceful_exit (int sig)  
 {  
   deprep_terminal();  
   fprintf (stderr, "\n\n%s.\n", strsignal (sig));  
   exit (0x80|sig);  
 }  
   
 jmp_buf throw_jmp_buf;  
   
 static void   
 signal_throw(int sig)  
 {  
   int code;  
   struct {  
     int signal;  
     int throwcode;  
   } *p, throwtable[] = {  
     { SIGINT, -28 },  
     { SIGFPE, -55 },  
 #ifdef SIGBUS  
     { SIGBUS, -23 },  
 #endif  
     { SIGSEGV, -9 },  
   };  
   signal(sig,signal_throw);  
   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 ? */  
 }  
   
 UCell cols=80;  
 #if defined(MSDOS) || defined (_WIN32)  
 UCell rows=25;  
 #else  
 UCell rows=24;  
 #endif  
   
 #ifdef SIGCONT  
 static void termprep (int sig)  
 {  
   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  
 }  
   
 static void change_winsize(int sig)  
 {  
   signal(sig,change_winsize);  
 #ifdef TIOCGWINSZ  
   get_winsize();  
 #endif  
 }  
 #endif  
   
 void install_signal_handlers (void)  
 {  
   
 #if 0  
 /* these signals are handled right by default, no need to handle them;  
    they are listed here just for fun */  
   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;  
   
 #define DIM(X)          (sizeof (X) / sizeof *(X))  
 /*  
   for (i = 0; i < DIM (sigs_to_ignore); i++)  
     signal (sigs_to_ignore [i], SIG_IGN);  
 */  
   for (i = 0; i < DIM (sigs_to_throw); i++)  
     signal (sigs_to_throw [i], die_on_signal ? graceful_exit : signal_throw);  
   for (i = 0; i < DIM (sigs_to_quit); i++)  
     signal (sigs_to_quit [i], graceful_exit);  
 #ifdef SIGCONT  
     signal (SIGCONT, termprep);  
 #endif  
 #ifdef SIGWINCH  
     signal (SIGWINCH, change_winsize);  
 #endif  
 }  
 /* end signal handling */  

Removed from v.1.7  
changed lines
  Added in v.1.21


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