diff options
author | Norbert Preining <norbert@preining.info> | 2019-09-02 13:46:59 +0900 |
---|---|---|
committer | Norbert Preining <norbert@preining.info> | 2019-09-02 13:46:59 +0900 |
commit | e0c6872cf40896c7be36b11dcc744620f10adf1d (patch) | |
tree | 60335e10d2f4354b0674ec22d7b53f0f8abee672 /dviware/dvgtk/unixio.c |
Initial commit
Diffstat (limited to 'dviware/dvgtk/unixio.c')
-rw-r--r-- | dviware/dvgtk/unixio.c | 357 |
1 files changed, 357 insertions, 0 deletions
diff --git a/dviware/dvgtk/unixio.c b/dviware/dvgtk/unixio.c new file mode 100644 index 0000000000..3c54a8a8f9 --- /dev/null +++ b/dviware/dvgtk/unixio.c @@ -0,0 +1,357 @@ +/* unixio.c - Unix terminal and signal handling + $Id: unixio.c,v 0.2 1997/03/28 03:17:33 tjchol01 Exp $ + Authors: Andrew Trevorrow, Ian Dall, Geoffrey Tobin, Tomasz J. Cholewo + */ + +#include "dvgt.h" +#include "unixio.h" +#include "screenio.h" /* for MesgString, MesgLine */ + +/* Set DV_FD (ioctl file descriptor) to 0 or 1 ? */ +#define DV_FD STDIN_FILENO + +sig_flags_t sig_flags; +cmode_flags_t cmode_flags; + +/* Alex Dickinson + Procedures for setting and resetting UNIX tty characteristics. + Interesting functions are: + save_init_tty; + restore_init_tty; + save_temp_tty; + restore_temp_tty; + echoon; + echooff; + singlecharon; + singlecharoff; + buffercount; + suspend; + A side effect of calling save_temp_tty is to set up signal handling + to reset the terminal characteristics appropriately for the various + interrupt signals. + */ + +/***************************************************************** +* terminal handling +*/ + +#if defined(HAVE_TERMIO_H) +#include <fcntl.h> +#include <termio.h> +#define TERMIO +#ifdef NCC +#define MAXCC NCC +#else +#define MAXCC 256 +#endif +#define DV_GTTY TCGETA +#define DV_STTY TCSETAW +typedef struct termio dv_tty; +unsigned char saved_cc[NCC]; +#else +#include <sgtty.h> +#define DV_GTTY TIOCGETP +#define DV_STTY TIOCSETN +typedef struct sgttyb dv_tty; +#endif /* TERMIOS || TERMIO */ + +#include <signal.h> +#include <errno.h> + +static dv_tty init_tty_state; /* store initial terminal characteristics */ +static dv_tty temp_tty_state; /* current terminal characteristics */ + +/* locally defined and used functions and data */ + +static void setsignals (); +static void reportio PARAMS ((int iostat)); +static int iostatus; /* return status of ioctl system function */ + +static void +reportio (int iostat) +{ + if (iostat < 0) + { /* an ioctl error */ + char *str = ""; + String cstr; + switch (errno) + { + /* generic errors */ +#ifdef EBADF + case EBADF: + str = "Not a valid, open, file descriptor!"; + break; +#endif +#ifdef EINTR + case EINTR: + str = "Signal caught."; + break; +#endif +#ifdef ENOTTY + case ENOTTY: + str = "No device driver, or doesn't accept control functions!"; + break; +#endif + /* specialised errors */ +#ifdef EFAULT + case EFAULT: + str = "Illegal data transfer address!"; + break; +#endif +#ifdef EINVAL + case EINVAL: + str = "Driver ignorant of this request or arg!"; + break; +#endif +#ifdef EIO + case EIO: + str = "Physical I/O error!"; + break; +#endif +#ifdef ENOLINK + case ENOLINK: + str = "Remote machine link no longer active!"; + break; +#endif +#ifdef ENXIO + case ENXIO: + str = "Subdevice cannot perform requested service!"; + break; +#endif + /* gt - should be ample space in cstr. */ + default: + sprintf (cstr, "Unknown error %d !", errno); + str = cstr; + break; + } + MesgString ("ioctl: "); + MesgString (str); + MesgLine (); + } +} /* reportio */ + +void +save_init_tty () +{ + /* Save the original tty characteristics and set up the signalling. */ + save_temp_tty (); + init_tty_state = temp_tty_state; +} /* save_init_tty */ + +void +restore_init_tty () +{ + /* Restore the original tty characteristics. */ + temp_tty_state = init_tty_state; + restore_temp_tty (); +} /* restore_init_tty */ + +void +save_temp_tty () +{ + /* Save the current tty characteristics and set up the signalling. */ + iostatus = ioctl (DV_FD, DV_GTTY, &temp_tty_state); + reportio (iostatus); + setsignals (); +} /* save_temp_tty */ + +void +restore_temp_tty () +{ + /* Restore the recent tty characteristics. */ + iostatus = ioctl (DV_FD, DV_STTY, &temp_tty_state); + reportio (iostatus); +} /* restore_temp_tty */ + +void +singlecharon () +{ + /* Set driver to read characters as they are typed without waiting for a + terminator. Echo remains unchanged. */ + dv_tty s; + + if (cmode_flags.cbreak != 1) + { + reportio (ioctl (DV_FD, DV_GTTY, &s)); +#ifndef TERMIO + s.sg_flags |= CBREAK; +#else /* TERMIO */ + saved_cc[VEOL] = s.c_cc[VEOL]; + saved_cc[VEOF] = s.c_cc[VEOF]; + s.c_lflag &= ~ICANON; /* Disable erase/kill processing */ + s.c_cc[VMIN] = 1; /* Input should wait for at least 1 char */ + s.c_cc[VTIME] = 0; /* no matter how long that takes. */ +#endif /* TERMIO */ + reportio (ioctl (DV_FD, DV_STTY, &s)); +#ifdef FLUSH_STDIN + fflush (stdin); +#endif /* FLUSH_STDIN */ + + cmode_flags.cbreak = 1; + } +} /* singlecharon */ + +void +singlecharoff () +{ + /* Turn off single character read mode. */ + dv_tty s; + + if (cmode_flags.cbreak != 0) + { + iostatus = ioctl (DV_FD, DV_GTTY, &s); + reportio (iostatus); +#ifndef TERMIO + s.sg_flags &= ~CBREAK; +#else /* TERMIO */ + s.c_lflag |= ICANON; /* Enable erase/kill processing */ + s.c_cc[VEOL] = saved_cc[VEOL]; + s.c_cc[VEOF] = saved_cc[VEOF]; +#endif /* TERMIO */ + iostatus = ioctl (DV_FD, DV_STTY, &s); + reportio (iostatus); + + cmode_flags.cbreak = 0; + } +} /* singlecharoff */ + +void +echoon () +{ + /* Turn character echoing on. */ + dv_tty s; + + reportio (ioctl (DV_FD, DV_GTTY, &s)); +#ifndef TERMIO + s.sg_flags |= ECHO; +#else /* TERMIO */ + s.c_lflag |= ECHO; +#endif /* TERMIO */ + reportio (ioctl (DV_FD, DV_STTY, &s)); + cmode_flags.echo = 1; +} /* echoon */ + +void +echooff () +{ + /* Turn character echoing off. */ + dv_tty s; + + iostatus = ioctl (DV_FD, DV_GTTY, &s); + reportio (iostatus); +#ifndef TERMIO + s.sg_flags &= ~ECHO; +#else /* TERMIO */ + s.c_lflag &= ~ECHO; +#endif /* TERMIO */ + iostatus = ioctl (DV_FD, DV_STTY, &s); + reportio (iostatus); + cmode_flags.echo = 0; +} /* echooff */ + +void +rawouton () +{ + dv_tty s; + + iostatus = ioctl (DV_FD, DV_GTTY, &s); + reportio (iostatus); +#ifdef TERMIO + s.c_oflag &= ~OPOST; /* Disables tab interpretation etc. */ +#endif /* TERMIO */ + iostatus = ioctl (DV_FD, DV_STTY, &s); + reportio (iostatus); + + cmode_flags.raw = 1; +} /* rawouton */ + +void +rawoutoff () +{ + dv_tty s; + + iostatus = ioctl (DV_FD, DV_GTTY, &s); + reportio (iostatus); +#ifdef TERMIO /* TERMIO */ + s.c_oflag |= OPOST; +#endif /* TERMIO */ + iostatus = ioctl (DV_FD, DV_STTY, &s); + reportio (iostatus); + + cmode_flags.raw = 0; +} /* rawoutoff */ + +int +buffercount () +{ + /* Return true if there are any characters currently in the input buffer. */ +#ifndef TERMIO + long count; + iostatus = ioctl (DV_FD, FIONREAD, &count); + reportio (iostatus); + return (count > 0); +#else /* TERMIO */ + int c, flags, ret; + + /* Save the current fcntl flags and make reads return without waiting */ + flags = fcntl (0, F_GETFL, 0); + fcntl (0, F_SETFL, flags | O_NDELAY); /* This might be SysV specific */ + if ((c = getchar ()) != EOF) + { + ungetc (c, stdin); + ret = 1; + } + else + { + ret = 0; + } + fcntl (0, F_SETFL, flags); /* This might be SysV specific */ + return ret; +#endif /* TERMIO */ +} /* buffercount */ + +RETSIGTYPE +handleint (int sig) +{ + /* Catch signals from tty. + If sig is an interrupt, set the intr flag, + Otherwise it was a suspend, so set the tstop flag. */ + fflush (stdin); + if (sig == SIGINT) + { + sig_flags.intr = 1; + } + else + { + sig_flags.tstop = 1; + } +#ifdef TERMIO /* TERMIO */ + setsignals (); /* Because SysV forgets its handlers */ +#endif /* TERMIO */ +} /* handleint */ + +static void +setsignals () +{ + /* Signal initialization. */ + signal (SIGINT, handleint); +#ifndef TERMIO + signal (SIGTSTP, handleint); +#endif /* TERMIO */ +} /* setsignals */ + +void +suspend () +{ + /* Suspend the process */ +#ifndef TERMIO + signal (SIGTSTP, SIG_DFL); + kill (0, SIGTSTP); + /* resumed again, goody! */ + setsignals (); +#else + /* don't know what to do */ +#endif /* TERMIO */ +} /* suspend */ + +#undef IN_UNIXIO_C |