|
|
DataMuseum.dkPresents historical artifacts from the history of: DKUUG/EUUG Conference tapes |
This is an automatic "excavation" of a thematic subset of
See our Wiki for more about DKUUG/EUUG Conference tapes Excavated with: AutoArchaeologist - Free & Open Source Software. |
top - metrics - downloadIndex: T t
Length: 9049 (0x2359)
Types: TextFile
Names: »te_chario.c«
└─⟦a0efdde77⟧ Bits:30001252 EUUGD11 Tape, 1987 Spring Conference Helsinki
└─⟦this⟧ »EUUGD11/euug-87hel/sec1/teco/te_chario.c«
/* TECO for Ultrix Copyright 1986 Matt Fichtenbaum */
/* This program and its components belong to GenRad Inc, Concord MA 01742 */
/* They may be copied if this copyright notice is included */
/* te_chario.c character I/O routines 10/9/86 */
#include <errno.h>
#include "te_defs.h"
#include <fcntl.h>
#ifndef DEBUG
#include <signal.h>
extern int int_handler();
extern int stp_handler();
extern int hup_handler();
#define SIGINTMASK 2
#endif
int lf_sw; /* nonzero: make up a LF following an entered CR */
int ttyflags; /* flags for (stdin) file descriptor */
struct tchars tc_orig, tc_new, tc_noint; /* original, new, disabled intrpt tty special chars */
struct ltchars lc_orig, lc_new; /* original and new local special chars */
struct sgttyb tty_orig, tty_new; /* original and new tty flags */
int tty_local; /* original tty local mode flags */
int lnoflsh = LNOFLSH; /* bit to force "no flush on interrupt */
#ifndef DEBUG
struct sigvec intsigstruc = { int_handler, 0, 0 } ; /* info structure for ^C interrupt */
struct sigvec stpsigstruc = { stp_handler, 0, 0 } ; /* info structure for "stop" signal */
struct sigvec hupsigstruc = { hup_handler, 0, 0 } ; /* info structure for "hangup" signal */
struct sigvec nosigstr = { SIG_DFL, 0, 0 }; /* default structure for signal */
#endif
int inp_noterm; /* nonzero if standard input is not a terminal */
int out_noterm; /* nonzero if standard output is not a terminal */
\f
/* set tty (stdin) mode. TECO mode is CBREAK, no ECHO, sep CR & LF */
/* operation; normal mode is none of the above. TTY_OFF and TTY_ON do this */
/* absolutely; TTY_SUSP and TTY_RESUME use saved signal status. */
setup_tty(arg)
int arg;
{
extern int errno;
int ioerr;
struct sgttyb tmpbuf;
/* initial processing: set tty mode */
if (arg == TTY_ON)
{
ioerr = ioctl(fileno(stdin), TIOCGETP, &tty_orig); /* get std input characteristics */
inp_noterm = (ioerr && (errno == ENOTTY)); /* nonzero if input not a terminal */
ioerr = ioctl(fileno(stdout), TIOCGETP, &tmpbuf); /* get std output characteristics */
out_noterm = (ioerr && (errno == ENOTTY)); /* nonzero if output not a terminal */
ioctl(fileno(stdout), TIOCLGET, &tty_local); /* get current "local mode flags" word */
ttybuf = tty_new = tty_orig; /* make a copy of tty control structure */
tty_new.sg_flags = (tty_new.sg_flags & ~ECHO & ~CRMOD) | CBREAK; /* turn on teco modes */
ioctl(fileno(stdin), TIOCGETC, &tc_orig); /* read current tchars */
tc_new = tc_orig; /* make local copy */
tc_new.t_quitc = tc_new.t_brkc = -1; /* disable "quit" and "delimiter" chars */
tc_noint = tc_new;
tc_noint.t_intrc = -1; /* disable the interrupt char in this one */
ioctl(fileno(stdin), TIOCGLTC, &lc_orig); /* read current ltchars */
lc_new = lc_orig; /* make local copy */
lc_new.t_rprntc = lc_new.t_werasc = lc_new.t_lnextc = -1; /* disable "reprint," "word erase," "lit next" */
}
if ((arg == TTY_ON) || (arg == TTY_RESUME))
{
ioctl(fileno(stdin), TIOCSETP, &tty_new); /* set flags for teco */
ioctl(fileno(stdin), TIOCSETC, &tc_new); /* update both */
ioctl(fileno(stdin), TIOCSLTC, &lc_new);
ioctl(fileno(stdout), TIOCLBIS, &lnoflsh); /* disable "interrupt => flush buffers" */
#ifndef DEBUG
sigvec(SIGTSTP, &stpsigstruc, 0); /* set up to trap "stop" signal */
sigvec(SIGINT, &intsigstruc, 0); /* and "interrupt" signal */
sigvec(SIGHUP, &hupsigstruc, 0); /* and "hangup" signal */
#endif
}
else
{
ioctl(fileno(stdin), TIOCSETP, &tty_orig); /* set flags back to original */
ioctl(fileno(stdin), TIOCSETC, &tc_orig); /* put both back to orig states */
ioctl(fileno(stdin), TIOCSLTC, &lc_orig);
ioctl(fileno(stdout), TIOCLSET, &tty_local); /* restore local mode flags to original states */
#ifndef DEBUG
sigvec(SIGTSTP, &nosigstr, 0); /* restore default signal handling */
sigvec(SIGINT, &nosigstr, 0);
sigvec(SIGHUP, &nosigstr, 0);
#endif
}
}
\f
/* routines to handle keyboard input */
/* routine to get a character without waiting, used by ^T when ET & 64 is set */
/* if lf_sw is nonzero, return the LF; else use the FNDELAY fcntl to inquire of the input */
int gettty_nowait()
{
int c;
if (lf_sw)
{
lf_sw = 0;
return(LF); /* LF to be sent: return it */
}
fcntl(fileno(stdin), F_SETFL, ttyflags | FNDELAY); /* set to "no delay" mode */
while (!(c = getchar())); /* read character, or -1, skip nulls */
fcntl(fileno(stdin), F_SETFL, ttyflags); /* reset to normal mode */
if (c == CR) ++lf_sw; /* CR: set switch to make up a LF */
return(c);
}
/* normal routine to get a character */
int in_read = 0; /* flag for "read busy" (used by interrupt handler) */
char gettty()
{
int c;
if (lf_sw)
{
lf_sw = 0;
return(LF); /* if switch set, make up a line feed */
}
++in_read; /* set "read busy" switch */
while(!(c = getchar())); /* get character; skip nulls */
in_read = 0; /* clear switch */
if (c == CR) ++lf_sw; /* CR: set switch to make up a LF */
if (c == EOF) ERROR(E_EFI); /* end-of-file from standard input */
return( (char) c & 0177); /* and return the 7-bit char */
}
\f
#ifndef DEBUG
/* routine to handle interrupt signal */
int_handler()
{
if (exitflag <= 0) /* if executing commands */
{
if (et_val & ET_CTRLC) et_val &= ~ET_CTRLC; /* if "trap ^C" set, clear it and ignore */
else exitflag = -2; /* else set flag to stop execution */
}
if (in_read) /* if interrupt happened in "getchar" pass a ^C to input */
{
in_read = 0; /* clear "read" switch */
ioctl(fileno(stdin), TIOCSETC, &tc_noint); /* disable interrupt char */
qio_char(CTL (C)); /* send a ^C to input stream */
ioctl(fileno(stdin), TIOCSETC, &tc_new); /* reenable interrupt char */
}
}
#endif
\f
/* routine to disable (1), enable (0) ^C interrupt, used to block interrupts during display update */
int old_mask; /* storage for previous signal mask */
#define INT_MASK 2
block_inter(func)
int func;
{
#ifndef DEBUG
if (func) old_mask = sigblock(INT_MASK); /* if arg nonzero, block interrupt */
else sigsetmask(old_mask); /* otherwise restore old signal mask */
#endif
}
#ifndef DEBUG
/* routine to handle "stop" signal (^Y) */
stp_handler()
{
window(WIN_SUSP); /* restore screen */
setup_tty(TTY_SUSP); /* put tty back to normal */
sigvec(SIGTSTP, &nosigstr, 0); /* put default action back */
sigsetmask(0); /* unblock "suspend" signal */
kill(0, SIGTSTP); /* suspend this process */
/* ----- process gets suspended here ----- */
sigvec(SIGTSTP, &stpsigstruc, 0); /* restore local handling of "stop" signal */
setup_tty(TTY_RESUME); /* restore tty */
buff_mod = 0; /* set whole screen modified */
if (win_data[7]) /* redraw window */
{
window(WIN_RESUME); /* re-enable window */
window(WIN_REDRAW); /* force complete redraw */
window(WIN_REFR); /* and refresh */
}
qio_char('\0'); /* wake up the input
if (exitflag) retype_cmdstr('*'); /* if not executing, prompt again and echo command string so far */
}
#endif
/* simulate a character's having been typed on the keyboard */
qio_char(c)
char c;
{
ioctl(fileno(stdin), TIOCSTI, &c); /* send char to input stream */
}
\f
/* routine to handle "hangup" signal */
#ifndef DEBUG
hup_handler()
{
if (!exitflag) exitflag = -3; /* if executing, set flag to terminate */
else
{
panic(); /* dump buffer and close output files */
exit(1);
}
}
#endif
/* type a crlf */
crlf()
{
type_char(CR);
type_char(LF);
}
/* reset ^O status */
int lflusho = LFLUSHO;
int lfo;
reset_ctlo()
{
ioctl(fileno(stdin), TIOCLGET, &lfo); /* read flags */
if (lfo & LFLUSHO) /* if ^O was set */
{
ioctl(fileno(stdin), TIOCLBIC, &lflusho); /* reset ^O */
crlf(); /* type a crlf */
}
}
\f
/* routine to type one character */
type_char(c)
char c;
{
if ((char_count >= WN_width) && (c != CR) && !(spec_chars[c] & A_L)) /* spacing char beyond end of line */
{
if (et_val & ET_TRUNC) return; /* truncate output to line width */
else crlf(); /* otherwise do automatic new line (note recursive call to type_char) */
}
if ((c & 0140) == 0) /* control char? */
{
switch (c & 0177)
{
case CR:
putchar(c);
char_count = 0;
break;
case LF:
putchar(c);
/* scroll_dly(); /* filler chars in case VT-100 scrolls */
break;
case ESC:
if ((et_val & ET_IMAGE) && !exitflag) putchar(c);
else
{
putchar('$');
char_count++;
}
break;
case TAB:
if ((et_val & ET_IMAGE) && !exitflag) putchar(c);
else for (type_char(' '); (char_count & tabmask) != 0; type_char(' '));
break;
default:
if ((et_val & ET_IMAGE) && !exitflag) putchar(c);
else
{
putchar('^');
putchar(c + 'A'-1);
char_count += 2;
}
break;
}
}
else
{
putchar(c);
char_count++;
}
}