BBN-Vax-TCP/src/telnet/ttyctl.c

Compare this file to the similar file:
Show the results in this format:

/*
 * TTY control package
 *
 * This set of routines establishes one or more "modes", each of which
 * is a tty structure. Routines are provided for allocating a new mode,
 * changing between modes, and setting and clearing the tty flags in a mode.
 * If the mode specified is the current mode, the tty structure is regarded as
 * being kept in the kernel itself; gtty, stty, and modtty are used on it.
 * Otherwise it is one of the allocated user-space structures.
 *
 * This package attempts to handle both old and new tty drivers, by
 * keeping both sets of modes around.
 *
 * A mode of NULL is regarded as a reference to the current mode.
 *
 * Note: the user must declare the external int "termfd" and set it to a file
 * descriptor opened to the terminal to be controlled. The statement
 *     int termfd 2;
 * external to any function, is sufficient.
 *
 * Eric Shienbrood(bbn) 16 Jul 81 - Added struct tchars to the TTYMODE
 *  structure.
 */

#include <stdio.h>
#include "ttyctl.h"

/* -------------------------- A L L O C M O D E --------------------- */
/*
 * AllocMode() returns a pointer to a new tty structure.
 * It is initialized to the current tty modes.
 */
TTYMODE *
AllocMode()
{
    TTYMODE *p;
    extern int termfd;
    extern char *malloc();

    p = (TTYMODE *)malloc(sizeof(*p));
    if (p == NULL)
	return(p);  /* Let the caller decide what to do */
    check("AllocMode", gtty(termfd, &(p->tm_sgtty)));
    check("AllocMode", ioctl(termfd, TIOCGETC, &(p->tm_tchars)));
    check("AllocMode", ioctl(termfd, TIOCLGET, &(p->tm_local)));
    return(p);
}

/* -------------------------- F R E E M O D E ----------------------- */

FreeMode(mode)
    TTYMODE *mode;
{
    extern TTYMODE *curmode;
    extern free();

    if (mode == NULL || mode == curmode)
	fprintf(stderr, "FreeMode: Attempt to free current mode block ignored\r\n");
    else
	free(mode);
}

/* -------------------------- C H G M O D E ------------------------- */
/*
 * ChgMode(mode) changes to a different mode. The current tty structure
 * is saved away, and the new mode structure is applied. The old mode
 * is returned.
 */
TTYMODE *
ChgMode(mode)
    TTYMODE *mode;
{
    TTYMODE *oldmode;
    extern int termfd;
    extern TTYMODE *curmode;

    if (mode == NULL || mode == curmode) /* Change to current mode -- no-op */
	return(curmode);

    check("ChgMode", gtty(termfd, &(curmode->tm_sgtty)));/* Save current mode */
    check("ChgMode", ioctl(termfd, TIOCGETC, &(curmode->tm_tchars)));/* Save current mode */
    check("ChgMode", ioctl(termfd, TIOCLGET, &(curmode->tm_local)));
    oldmode = curmode;
    curmode = mode;
    check("ChgMode", stty(termfd, &(curmode->tm_sgtty)));
    check("ChgMode", ioctl(termfd, TIOCSETC, &(curmode->tm_tchars)));
    check("ChgMode", ioctl(termfd, TIOCLSET, &(curmode->tm_local)));
    return(oldmode);
}

/* -------------------------- G E T M O D E ------------------------- */
/*
 * GetMode(mode) returns the sgttyb portion of the mode block for "mode".
 * It implements the current mode special casing.
 */
struct sgttyb *
GetMode(mode)
    TTYMODE *mode;
{
    extern TTYMODE *curmode;
    extern int termfd;

    if (mode == NULL)
	mode = curmode;
    if (mode == curmode)
	check("GetMode", gtty(termfd, &(curmode->tm_sgtty)));
    return(&(mode->tm_sgtty));
}

/* -------------------------- S E T M O D E ------------------------- */
/*
 * SetMode(mode) sets the sgttyb portion of the mode block for "mode".
 * It implements the current mode special casing.
 */
SetMode(mode, ttyblock)
    TTYMODE *mode;
    struct sgttyb *ttyblock;
{
    register struct sgttyb *p;
    register struct sgttyb *q;
    extern int termfd;
    extern TTYMODE *curmode;

    if (mode == 0)
	mode = curmode;
    p = &(mode->tm_sgtty);
    q = ttyblock;
    p->sg_ospeed = q->sg_ospeed;
    p->sg_ispeed = q->sg_ispeed;
    p->sg_erase = q->sg_erase;
    p->sg_kill = q->sg_kill;
    p->sg_flags = q->sg_flags;
    if (mode == curmode)
	check("SetMode", stty(termfd, &(curmode->tm_sgtty)));
}

/* -------------------------- S E T F L A G S ----------------------- */
/*
 * SetFlags(mode, mask, flags) sets the tty flags of "mode" to "flags".
 * However, only those flag bits accessible through "mask" are set or
 * cleared; the rest of the flags are untouched. The old values of those
 * flags are returned.
 */
SetFlags(mode, mask, flags)
    TTYMODE *mode;
    int mask;
    int flags;
{
    int oldflags;
    int newflags;
    struct sgttyb *sgmodes;
    extern int termfd;
    extern TTYMODE *curmode;
    extern struct sgttyb *GetMode();

    flags &= mask;

    sgmodes = GetMode(mode);

    oldflags = newflags = sgmodes->sg_flags;
    newflags &= ~mask;
    newflags |= flags;
    sgmodes->sg_flags = newflags;

    if (sgmodes == &curmode->tm_sgtty)
	check("SetFlags", stty(termfd, &curmode->tm_sgtty));

    return(oldflags);
}

/* -------------------------- G E T F L A G S ----------------------- */
/*
 * GetFlags(mode) returns the tty flags of "mode".
 */
GetFlags(mode)
    TTYMODE *mode;
{
    return(GetMode(mode)->sg_flags);
}

/* -------------------------- O R I G M O D E ----------------------- */
/*
 * OrigMode() returns a pointer to the original mode block -- that is,
 * the one containing the modes in effect before the first ChgMode was done.
 */
TTYMODE *
OrigMode()
{
    extern TTYMODE origmode;

    return(&origmode);
}

/* -------------------------- C U R M O D E ------------------------- */
/*
 * CurMode() returns a pointer to the current mode block. Useful
 * mainly for freeing the block when a mode is no longer needed.
 */
TTYMODE *
CurMode()
{
    extern TTYMODE *curmode;

    return(curmode);
}

/* -------------------------- C H E C K ----------------------------- */
/*
 * check(name, val) is an internal routine to check system calls. If val is
 * -1, it prints an error message and aborts.
 */
check(name, val)
    char *name;
    int val;
{
    extern int termfd;
    extern char *errmsg();

    if (val != -1)
	return;
    fprintf(stderr, "%s: Error. %s. termfd = %d\r\n", name, errmsg(0), termfd);
    ecmderr(0, "Exiting.");
}

/* -------------------------- G L O B A L S ------------------------- */
/*
 * curmode points to the tty structure to save the current tty modes in
 * when switching to a new mode.
 *
 * origmode is the original set of modes.
 */
TTYMODE origmode;
TTYMODE *curmode = &origmode;