|
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 - 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++; } }