ftp.nice.ch/pub/next/unix/communication/pcomm.NIHS.bs.tar.gz#/pcomm/Source/tty_att.c

This is tty_att.c in view mode; [Download] [Up]

/*
 * System V specific routines for manipulating the TTY
 */

#include <stdio.h>
#ifdef XENIX_3
#include <sys/types.h>
#include <sys/ioctl.h>
#endif /* XENIX_3 */
#include <termio.h>
#include <fcntl.h>
#include "dial_dir.h"
#include "modem.h"
#include "param.h"

static struct termio hold;

/*
 * Change the communication line settings to the new values.
 */

void
line_set()
{
	static int first = 1;
	extern int fd;
	struct termio tbuf;
	int baud;

	if (first) {
		ioctl(fd, TCGETA, &hold);
		first = 0;
	}

	/*
	 * The manual dial entry also serves to store the previous
	 * line settings.  How else would the manual dial entry
	 * know what line setting to use?
	 */
	if (dir->d_cur != 0) {
		dir->baud[0] = dir->baud[dir->d_cur];
		dir->parity[0] = dir->parity[dir->d_cur];
		dir->dbits[0] = dir->dbits[dir->d_cur];
		dir->sbits[0] = dir->sbits[dir->d_cur];
	}
					/* nothing to do! */
	if (fd == -1)
		return;
					/* get the current settings */
	ioctl(fd, TCGETA, &tbuf);
					/* set some beginning values */
	tbuf.c_cc[4] = 1;		/* VMIN */
	tbuf.c_cc[5] = 0;		/* VTIME */
	tbuf.c_oflag = 0;
	tbuf.c_iflag = 0;
	tbuf.c_cflag = (CREAD|HUPCL|CLOCAL);
	tbuf.c_lflag = 0;

	if (*param->flow == 'X')
		tbuf.c_iflag |= (IXON|IXOFF);
					/* strip high bit? */
	if (*param->strip == 'Y')
		tbuf.c_iflag |= ISTRIP;

					/* the baud rate */
	baud = modem->init_sp[modem->m_cur];
	if (baud == 0)
		baud = dir->baud[dir->d_cur];

	switch (baud) {
		case 300:
			tbuf.c_cflag |= B300;
			break;
		case 1200:
			tbuf.c_cflag |= B1200;
			break;
		case 2400:
			tbuf.c_cflag |= B2400;
			break;
		case 4800:
			tbuf.c_cflag |= B4800;
			break;
		case 9600:
			tbuf.c_cflag |= B9600;
			break;
		case 19200:
#ifdef B19200
			tbuf.c_cflag |= B19200;
#else /* B19200 */
#ifdef EXTA
			tbuf.c_cflag |= EXTA;
#endif /* EXTA */
#endif /* B19200 */
			break;
	}
					/* the parity */
	switch (dir->parity[dir->d_cur]) {
		case 'N':
			break;
		case 'O':
			tbuf.c_cflag |= (PARENB|PARODD);
			break;
		case 'E':
			tbuf.c_cflag |= PARENB;
			break;
	}
					/* the data bits */
	if (dir->dbits[dir->d_cur] == 8)
		tbuf.c_cflag |= CS8;
	else
		tbuf.c_cflag |= CS7;
					/* the stop bits */
	if (dir->sbits[dir->d_cur] == 2)
		tbuf.c_cflag |= CSTOPB;

					/* now set 'em! */
	ioctl(fd, TCSETAF, &tbuf);
	return;
}

/*
 * Put things back the way they were.
 */

void
reset_line()
{
	extern int fd;

	ioctl(fd, TCSETAF, &hold);
	return;
}

/*
 * Put the stdin/stdout in terminal mode.  We've divided up the
 * responsibility for the line settings options between the serial port
 * and the stdin and stdout.
 */

