--- gforth/engine/io.c 1997/07/31 16:17:26 1.3 +++ gforth/engine/io.c 2007/07/01 20:01:32 1.29 @@ -1,6 +1,6 @@ -/* 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,2006 Free Software Foundation, Inc. This file is part of Gforth. @@ -16,7 +16,7 @@ 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. + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111, USA. The following is stolen from the readline library for bash */ @@ -26,16 +26,23 @@ */ #include "config.h" +#include "forth.h" +#include +#include #include #if defined(apollo) || defined(_WIN32) #define _POSIX_VERSION #endif +#if !defined(Solaris) && defined(sun) && defined(__svr4__) +#define Solaris +typedef unsigned int uint32_t; +#endif + #include #include #include -#include #if !defined(apollo) && !defined(MSDOS) #include #endif @@ -45,7 +52,6 @@ #include #endif #include -#include "forth.h" #include "io.h" #ifndef MSDOS @@ -441,6 +447,8 @@ void deprep_terminal () #define VTIME VEOL #endif +#include + void prep_terminal () { int tty = fileno (stdin); @@ -466,6 +474,9 @@ void prep_terminal () return; /* added by MdG */ } /* added by MdG */ + setlocale(LC_ALL, ""); + setlocale(LC_NUMERIC, "C"); + /* Try to keep this function from being INTerrupted. We can do it on POSIX and systems with BSD-like signal handling. */ #if defined (HAVE_POSIX_SIGNALS) @@ -607,50 +618,20 @@ void deprep_terminal () } #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 (stream) - FILE *stream; +long key_avail (FILE * stream) { int tty = fileno (stream); - long chars_avail = pending; - int result; - - if(!terminal_prepped) prep_terminal(); - -#ifndef _WIN32 - result = ioctl (tty, FIONREAD, &chars_avail); -#else - { - 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; + fd_set selin; + static struct timespec now = { 0 , 0 }; + int res; + + setvbuf(stream, NULL, _IONBF, 0); + if(!terminal_prepped && stream == stdin) + prep_terminal(); + + FD_ZERO(&selin); + FD_SET(tty, &selin); + return select(1, &selin, NULL, NULL, &now); } /* Get a key from the buffer of characters to be read. @@ -660,38 +641,30 @@ long key_avail (stream) /* When compiling and running in the `Posix' environment, Ultrix does not restart system calls, so this needs to do it. */ -unsigned char getkey(stream) - FILE *stream; +Cell getkey(FILE * stream) { - int result; + Cell result; unsigned char c; - if(!terminal_prepped) prep_terminal(); - - while (pending < 0) - { - result = read (fileno (stream), &c, sizeof (char)); - - if (result == sizeof (char)) - return /* (c == 0x7F ? 0x08 :*/ c /*)*/; + setvbuf(stream, NULL, _IONBF, 0); + if(!terminal_prepped && stream == stdin) + prep_terminal(); - /* If zero characters are returned, then the file that we are - reading from is empty! Return EOF in that case. */ - if (result == 0) - return CTRL('D'); - - /* If the error that we received was SIGINT, then try again, - this is simply an interrupted system call to read (). - Otherwise, some error ocurred, also signifying EOF. */ - if (errno != EINTR) - return (EOF); - } + result = fread(&c, sizeof(c), 1, stream); + return result==0 ? (errno == EINTR ? 12 : EOF) : c; +} - result = (int) pending; - pending = -1L; +#ifdef STANDALONE +void emit_char(char x) +{ + putc(x, stdout); +} - return result; +void type_chars(char *addr, unsigned int l) +{ + fwrite(addr, l, 1, stdout); } +#endif #ifdef TEST @@ -734,257 +707,3 @@ int main() #endif #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; psignal) { - 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 */