void
term_mode()
{
	struct termio tbuf;

	ioctl(0, TCGETA, &tbuf);

	tbuf.c_cc[4] = 1;		/* VMIN */
	tbuf.c_cc[5] = 0;		/* VTIME */
	tbuf.c_iflag = 0;
	tbuf.c_oflag = 0;
	tbuf.c_lflag = 0;
					/* duplex */
	if (dir->duplex[dir->d_cur] == 'H')
		tbuf.c_lflag = ECHO;

	ioctl(0, TCSETAF, &tbuf);
	return;
}

/*
 * Put the TTY driver in the mode suitable for xmodem transfers.
 */

void
xmodem_mode(fds)
int fds;
{
	struct termio tbuf;

	ioctl(fds, TCGETA, &tbuf);
	/*
	 * Turn off the XON/XOFF flow control, turn off echoing, and
	 * switch to 8 bit no parity.
	 */
	tbuf.c_cc[4] = 1;		/* VMIN */
	tbuf.c_cc[5] = 0;		/* VTIME */
	tbuf.c_iflag = 0;		/* no flow control or mapping */
	tbuf.c_oflag = 0;		/* no char mapping or delays */
	tbuf.c_lflag = 0;		/* no echo or signals */
	tbuf.c_cflag &= ~(PARENB|CSIZE);/* no parity */
	tbuf.c_cflag |= CS8;		/* 8 bit */

	ioctl(fds, TCSETAF, &tbuf);
	return;
}

/*
 * Put the TTY line in a mode suitable for the ASCII transfer.  Puts the
 * terminal in the raw, non-blocking mode.
 */

void
ascii_mode(up)
int up;
{
	extern int fd;
	struct termio tbuf;

	ioctl(fd, TCGETA, &tbuf);
	tbuf.c_oflag = 0;
					/* flow control & 8th bit stripping */
	if (up) {
		tbuf.c_iflag = (ISTRIP|IXON);

					/* if no CR's, use NL delays */
		if (!strcmp(param->cr_up, "STRIP"))
			tbuf.c_oflag = (OPOST|ONLRET);

					/* CR delay times */
		switch (param->cr_delay) {
			case 0:
				break;
			case 100:
				tbuf.c_oflag |= (OPOST|CR2);
				break;
			case 150:
				tbuf.c_oflag |= (OPOST|CR3);
				break;
		}
	}
					/* if down loading */
	else
		tbuf.c_iflag = (ISTRIP|IXOFF);

	ioctl(fd, TCSETAF, &tbuf);
	return;
}

/*
 * Flush the file descriptor
 */

int
tty_flush(fds, mode)
int fds, mode;
{
	return(ioctl(fds, TCFLSH, mode));
}

/*
 * Wait for the output to drain
 */

int
tty_drain(fds)
int fds;
{
	return(ioctl(fds, TCSBRK, 1));
}

/*
 * Send a modem break
 */

int
tty_break(fds)
int fds;
{
	return(ioctl(fds, TCSBRK, 0));
}

/*
 * Fix the file descriptor so that a read is satisfied immediately.  When
 * read() is called it returns the character in the queue, or an error if
 * no key was pressed.
 */

int
tty_noblock(fds, on)
int fds, on;
{
	int current;

	current = fcntl(fds, F_GETFL, 0);
	if (on)
		return(fcntl(fds, F_SETFL, current | O_NDELAY));
	else
		return(fcntl(fds, F_SETFL, current & ~O_NDELAY));
}

/*
 * Get the current baud rate of the terminal
 */

int
my_speed()
{
	static int speed[15] = {0, 50, 75, 110, 134, 150, 200, 300, 600,
	 1200, 1800, 2400, 4800, 9600, 19200};
	struct termio tbuf;

	ioctl(0, TCGETA, &tbuf);
	return(speed[tbuf.c_cflag & CBAUD]);
}

/*
 * Restart any XON/XOFF flow control that may have stopped the tty 
 */

void
tty_restart()
{
	extern int fd;

	if (fd != -1 && *param->flow == 'X') 
		ioctl(fd, TCXONC, 1);
	return;
}

These are the contents of the former NiCE NeXT User Group NeXTSTEP/OpenStep software archive, currently hosted by Netfuture.ch.