Blame src/lib/libcmd/stty.c

Packit Service a8c26c
/***********************************************************************
Packit Service a8c26c
*                                                                      *
Packit Service a8c26c
*               This software is part of the ast package               *
Packit Service a8c26c
*          Copyright (c) 1992-2012 AT&T Intellectual Property          *
Packit Service a8c26c
*                      and is licensed under the                       *
Packit Service a8c26c
*                 Eclipse Public License, Version 1.0                  *
Packit Service a8c26c
*                    by AT&T Intellectual Property                     *
Packit Service a8c26c
*                                                                      *
Packit Service a8c26c
*                A copy of the License is available at                 *
Packit Service a8c26c
*          http://www.eclipse.org/org/documents/epl-v10.html           *
Packit Service a8c26c
*         (with md5 checksum b35adb5213ca9657e911e9befb180842)         *
Packit Service a8c26c
*                                                                      *
Packit Service a8c26c
*              Information and Software Systems Research               *
Packit Service a8c26c
*                            AT&T Research                             *
Packit Service a8c26c
*                           Florham Park NJ                            *
Packit Service a8c26c
*                                                                      *
Packit Service a8c26c
*                 Glenn Fowler <gsf@research.att.com>                  *
Packit Service a8c26c
*                  David Korn <dgk@research.att.com>                   *
Packit Service a8c26c
*                                                                      *
Packit Service a8c26c
***********************************************************************/
Packit Service a8c26c
#pragma prototyped
Packit Service a8c26c
/*
Packit Service a8c26c
 * stty.c
Packit Service a8c26c
 * Written by David Korn
Packit Service a8c26c
 * Tue Apr  4 10:46:00 EDT 1995
Packit Service a8c26c
 */
Packit Service a8c26c
Packit Service a8c26c
static const char usage[] =
Packit Service a8c26c
"[-?@(#)$Id: stty (AT&T Research) 2010-04-01 $\n]"
Packit Service a8c26c
USAGE_LICENSE
Packit Service a8c26c
"[+NAME?stty - set or get terminal modes]"
Packit Service a8c26c
"[+DESCRIPTION?\bstty\b sets certain terminal I/O modes for the device "
Packit Service a8c26c
    "that is the current standard input; without arguments, it writes the "
Packit Service a8c26c
    "settings of certain modes to standard output.]"
Packit Service a8c26c
"[a:all?Writes to standard output all of the mode settings.]"
Packit Service a8c26c
"[f|F:fd|file?Use \afd\a as the terminal fd.]#[fd:=0]"
Packit Service a8c26c
"[g:save?Writes the current settings to standard output in a form that "
Packit Service a8c26c
    "can be used as an argument to another \bstty\b command. The \brows\b "
Packit Service a8c26c
    "and \bcolumns\b values are not included.]"
Packit Service a8c26c
"[t:terminal-group?Print the terminal group id of the device, -1 if "
Packit Service a8c26c
    "unknown.]"
Packit Service a8c26c
"\n"
Packit Service a8c26c
"\n[mode ...]\n"
Packit Service a8c26c
"\n"
Packit Service a8c26c
"[+EXTENDED DESCRIPTION?Modes are specified either as a single name or "
Packit Service a8c26c
    "as a name followed by a value. As indicated below, many of the mode "
Packit Service a8c26c
    "names can be preceded by a \b-\b to negate its meaning. Modes are "
Packit Service a8c26c
    "listed by group corresponding to field in the \btermios\b structure "
Packit Service a8c26c
    "defined in \b<termios.h>\b. Modes in the last group are implemented "
Packit Service a8c26c
    "using options in the previous groups. Note that many combinations of "
Packit Service a8c26c
    "modes make no sense, but no sanity checking is performed. The modes are "
Packit Service a8c26c
    "selected from the following:]"
Packit Service a8c26c
    "{\fabc\f}"
Packit Service a8c26c
"[+EXIT STATUS?]"
Packit Service a8c26c
    "{"
Packit Service a8c26c
        "[+0?All modes reported or set successfully.]"
Packit Service a8c26c
        "[+>0?Standard input not a terminaol or one or more modes "
Packit Service a8c26c
            "failed.]"
Packit Service a8c26c
    "}"
Packit Service a8c26c
"[+SEE ALSO?\btegetattr\b(2), \btcsetattr\b(2), \bioctl\b(2)]"
Packit Service a8c26c
;
Packit Service a8c26c
Packit Service a8c26c
#include	<cmd.h>
Packit Service a8c26c
#include	<ccode.h>
Packit Service a8c26c
#include	<ctype.h>
Packit Service a8c26c
#include	<ast_tty.h>
Packit Service a8c26c
#if _sys_ioctl
Packit Service a8c26c
#include	<sys/ioctl.h>
Packit Service a8c26c
#endif
Packit Service a8c26c
Packit Service a8c26c
#define C(x)	ERROR_catalog(x)
Packit Service a8c26c
Packit Service a8c26c
#ifndef _POSIX_VDISABLE
Packit Service a8c26c
#   define _POSIX_VDISABLE 0
Packit Service a8c26c
#endif
Packit Service a8c26c
Packit Service a8c26c
#ifndef NCCS
Packit Service a8c26c
#   ifdef NCC
Packit Service a8c26c
#	define NCCS	NCC
Packit Service a8c26c
#   else
Packit Service a8c26c
#	define NCCS	elementsof(((struct termio*)0)->c_cc)
Packit Service a8c26c
#   endif
Packit Service a8c26c
#endif
Packit Service a8c26c
Packit Service a8c26c
/* command options */
Packit Service a8c26c
#define A_FLAG	1
Packit Service a8c26c
#define G_FLAG	2
Packit Service a8c26c
#define T_FLAG	4
Packit Service a8c26c
Packit Service a8c26c
/* termios fields */
Packit Service a8c26c
#define C_FLAG	1
Packit Service a8c26c
#define C_LINE	2
Packit Service a8c26c
#define C_SPEED	3
Packit Service a8c26c
#define I_FLAG	4
Packit Service a8c26c
#define O_FLAG	5
Packit Service a8c26c
#define L_FLAG	6
Packit Service a8c26c
#define T_CHAR	7
Packit Service a8c26c
#define W_SIZE	8
Packit Service a8c26c
Packit Service a8c26c
#define BIT	1
Packit Service a8c26c
#define BITS	2
Packit Service a8c26c
#define NUM	3
Packit Service a8c26c
#define CHAR	4
Packit Service a8c26c
#define SPEED	5
Packit Service a8c26c
#define SIZE	6
Packit Service a8c26c
#define MIXED	7
Packit Service a8c26c
#define SANE	8
Packit Service a8c26c
#define COOKED	9
Packit Service a8c26c
#define CASE	10
Packit Service a8c26c
#define TABS	11
Packit Service a8c26c
#define WIND	12
Packit Service a8c26c
Packit Service a8c26c
#undef	SS			/* who co-opted this namespace?	*/
Packit Service a8c26c
Packit Service a8c26c
#define IG	0x0001		/* ignore display		*/
Packit Service a8c26c
#define NL	0x0002		/* entry ends line of display	*/
Packit Service a8c26c
#define SS	0x0004		/* set in sane mode		*/
Packit Service a8c26c
#define US	0x0010		/* unset in sane mode		*/
Packit Service a8c26c
Packit Service a8c26c
typedef struct tty_s
Packit Service a8c26c
{
Packit Service a8c26c
	const char	name[8];
Packit Service a8c26c
	unsigned char	type;
Packit Service a8c26c
	unsigned char	field;
Packit Service a8c26c
	short		flags;
Packit Service a8c26c
	unsigned long	mask;
Packit Service a8c26c
	unsigned long	val;
Packit Service a8c26c
	const char	description[76];
Packit Service a8c26c
} Tty_t; 
Packit Service a8c26c
Packit Service a8c26c
static const Tty_t Ttable[] =
Packit Service a8c26c
{
Packit Service a8c26c
#ifdef CBAUD
Packit Service a8c26c
{ "ispeed",	NUM,	C_SPEED,0,	CBAUD, 0, C("\an\a is the input baud rate") },
Packit Service a8c26c
{ "ospeed",	NUM,	C_SPEED,0,	CBAUD, 0, C("\an\a is the output baud rate") },
Packit Service a8c26c
{ "speed",	NUM,	C_SPEED,IG,	CBAUD },
Packit Service a8c26c
#endif
Packit Service a8c26c
{ "0",		SPEED,	C_FLAG,	0,	B0 },
Packit Service a8c26c
{ "50",		SPEED,	C_FLAG,	0,	B50 },
Packit Service a8c26c
{ "75",		SPEED,	C_FLAG,	0,	B75 },
Packit Service a8c26c
{ "110",	SPEED,	C_FLAG,	0,	B110 },
Packit Service a8c26c
{ "134",	SPEED,	C_FLAG,	0,	B134 },
Packit Service a8c26c
{ "150",	SPEED,	C_FLAG,	0,	B150 },
Packit Service a8c26c
{ "200",	SPEED,	C_FLAG,	0,	B200 },
Packit Service a8c26c
{ "300",	SPEED,	C_FLAG,	0,	B300 },
Packit Service a8c26c
{ "600",	SPEED,	C_FLAG,	0,	B600 },
Packit Service a8c26c
{ "1200",	SPEED,	C_FLAG,	0,	B1200 },
Packit Service a8c26c
{ "1800",	SPEED,	C_FLAG,	0,	B1800 },
Packit Service a8c26c
{ "2400",	SPEED,	C_FLAG,	0,	B2400 },
Packit Service a8c26c
{ "4800",	SPEED,	C_FLAG,	0,	B4800 },
Packit Service a8c26c
{ "9600",	SPEED,	C_FLAG,	0,	B9600 },
Packit Service a8c26c
{ "19200",	SPEED,	C_FLAG,	0,	B19200 },
Packit Service a8c26c
{ "38400",	SPEED,	C_FLAG,	0,	B38400 },
Packit Service a8c26c
Packit Service a8c26c
#ifdef TIOCSWINSZ
Packit Service a8c26c
{ "rows",	WIND,	W_SIZE,	IG,	0, 24, C("\an\a is the number of lines for display") },
Packit Service a8c26c
{ "cols",	WIND,	W_SIZE,	IG,	1, 80, C("\an\a is the number of columns for display") },
Packit Service a8c26c
{ "columns",	WIND,	W_SIZE,	IG,	1, 80, C("Same as \bcols\b") },
Packit Service a8c26c
#endif
Packit Service a8c26c
{ "intr",	CHAR,	T_CHAR,	SS,	VINTR, 'C', C("Send an interrupt signal") },
Packit Service a8c26c
{ "quit",	CHAR,	T_CHAR,	SS,	VQUIT, '|', C("Send a quit signal") },
Packit Service a8c26c
{ "erase",	CHAR,	T_CHAR,	SS,	VERASE, 'H', C("Erase the last character entered") },
Packit Service a8c26c
{ "kill",	CHAR,	T_CHAR,	NL|SS,	VKILL, 'U', C("Erase the current line") },
Packit Service a8c26c
{ "eof",	CHAR,	T_CHAR,	SS,	VEOF, 'D', C("Send an end of file") },
Packit Service a8c26c
#ifdef VEOL2
Packit Service a8c26c
{ "eol2",	CHAR,	T_CHAR,	US,	VEOL2, _POSIX_VDISABLE, C("Alternate character to end the line") },
Packit Service a8c26c
#endif /* VEOL2 */
Packit Service a8c26c
#ifdef VSWTCH
Packit Service a8c26c
{ "swtch",	CHAR,	T_CHAR,	US,	VSWTCH, _POSIX_VDISABLE, C("Switch to a different shell layer") },
Packit Service a8c26c
#endif /* VSWTCH */
Packit Service a8c26c
{ "eol",	CHAR,	T_CHAR,	NL|US,	VEOL, _POSIX_VDISABLE, C("End the line") },
Packit Service a8c26c
#ifdef VSTART
Packit Service a8c26c
{ "start",	CHAR,	T_CHAR,	SS,	VSTART, 'Q', C("Restart the output after stopping it") },
Packit Service a8c26c
#endif /* VSTART */
Packit Service a8c26c
#ifdef VSTOP
Packit Service a8c26c
{ "stop",	CHAR,	T_CHAR,	SS,	VSTOP, 'S', C("Stop the output") },
Packit Service a8c26c
#endif /* VSTOP */
Packit Service a8c26c
#ifdef VDSUSP
Packit Service a8c26c
{ "dsusp",	CHAR,	T_CHAR,	SS,	VDSUSP, 'Y', C("Send a terminal stop signal after flushing the input") },
Packit Service a8c26c
#endif /* VDSUSP */
Packit Service a8c26c
#ifdef VSUSP
Packit Service a8c26c
{ "susp",	CHAR,	T_CHAR,	NL|SS,	VSUSP, 'Z', C("Send a terminal stop signal") },
Packit Service a8c26c
#endif /* VSUSP */
Packit Service a8c26c
#ifdef VREPRINT
Packit Service a8c26c
{ "rprnt",	CHAR,	T_CHAR,	SS,	VREPRINT, 'R', C("Redraw the current line") },
Packit Service a8c26c
#endif /* VREPRINT */
Packit Service a8c26c
#ifdef VDISCARD
Packit Service a8c26c
{ "flush",	CHAR,	T_CHAR,	SS,	VDISCARD, 'O', C("Discard output") },
Packit Service a8c26c
#endif /* VDISCARD */
Packit Service a8c26c
#ifdef VWERASE
Packit Service a8c26c
{ "werase",	CHAR,	T_CHAR,	SS,	VWERASE, 'W', C("Erase the last word entered") },
Packit Service a8c26c
#endif /* VWERASE */
Packit Service a8c26c
#ifdef VLNEXT
Packit Service a8c26c
{ "lnext",	CHAR,	T_CHAR,	NL|SS,	VLNEXT, 'V', C("Enter the next input character literally") },
Packit Service a8c26c
#endif /* VLNEXT */
Packit Service a8c26c
	
Packit Service a8c26c
#if _mem_c_line_termios
Packit Service a8c26c
{ "line",	NUM,	C_LINE,	0,	0, 0, C("Line discipline number") },
Packit Service a8c26c
#endif
Packit Service a8c26c
{ "min",	NUM,	T_CHAR,	0,	VMIN, 0, C("Mininmum number of characters to read in raw mode") },
Packit Service a8c26c
{ "time",	NUM,	T_CHAR,	0,	VTIME, 0, C("Number of .1 second intervals with raw mode") },
Packit Service a8c26c
Packit Service a8c26c
{ "parenb",	BIT,	C_FLAG,	0,	PARENB,	PARENB, C("Enable (disable) parity generation and detection") },
Packit Service a8c26c
{ "parodd",	BIT,	C_FLAG,	0,	PARODD, PARODD, C("Use odd (even) parity") },
Packit Service a8c26c
#ifdef PAREXT
Packit Service a8c26c
{ "parext",	BIT,	C_FLAG,	0,	PAREXT, PAREXT },
Packit Service a8c26c
#endif /* PAREXT */
Packit Service a8c26c
#ifdef CREAD
Packit Service a8c26c
{ "cread",	BIT,	C_FLAG,	SS,	CREAD, CREAD, C("Enable (disable) input") },
Packit Service a8c26c
#endif /* CREAD */
Packit Service a8c26c
{ "cs5",	SIZE,	C_FLAG,	0,	CSIZE,	CS5 , C("Char size 5") },
Packit Service a8c26c
{ "cs6",	SIZE,	C_FLAG,	0,	CSIZE,	CS6 , C("Char size 6") },
Packit Service a8c26c
{ "cs7",	SIZE,	C_FLAG,	0,	CSIZE,	CS7 , C("Char size 7") },
Packit Service a8c26c
{ "cs8",	SIZE,	C_FLAG,	0,	CSIZE,	CS8 , C("Char size 8") },
Packit Service a8c26c
{ "hupcl",	BIT,	C_FLAG,	0,	HUPCL, HUPCL, C("Hangup (do not hangup) connection on last close") },
Packit Service a8c26c
{ "hup",	BIT,	C_FLAG,	IG,	HUPCL, HUPCL, C("Same as \bhupcl\b") },
Packit Service a8c26c
{ "cstopb",	BIT,	C_FLAG,	0,	CSTOPB, CSTOPB, C("Use two (one) stop bits") },
Packit Service a8c26c
#ifdef CRTSCTS
Packit Service a8c26c
{ "crtscts",	BIT,	C_FLAG,	0,	CRTSCTS, CRTSCTS, C("Enable (disable) RTS/CTS handshaking") },
Packit Service a8c26c
#endif /* CRTSCTS */
Packit Service a8c26c
{ "clocal",	BIT,	C_FLAG,	NL,	CLOCAL, CLOCAL, C("Disable (enable) modem control signals") },
Packit Service a8c26c
	
Packit Service a8c26c
{ "ignbrk",	BIT,	I_FLAG,	US,	IGNBRK, IGNBRK, C("Ignore (do not ignore) break characters") },
Packit Service a8c26c
{ "brkint",	BIT,	I_FLAG,	SS,	BRKINT, BRKINT, C("Generate (do not generate) INTR signal on break") },
Packit Service a8c26c
{ "ignpar",	BIT,	I_FLAG,	0,	IGNPAR, IGNPAR, C("Ignore (do not ignore) characters with parity errors") },
Packit Service a8c26c
{ "parmrk",	BIT,	I_FLAG,	0,	PARMRK, PARMRK, C("Mark (do not mark) parity errors") },
Packit Service a8c26c
{ "inpck",	BIT,	I_FLAG,	0,	INPCK, INPCK, C("Enable (disable) input parity checking") },
Packit Service a8c26c
{ "istrip",	BIT,	I_FLAG,	0,	ISTRIP, ISTRIP, C("Clear (do not clear) high bit of input characters") },
Packit Service a8c26c
{ "inlcr",	BIT,	I_FLAG,	US,	INLCR, INLCR, C("Translate (do not translate) carriage return to newline") },
Packit Service a8c26c
{ "igncr",	BIT,	I_FLAG,	US,	IGNCR, IGNCR, C("Ignore (do not ignore) carriage return") },
Packit Service a8c26c
#ifdef IUCLC
Packit Service a8c26c
{ "iuclc",	BIT,	I_FLAG,	US,	IUCLC, IUCLC, C("Map (do not map) upper-case to lower case") },
Packit Service a8c26c
#endif /* IUCLC */
Packit Service a8c26c
{ "ixon",	BIT,	I_FLAG,	0,	IXON, IXON, C("Enable (disable) XON/XOFF flow control. \bstop\b character stops output") },
Packit Service a8c26c
#ifdef IXANY
Packit Service a8c26c
{ "ixany",	BIT,	I_FLAG,	US,	IXANY, IXANY, C("Any character (only start character) can restart output.") },
Packit Service a8c26c
{ "decctlq",	BIT,	I_FLAG,	IG,	IXANY, 0, C("Same as \b-ixany\b") },
Packit Service a8c26c
#endif /* IXANY */
Packit Service a8c26c
{ "ixoff",	BIT,	I_FLAG,	US,	IXOFF, IXOFF, C("Disable (enable) XON/XOFF flow control") },
Packit Service a8c26c
#ifdef IMAXBEL
Packit Service a8c26c
{ "imaxbel",	BIT,	I_FLAG,	SS,	IMAXBEL, IMAXBEL, C("Beep (do not beep) if a character arrives with full input buffer") },
Packit Service a8c26c
#endif /* IMAXBEL */
Packit Service a8c26c
{ "icrnl",	BIT,	I_FLAG,	NL|SS,	ICRNL, ICRNL, C("Translate (do not translate) carriage return to newline") },
Packit Service a8c26c
	
Packit Service a8c26c
{ "isig",	BIT,	L_FLAG,	SS,	ISIG, ISIG, C("Enable (disable) \bintr\b, \bquit\b, and \bsusp\b special characters") },
Packit Service a8c26c
{ "icanon",	BIT,	L_FLAG,	SS,	ICANON, ICANON, C("Enable (disable) \berase\b, \bkill\b, \bwerase\b, and \brprnt\b special characters") },
Packit Service a8c26c
{ "icannon",	BIT,	L_FLAG,	SS,	ICANON, ICANON },
Packit Service a8c26c
#ifdef IEXTEN
Packit Service a8c26c
{ "iexten",	BIT,	L_FLAG,	SS,	IEXTEN, IEXTEN, C("Enable (disable) non-POSIX special characters") },
Packit Service a8c26c
#endif /* IEXTEN */
Packit Service a8c26c
{ "echo",	BIT,	L_FLAG,	SS,	ECHO|ECHONL, ECHO|ECHONL, C("Echo (do not echo) input characters") },
Packit Service a8c26c
{ "echoe",	BIT,	L_FLAG,	SS,	ECHOE, ECHOE, C("Echo (do not echo) erase characters as backspace-space-backspace") },
Packit Service a8c26c
{ "echok",	BIT,	L_FLAG,	SS,	ECHOK, ECHOK, C("Echo (do not echo) a newline after a kill character") },
Packit Service a8c26c
#ifdef ECHOKE
Packit Service a8c26c
{ "echoke",	BIT,	L_FLAG,	SS,	ECHOKE, ECHOKE, C("Echo (do not echo) a newline after a kill character") },
Packit Service a8c26c
#endif
Packit Service a8c26c
{ "lfkc",	BIT,	L_FLAG,	IG,	ECHOK, ECHOK, C("Same as \bechok\b (\b-echok\b); obsolete") },
Packit Service a8c26c
{ "echonl",	BIT,	L_FLAG,	SS,	ECHONL, ECHONL,"Echo (do not echo) newline even if not echoing other character" },
Packit Service a8c26c
#ifdef ECHOCTL
Packit Service a8c26c
{ "echoctl",	BIT,	L_FLAG,	SS,	ECHOCTL, ECHOCTL, C("Echo (do not echo) control characters as \b^\b\ac\a") },
Packit Service a8c26c
#else
Packit Service a8c26c
#define ECHOCTL		0
Packit Service a8c26c
#endif /* ECHOCTL */
Packit Service a8c26c
#ifdef ECHOPRT
Packit Service a8c26c
{ "echoprt",	BIT,	L_FLAG,	US,	ECHOPRT, ECHOPRT, C("Echo (do not echo) erased characters backward, between '\\' and '/'") },
Packit Service a8c26c
#else
Packit Service a8c26c
#define ECHOPRT		0
Packit Service a8c26c
#endif /* ECHOPRT */
Packit Service a8c26c
#ifdef XCASE
Packit Service a8c26c
{ "xcase",	BIT,	L_FLAG,	US,	XCASE, XCASE, C("Enable (disable) \bicanon\b uppercase as lowercase with '\\' prefix") },
Packit Service a8c26c
#endif /* XCASE */
Packit Service a8c26c
#ifdef DEFECHO
Packit Service a8c26c
{ "defecho",	BIT,	L_FLAG,	0,	DEFECHO, DEFECHO },
Packit Service a8c26c
#endif /* DEFECHO */
Packit Service a8c26c
#ifdef FLUSHO
Packit Service a8c26c
{ "flusho",	BIT,	L_FLAG,	0,	FLUSHO, FLUSHO, C("Discard (do not discard) written data. Cleared by subsequent input") },
Packit Service a8c26c
#endif /* FLUSHO */
Packit Service a8c26c
#ifdef PENDIN
Packit Service a8c26c
{ "pendin",	BIT,	L_FLAG,	0,	PENDIN, PENDIN, C("Redisplay pending input at next read and then automatically clear \bpendin\b") },
Packit Service a8c26c
#endif /* PENDIN */
Packit Service a8c26c
{ "noflsh",	BIT,	L_FLAG,	US,	NOFLSH, NOFLSH, C("Disable (enable) flushing after \bintr\b and \bquit\b special characters") },
Packit Service a8c26c
#ifdef TOSTOP
Packit Service a8c26c
{ "tostop",	BIT,	L_FLAG,	NL|US,	TOSTOP, TOSTOP, C("Stop (do not stop) background jobs that try to write to the terminal") },
Packit Service a8c26c
#endif /* TOSTOP */
Packit Service a8c26c
#ifdef OLCUC
Packit Service a8c26c
{ "olcuc",	BIT,	O_FLAG,	US,	OLCUC, OLCUC, C("Translate (do not translate) lowercase characters to uppercase") },
Packit Service a8c26c
#endif /* OLCUC */
Packit Service a8c26c
#ifdef ONLCR
Packit Service a8c26c
{ "onlcr",	BIT,	O_FLAG,	SS,	ONLCR, ONLCR, C("Translate (do not translate) newline to carriage return-newline") },
Packit Service a8c26c
#endif /* ONLCR */
Packit Service a8c26c
#ifdef ONLRET
Packit Service a8c26c
{ "onlret",	BIT,	O_FLAG,	US,	ONLRET, ONLRET, C("Newline performs (does not perform) a carriage return") },
Packit Service a8c26c
#endif /* ONLRET */
Packit Service a8c26c
#ifdef OCRNL
Packit Service a8c26c
{ "ocrnl",	BIT,	O_FLAG,	US,	OCRNL, OCRNL, C("Translate (do not translate) carriage return to newline") },
Packit Service a8c26c
#endif /* OCRNL */
Packit Service a8c26c
#ifdef ONOCR
Packit Service a8c26c
{ "onocr",	BIT,	O_FLAG,	US,	ONOCR, ONOCR, C("Do not (do) print carriage returns in the first column") },
Packit Service a8c26c
#endif /* ONOCR */
Packit Service a8c26c
#ifdef OFILL
Packit Service a8c26c
{ "ofill",	BIT,	O_FLAG,	US,	OFILL, OFILL, C("Use fill characters (use timing) for delays") },
Packit Service a8c26c
#endif /* OFILL */
Packit Service a8c26c
#ifdef OFDEL
Packit Service a8c26c
{ "ofdel",	BIT,	O_FLAG,	US,	OFDEL, OFDEL, C("Use DEL (NUL) as fill characters for delays") },
Packit Service a8c26c
#endif /* OFDEL */
Packit Service a8c26c
{ "opost",	BIT,	O_FLAG,	SS,	OPOST, OPOST, C(" Postprocess (do not postprocess) output") },
Packit Service a8c26c
#ifdef CRDLY
Packit Service a8c26c
{ "cr0",	BITS,	O_FLAG,	IG|SS,	CRDLY, CR0  },
Packit Service a8c26c
{ "cr1",	BITS,	O_FLAG,	US,	CRDLY, CR1  },
Packit Service a8c26c
{ "cr2",	BITS,	O_FLAG,	US,	CRDLY, CR2  },
Packit Service a8c26c
{ "cr3",	BITS,	O_FLAG,	US,	CRDLY, CR3  },
Packit Service a8c26c
#endif
Packit Service a8c26c
#ifdef NLDLY
Packit Service a8c26c
{ "nl0",	BITS,	O_FLAG,	IG|US,	NLDLY, NL0  },
Packit Service a8c26c
{ "nl1",	BITS,	O_FLAG,	US,	NLDLY, NL1  },
Packit Service a8c26c
#endif
Packit Service a8c26c
#ifdef TABDLY
Packit Service a8c26c
{ "tabs",	TABS,	O_FLAG,	IG,	TABDLY, TAB3, C("Preserve (expand to spaces) tabs") },
Packit Service a8c26c
#ifdef TAB0
Packit Service a8c26c
{ "tab0",	BITS,	O_FLAG,	IG|SS,	TABDLY, TAB0  },
Packit Service a8c26c
#endif
Packit Service a8c26c
#ifdef TAB1
Packit Service a8c26c
{ "tab1",	BITS,	O_FLAG,	US,	TABDLY, TAB1  },
Packit Service a8c26c
#endif
Packit Service a8c26c
#ifdef TAB2
Packit Service a8c26c
{ "tab2",	BITS,	O_FLAG,	US,	TABDLY, TAB2  },
Packit Service a8c26c
#endif
Packit Service a8c26c
{ "tab3",	BITS,	O_FLAG,	US,	TABDLY, TAB3  },
Packit Service a8c26c
#endif
Packit Service a8c26c
#ifdef BSDLY
Packit Service a8c26c
{ "bs0",	BITS,	O_FLAG,	IG|SS,	BSDLY, BS0 },
Packit Service a8c26c
{ "bs1",	BITS,	O_FLAG,	US,	BSDLY, BS1  },
Packit Service a8c26c
#endif
Packit Service a8c26c
#ifdef VTDLY
Packit Service a8c26c
{ "vt0",	BITS,	O_FLAG,	IG|SS,	VTDLY, VT0  },
Packit Service a8c26c
{ "vt1",	BITS,	O_FLAG,	US,	VTDLY, VT1  },
Packit Service a8c26c
#endif
Packit Service a8c26c
#ifdef FFDLY
Packit Service a8c26c
{ "ff0",	BITS,	O_FLAG,	IG|SS,	FFDLY, FF0 },
Packit Service a8c26c
{ "ff1",	BITS,	O_FLAG,	US,	FFDLY, FF1 },
Packit Service a8c26c
#endif
Packit Service a8c26c
{ "",		MIXED,	O_FLAG,	NL|IG },
Packit Service a8c26c
	
Packit Service a8c26c
{ "evenp",	MIXED,	C_FLAG,	IG,	PARENB, 0, C("Same as \bparenb -parodd cs7\b") },
Packit Service a8c26c
{ "oddp",	MIXED,	C_FLAG,	IG,	PARODD, 0, C("Same as \bparenb parodd cs7\b") },
Packit Service a8c26c
{ "parity",	MIXED,	C_FLAG,	IG,	0, 0, C("Same as parenb \b-parodd cs7\b") },
Packit Service a8c26c
{ "ek",		MIXED,	C_FLAG,	IG,	0, 0, C("Reset the \berase\b and \bkill\b special characters to their default values") },
Packit Service a8c26c
{ "sane",	SANE,	C_FLAG,	IG,	0, 0, C("Reset all modes to some reasonable values") },
Packit Service a8c26c
{ "cooked",	COOKED,	C_FLAG,	IG,	0, 0, C("Disable raw input and output") },
Packit Service a8c26c
{ "raw",	COOKED,	C_FLAG,	IG,	0, 0, C("Enable raw input and output") },
Packit Service a8c26c
{ "lcase",	CASE,	C_FLAG,	IG,	0 , 0, C("Set \bxcase\b, \biuclc\b, and \bolcuc\b") },
Packit Service a8c26c
{ "LCASE",	CASE,	C_FLAG,	IG,	0 , 0, C("Same as \blcase\b") }
Packit Service a8c26c
};
Packit Service a8c26c
Packit Service a8c26c
#if CC_NATIVE == CC_ASCII
Packit Service a8c26c
#define cntl(x)		(((x)=='?')?0177:((x)&037))
Packit Service a8c26c
#else
Packit Service a8c26c
#define cntl(x)		(((x)=='?')?ccmapc(0177,CC_ASCII,CC_NATIVE):ccmapc(ccmapc(x,CC_NATIVE,CC_ASCII)&037,CC_ASCII,CC_NATIVE))
Packit Service a8c26c
#endif
Packit Service a8c26c
Packit Service a8c26c
static void sane(register struct termios *sp)
Packit Service a8c26c
{
Packit Service a8c26c
	register const Tty_t*	tp;
Packit Service a8c26c
Packit Service a8c26c
	for (tp = Ttable; tp < &Ttable[elementsof(Ttable)]; tp++)
Packit Service a8c26c
		if (tp->flags & (SS|US))
Packit Service a8c26c
			switch (tp->type)
Packit Service a8c26c
			{
Packit Service a8c26c
			case BIT:
Packit Service a8c26c
			case BITS:
Packit Service a8c26c
				switch (tp->field)
Packit Service a8c26c
				{
Packit Service a8c26c
				case C_FLAG:
Packit Service a8c26c
					if (tp->flags & SS)
Packit Service a8c26c
						sp->c_cflag |= tp->mask;
Packit Service a8c26c
					else
Packit Service a8c26c
						sp->c_cflag &= ~tp->mask;
Packit Service a8c26c
					break;
Packit Service a8c26c
				case I_FLAG:
Packit Service a8c26c
					if (tp->flags & SS)
Packit Service a8c26c
						sp->c_iflag |= tp->mask;
Packit Service a8c26c
					else
Packit Service a8c26c
						sp->c_iflag &= ~tp->mask;
Packit Service a8c26c
					break;
Packit Service a8c26c
				case O_FLAG:
Packit Service a8c26c
					if (tp->flags & SS)
Packit Service a8c26c
						sp->c_oflag |= tp->mask;
Packit Service a8c26c
					else
Packit Service a8c26c
						sp->c_oflag &= ~tp->mask;
Packit Service a8c26c
					break;
Packit Service a8c26c
				case L_FLAG:
Packit Service a8c26c
					if (tp->flags & SS)
Packit Service a8c26c
						sp->c_lflag |= tp->mask;
Packit Service a8c26c
					else
Packit Service a8c26c
						sp->c_lflag &= ~tp->mask;
Packit Service a8c26c
					break;
Packit Service a8c26c
				}
Packit Service a8c26c
				break;
Packit Service a8c26c
			case CHAR:
Packit Service a8c26c
				sp->c_cc[tp->mask] = cntl(tp->val);
Packit Service a8c26c
				break;
Packit Service a8c26c
			}
Packit Service a8c26c
}
Packit Service a8c26c
Packit Service a8c26c
static int gin(char *arg,struct termios *sp)
Packit Service a8c26c
{
Packit Service a8c26c
	register int i;
Packit Service a8c26c
	if(*arg++ != ':')
Packit Service a8c26c
		return(0);
Packit Service a8c26c
	sp->c_iflag = strtol(arg,&arg,16);
Packit Service a8c26c
	if(*arg++ != ':')
Packit Service a8c26c
		return(0);
Packit Service a8c26c
	sp->c_oflag = strtol(arg,&arg,16);
Packit Service a8c26c
	if(*arg++ != ':')
Packit Service a8c26c
		return(0);
Packit Service a8c26c
	sp->c_cflag = strtol(arg,&arg,16);
Packit Service a8c26c
	if(*arg++ != ':')
Packit Service a8c26c
		return(0);
Packit Service a8c26c
	sp->c_lflag = strtol(arg,&arg,16);
Packit Service a8c26c
	if(*arg++ != ':')
Packit Service a8c26c
		return(0);
Packit Service a8c26c
	for(i=0;i< NCCS; i++)
Packit Service a8c26c
	{
Packit Service a8c26c
		sp->c_cc[i] = strtol(arg,&arg,16);
Packit Service a8c26c
		if(*arg++ != ':')
Packit Service a8c26c
			return(0);
Packit Service a8c26c
	}
Packit Service a8c26c
#if _mem_c_line_termios
Packit Service a8c26c
	sp->c_line =
Packit Service a8c26c
#endif
Packit Service a8c26c
		strtol(arg,&arg,16);
Packit Service a8c26c
	if(*arg++ != ':')
Packit Service a8c26c
		return(0);
Packit Service a8c26c
	i = strtol(arg,&arg,16);
Packit Service a8c26c
	if(*arg++ != ':')
Packit Service a8c26c
		return(0);
Packit Service a8c26c
	cfsetispeed(sp, i);
Packit Service a8c26c
	i = strtol(arg,&arg,16);
Packit Service a8c26c
	if(*arg++ != ':')
Packit Service a8c26c
		return(0);
Packit Service a8c26c
	cfsetospeed(sp, i);
Packit Service a8c26c
	if(*arg)
Packit Service a8c26c
		return(0);
Packit Service a8c26c
	return(1);
Packit Service a8c26c
}
Packit Service a8c26c
Packit Service a8c26c
static void gout(struct termios *sp)
Packit Service a8c26c
{
Packit Service a8c26c
	register int i;
Packit Service a8c26c
	sfprintf(sfstdout,":%x",sp->c_iflag);
Packit Service a8c26c
	sfprintf(sfstdout,":%x",sp->c_oflag);
Packit Service a8c26c
	sfprintf(sfstdout,":%x",sp->c_cflag);
Packit Service a8c26c
	sfprintf(sfstdout,":%x",sp->c_lflag);
Packit Service a8c26c
	for(i=0;i< NCCS; i++)
Packit Service a8c26c
		sfprintf(sfstdout,":%x",sp->c_cc[i]);
Packit Service a8c26c
#if _mem_c_line_termios
Packit Service a8c26c
	sfprintf(sfstdout,":%x", sp->c_line);
Packit Service a8c26c
#else
Packit Service a8c26c
	sfprintf(sfstdout,":%x", 0);
Packit Service a8c26c
#endif
Packit Service a8c26c
	sfprintf(sfstdout,":%x",cfgetispeed(sp));
Packit Service a8c26c
	sfprintf(sfstdout,":%x",cfgetospeed(sp));
Packit Service a8c26c
	sfprintf(sfstdout,":\n");
Packit Service a8c26c
}
Packit Service a8c26c
Packit Service a8c26c
static void output(struct termios *sp, int flags)
Packit Service a8c26c
{
Packit Service a8c26c
	const Tty_t *tp;
Packit Service a8c26c
	struct termios tty;
Packit Service a8c26c
	register int delim = ' ';
Packit Service a8c26c
	register int i,off,off2;
Packit Service a8c26c
	char schar[2];
Packit Service a8c26c
	unsigned int ispeed = cfgetispeed(sp);
Packit Service a8c26c
	unsigned int ospeed = cfgetospeed(sp);
Packit Service a8c26c
	if(flags&G_FLAG)
Packit Service a8c26c
	{
Packit Service a8c26c
		gout(sp);
Packit Service a8c26c
		return;
Packit Service a8c26c
	}
Packit Service a8c26c
	tty = *sp;
Packit Service a8c26c
	sane(&tty);
Packit Service a8c26c
	for(i=0; i < elementsof(Ttable); i++)
Packit Service a8c26c
	{
Packit Service a8c26c
		tp= &Ttable[i];
Packit Service a8c26c
		if(tp->flags&IG)
Packit Service a8c26c
		{
Packit Service a8c26c
			if(tp->flags&NL)
Packit Service a8c26c
				sfputc(sfstdout,'\n');
Packit Service a8c26c
			continue;
Packit Service a8c26c
		}
Packit Service a8c26c
		switch(tp->type)
Packit Service a8c26c
		{
Packit Service a8c26c
		    case BIT:
Packit Service a8c26c
		    case BITS:
Packit Service a8c26c
			off = off2 = 1;
Packit Service a8c26c
			switch(tp->field)
Packit Service a8c26c
			{
Packit Service a8c26c
			    case C_FLAG:
Packit Service a8c26c
				if(sp->c_cflag&tp->mask)
Packit Service a8c26c
					off = 0;
Packit Service a8c26c
				if(tty.c_cflag&tp->mask)
Packit Service a8c26c
					off2 = 0;
Packit Service a8c26c
				break;
Packit Service a8c26c
			    case I_FLAG:
Packit Service a8c26c
				if(sp->c_iflag&tp->mask)
Packit Service a8c26c
					off = 0;
Packit Service a8c26c
				if(tty.c_iflag&tp->mask)
Packit Service a8c26c
					off2 = 0;
Packit Service a8c26c
				break;
Packit Service a8c26c
			    case O_FLAG:
Packit Service a8c26c
				if((sp->c_oflag&tp->mask)==tp->val)
Packit Service a8c26c
					off = 0;
Packit Service a8c26c
				if(tty.c_oflag&tp->mask)
Packit Service a8c26c
					off2 = 0;
Packit Service a8c26c
				break;
Packit Service a8c26c
			    case L_FLAG:
Packit Service a8c26c
				if(sp->c_lflag&tp->mask)
Packit Service a8c26c
					off = 0;
Packit Service a8c26c
				if(tty.c_lflag&tp->mask)
Packit Service a8c26c
					off2 = 0;
Packit Service a8c26c
			}
Packit Service a8c26c
			if(tp->flags&NL)
Packit Service a8c26c
				delim = '\n';
Packit Service a8c26c
			if(!flags && off==off2)
Packit Service a8c26c
				continue;
Packit Service a8c26c
			if(!off)
Packit Service a8c26c
				sfprintf(sfstdout,"%s%c",tp->name,delim);
Packit Service a8c26c
			else if(tp->type==BIT)
Packit Service a8c26c
				sfprintf(sfstdout,"-%s%c",tp->name,delim);
Packit Service a8c26c
			delim = ' ';
Packit Service a8c26c
			break;
Packit Service a8c26c
Packit Service a8c26c
		    case CHAR:
Packit Service a8c26c
			off = sp->c_cc[tp->mask];
Packit Service a8c26c
			if(tp->flags&NL)
Packit Service a8c26c
				delim = '\n';
Packit Service a8c26c
			if(!flags && off==(unsigned char)tty.c_cc[tp->mask])
Packit Service a8c26c
				continue;
Packit Service a8c26c
			if(off==_POSIX_VDISABLE)
Packit Service a8c26c
				sfprintf(sfstdout,"%s = <undef>;%c",tp->name,delim);
Packit Service a8c26c
			else if(isprint(off&0xff))
Packit Service a8c26c
				sfprintf(sfstdout,"%s = %c;%c",tp->name,off,delim);
Packit Service a8c26c
			else
Packit Service a8c26c
#if CC_NATIVE == CC_ASCII
Packit Service a8c26c
			sfprintf(sfstdout,"%s = ^%c;%c",tp->name,off==0177?'?':(off^0100),delim);
Packit Service a8c26c
#else
Packit Service a8c26c
			{
Packit Service a8c26c
				off = ccmapc(off, CC_NATIVE, CC_ASCII);
Packit Service a8c26c
				sfprintf(sfstdout,"%s = ^%c;%c",tp->name,off==0177?'?':ccmapc(off^0100,CC_ASCII,CC_NATIVE),delim);
Packit Service a8c26c
			}
Packit Service a8c26c
#endif
Packit Service a8c26c
			delim = ' ';
Packit Service a8c26c
			break;
Packit Service a8c26c
		    case SIZE:
Packit Service a8c26c
			if((sp->c_cflag&CSIZE)!=tp->mask)
Packit Service a8c26c
				continue;
Packit Service a8c26c
			if(flags || (sp->c_cflag&CSIZE) != (tty.c_cflag&CSIZE))
Packit Service a8c26c
				sfprintf(sfstdout,"%s ",tp->name);
Packit Service a8c26c
			break;
Packit Service a8c26c
		    case SPEED:
Packit Service a8c26c
			if(tp->mask==ispeed)
Packit Service a8c26c
			{
Packit Service a8c26c
				if(ispeed!=ospeed)
Packit Service a8c26c
					schar[0]='i';
Packit Service a8c26c
				else
Packit Service a8c26c
					schar[0]=0;
Packit Service a8c26c
			}
Packit Service a8c26c
			else if(tp->mask==ospeed)
Packit Service a8c26c
				schar[0]='o';
Packit Service a8c26c
			else
Packit Service a8c26c
				continue;
Packit Service a8c26c
			schar[1] = 0;
Packit Service a8c26c
#ifdef TIOCSWINSZ
Packit Service a8c26c
			{
Packit Service a8c26c
				struct winsize win;
Packit Service a8c26c
				off = ioctl(0,TIOCGWINSZ,&win);
Packit Service a8c26c
				if(off>=0)
Packit Service a8c26c
					sfprintf(sfstdout,"%sspeed %s baud; rows %d; columns %d;\n",schar,tp->name,win.ws_row,win.ws_col);
Packit Service a8c26c
			}
Packit Service a8c26c
			if(off<0)
Packit Service a8c26c
#endif
Packit Service a8c26c
				sfprintf(sfstdout,"%sspeed %s baud;\n",schar,tp->name);
Packit Service a8c26c
		}
Packit Service a8c26c
	}
Packit Service a8c26c
	if(delim=='\n')
Packit Service a8c26c
		sfputc(sfstdout,'\n');
Packit Service a8c26c
}
Packit Service a8c26c
Packit Service a8c26c
static const Tty_t *lookup(const char *name)
Packit Service a8c26c
{
Packit Service a8c26c
	register int i;
Packit Service a8c26c
	for(i=0; i < elementsof(Ttable); i++)
Packit Service a8c26c
	{
Packit Service a8c26c
		if(strcmp(Ttable[i].name,name)==0)
Packit Service a8c26c
			return(&Ttable[i]);
Packit Service a8c26c
	}
Packit Service a8c26c
	return(0);
Packit Service a8c26c
Packit Service a8c26c
}
Packit Service a8c26c
Packit Service a8c26c
static const Tty_t *getspeed(unsigned long val)
Packit Service a8c26c
{
Packit Service a8c26c
	register int i;
Packit Service a8c26c
	for(i=0; i < elementsof(Ttable); i++)
Packit Service a8c26c
	{
Packit Service a8c26c
		if(Ttable[i].type==SPEED && Ttable[i].mask==val)
Packit Service a8c26c
			return(&Ttable[i]);
Packit Service a8c26c
	}
Packit Service a8c26c
	return(0);
Packit Service a8c26c
}
Packit Service a8c26c
Packit Service a8c26c
static int gettchar(register const char *cp)
Packit Service a8c26c
{
Packit Service a8c26c
	if(*cp==0)
Packit Service a8c26c
		return(-1);
Packit Service a8c26c
	if(cp[1]==0)
Packit Service a8c26c
		return((unsigned)cp[0]);
Packit Service a8c26c
	if(*cp=='^' && cp[1] && cp[2]==0)
Packit Service a8c26c
	{
Packit Service a8c26c
		switch(cp[1])
Packit Service a8c26c
		{
Packit Service a8c26c
		    case '-':
Packit Service a8c26c
			return(-1);
Packit Service a8c26c
		    default:
Packit Service a8c26c
			return(cntl(cp[1]));
Packit Service a8c26c
		}
Packit Service a8c26c
	}
Packit Service a8c26c
	if(streq(cp,"undef") || streq(cp,"<undef>"))
Packit Service a8c26c
		return(-1);
Packit Service a8c26c
	return(*((unsigned char*)cp));
Packit Service a8c26c
}
Packit Service a8c26c
Packit Service a8c26c
static void set(char *argv[], struct termios *sp)
Packit Service a8c26c
{
Packit Service a8c26c
	const Tty_t *tp;
Packit Service a8c26c
	register int c,off;
Packit Service a8c26c
	char *cp;
Packit Service a8c26c
	char *ep;
Packit Service a8c26c
	while(cp = *argv++)
Packit Service a8c26c
	{
Packit Service a8c26c
		off = 0;
Packit Service a8c26c
		if(*cp=='-')
Packit Service a8c26c
		{
Packit Service a8c26c
			cp++;
Packit Service a8c26c
			off=1;
Packit Service a8c26c
		}
Packit Service a8c26c
		if(!(tp=lookup(cp)) || (off && (tp->type!=BIT) && (tp->type!=TABS)))
Packit Service a8c26c
			error(ERROR_exit(1),"%s: unknown mode",cp);
Packit Service a8c26c
		switch(tp->type)
Packit Service a8c26c
		{
Packit Service a8c26c
		    case CHAR:
Packit Service a8c26c
			if(off)
Packit Service a8c26c
				error(ERROR_exit(1),"%s: unknown mode",cp);
Packit Service a8c26c
			if(!*argv)
Packit Service a8c26c
				error(ERROR_exit(1),"missing argument to %s",cp);
Packit Service a8c26c
			c = gettchar(*argv++);
Packit Service a8c26c
			if(c>=0)
Packit Service a8c26c
				sp->c_cc[tp->mask] = c;
Packit Service a8c26c
			else
Packit Service a8c26c
				sp->c_cc[tp->mask] = _POSIX_VDISABLE;
Packit Service a8c26c
			break;
Packit Service a8c26c
		    case BIT: case BITS:
Packit Service a8c26c
			switch(tp->field)
Packit Service a8c26c
			{
Packit Service a8c26c
			    case C_FLAG:
Packit Service a8c26c
				if(off)
Packit Service a8c26c
					sp->c_cflag &= ~tp->mask;
Packit Service a8c26c
				else
Packit Service a8c26c
					sp->c_cflag |= tp->mask;
Packit Service a8c26c
				break;
Packit Service a8c26c
			    case I_FLAG:
Packit Service a8c26c
				if(off)
Packit Service a8c26c
					sp->c_iflag &= ~tp->mask;
Packit Service a8c26c
				else
Packit Service a8c26c
					sp->c_iflag |= tp->mask;
Packit Service a8c26c
				break;
Packit Service a8c26c
			    case O_FLAG:
Packit Service a8c26c
				sp->c_oflag &= ~tp->mask;
Packit Service a8c26c
				sp->c_oflag |= tp->val;
Packit Service a8c26c
				break;
Packit Service a8c26c
			    case L_FLAG:
Packit Service a8c26c
				if(off)
Packit Service a8c26c
					sp->c_lflag &= ~tp->mask;
Packit Service a8c26c
				else
Packit Service a8c26c
					sp->c_lflag |= tp->mask;
Packit Service a8c26c
				break;
Packit Service a8c26c
			}
Packit Service a8c26c
			break;
Packit Service a8c26c
		    case TABS:
Packit Service a8c26c
			sp->c_oflag &= ~tp->mask;
Packit Service a8c26c
			if(off)
Packit Service a8c26c
				sp->c_oflag |= tp->val;
Packit Service a8c26c
			break;
Packit Service a8c26c
#ifdef TIOCSWINSZ
Packit Service a8c26c
		    case WIND:
Packit Service a8c26c
		    {
Packit Service a8c26c
			struct winsize win;
Packit Service a8c26c
			int n;
Packit Service a8c26c
			if(ioctl(0,TIOCGWINSZ,&win)<0)
Packit Service a8c26c
				error(ERROR_system(1),"cannot set %s",tp->name);
Packit Service a8c26c
			if(!(cp= *argv))
Packit Service a8c26c
			{
Packit Service a8c26c
				sfprintf(sfstdout,"%d\n",tp->mask?win.ws_col:win.ws_row);
Packit Service a8c26c
				break;
Packit Service a8c26c
			}
Packit Service a8c26c
			argv++;
Packit Service a8c26c
			n=strtol(cp,&cp,10);
Packit Service a8c26c
			if(*cp)
Packit Service a8c26c
				error(ERROR_system(1),"%d: invalid number of %s",argv[-1],tp->name);
Packit Service a8c26c
			if(tp->mask)
Packit Service a8c26c
				win.ws_col = n;
Packit Service a8c26c
			else
Packit Service a8c26c
				win.ws_row = n;
Packit Service a8c26c
			if(ioctl(0,TIOCSWINSZ,&win)<0)
Packit Service a8c26c
				error(ERROR_system(1),"cannot set %s",tp->name);
Packit Service a8c26c
			break;
Packit Service a8c26c
		    }
Packit Service a8c26c
#endif
Packit Service a8c26c
		    case NUM:
Packit Service a8c26c
			cp = *argv;
Packit Service a8c26c
			if (!cp)
Packit Service a8c26c
			{
Packit Service a8c26c
				if (tp->field == C_SPEED)
Packit Service a8c26c
				{
Packit Service a8c26c
					if (tp = getspeed(*tp->name == 'i' ? cfgetispeed(sp) : cfgetospeed(sp)))
Packit Service a8c26c
						sfprintf(sfstdout, "%s\n", tp->name);
Packit Service a8c26c
					break;
Packit Service a8c26c
				}
Packit Service a8c26c
				error(ERROR_exit(1), "%s: missing numeric argument", tp->name);
Packit Service a8c26c
			}
Packit Service a8c26c
			argv++;
Packit Service a8c26c
			c = (int)strtol(cp, &ep, 10);
Packit Service a8c26c
			if (*ep)
Packit Service a8c26c
				error(ERROR_exit(1), "%s: %s: numeric argument expected", tp->name, cp);
Packit Service a8c26c
			switch (tp->field)
Packit Service a8c26c
			{
Packit Service a8c26c
#if _mem_c_line_termios
Packit Service a8c26c
			case C_LINE:
Packit Service a8c26c
				sp->c_line = c;
Packit Service a8c26c
				break;
Packit Service a8c26c
#endif
Packit Service a8c26c
			case C_SPEED:
Packit Service a8c26c
				if(getspeed(c))
Packit Service a8c26c
				{
Packit Service a8c26c
					if (*tp->name != 'o')
Packit Service a8c26c
						cfsetispeed(sp, c);
Packit Service a8c26c
					if (*tp->name != 'i')
Packit Service a8c26c
						cfsetospeed(sp, c);
Packit Service a8c26c
				}
Packit Service a8c26c
				else
Packit Service a8c26c
					error(ERROR_exit(1), "%s: %s: invalid speed", tp->name, cp);
Packit Service a8c26c
				break;
Packit Service a8c26c
			case T_CHAR:
Packit Service a8c26c
				sp->c_cc[tp->mask] = c;
Packit Service a8c26c
				break;
Packit Service a8c26c
			}
Packit Service a8c26c
			break;
Packit Service a8c26c
		    case SPEED:
Packit Service a8c26c
			cfsetospeed(sp, tp->mask);
Packit Service a8c26c
			cfsetispeed(sp, tp->mask);
Packit Service a8c26c
			break;
Packit Service a8c26c
		    case SIZE:
Packit Service a8c26c
			sp->c_cflag &= ~CSIZE;
Packit Service a8c26c
			sp->c_cflag |= tp->mask;
Packit Service a8c26c
			break;
Packit Service a8c26c
		    case SANE:
Packit Service a8c26c
			sane(sp);
Packit Service a8c26c
			break;
Packit Service a8c26c
#if defined(OLCUC) && defined(IUCLC)
Packit Service a8c26c
		    case CASE:
Packit Service a8c26c
			if(off)
Packit Service a8c26c
			{
Packit Service a8c26c
				sp->c_iflag |= IUCLC;
Packit Service a8c26c
				sp->c_oflag |= OLCUC;
Packit Service a8c26c
			}
Packit Service a8c26c
			else
Packit Service a8c26c
			{
Packit Service a8c26c
				sp->c_iflag &= ~IUCLC;
Packit Service a8c26c
				sp->c_oflag &= ~OLCUC;
Packit Service a8c26c
			}
Packit Service a8c26c
			break;
Packit Service a8c26c
#endif /* OLCUC && IUCLC */
Packit Service a8c26c
		}
Packit Service a8c26c
	}
Packit Service a8c26c
}
Packit Service a8c26c
Packit Service a8c26c
Packit Service a8c26c
static void listchars(Sfio_t *sp,int type)
Packit Service a8c26c
{
Packit Service a8c26c
	int i,c;
Packit Service a8c26c
	c = (type==CHAR?'c':'n');
Packit Service a8c26c
	for(i=0; i < elementsof(Ttable); i++)
Packit Service a8c26c
	{
Packit Service a8c26c
		if(Ttable[i].type==type && *Ttable[i].description)
Packit Service a8c26c
			sfprintf(sp,"[+%s \a%c\a?%s.]",Ttable[i].name,c,Ttable[i].description);
Packit Service a8c26c
	}
Packit Service a8c26c
}
Packit Service a8c26c
Packit Service a8c26c
static void listgroup(Sfio_t *sp,int type, const char *description)
Packit Service a8c26c
{
Packit Service a8c26c
	int i;
Packit Service a8c26c
	sfprintf(sp,"[+");
Packit Service a8c26c
	for(i=0; i < elementsof(Ttable); i++)
Packit Service a8c26c
	{
Packit Service a8c26c
		if(Ttable[i].type==type)
Packit Service a8c26c
			sfprintf(sp,"%s ",Ttable[i].name);
Packit Service a8c26c
	}
Packit Service a8c26c
	sfprintf(sp,"?%s.]",description);
Packit Service a8c26c
}
Packit Service a8c26c
Packit Service a8c26c
static void listmask(Sfio_t *sp,unsigned int mask,const char *description)
Packit Service a8c26c
{
Packit Service a8c26c
	int i;
Packit Service a8c26c
	sfprintf(sp,"[+");
Packit Service a8c26c
	for(i=0; i < elementsof(Ttable); i++)
Packit Service a8c26c
	{
Packit Service a8c26c
		if(Ttable[i].mask==mask && Ttable[i].type==BITS)
Packit Service a8c26c
			sfprintf(sp,"%s ",Ttable[i].name);
Packit Service a8c26c
	}
Packit Service a8c26c
	sfprintf(sp,"?%s.]",description);
Packit Service a8c26c
}
Packit Service a8c26c
Packit Service a8c26c
static void listfields(Sfio_t *sp,int field)
Packit Service a8c26c
{
Packit Service a8c26c
	int i;
Packit Service a8c26c
	for(i=0; i < elementsof(Ttable); i++)
Packit Service a8c26c
	{
Packit Service a8c26c
		if(Ttable[i].field==field &&  Ttable[i].type==BIT && *Ttable[i].description)
Packit Service a8c26c
			sfprintf(sp,"[+%s (-%s)?%s.]",Ttable[i].name,Ttable[i].name,Ttable[i].description);
Packit Service a8c26c
	}
Packit Service a8c26c
}
Packit Service a8c26c
Packit Service a8c26c
static void listmode(Sfio_t *sp,const char *name)
Packit Service a8c26c
{
Packit Service a8c26c
	sfprintf(sp,"[+%s?%s.]",name,lookup(name)->description);
Packit Service a8c26c
}
Packit Service a8c26c
Packit Service a8c26c
static int infof(Opt_t* op, Sfio_t* sp, const char* s, Optdisc_t* dp)
Packit Service a8c26c
{
Packit Service a8c26c
	NoP(op);
Packit Service a8c26c
	NoP(s);
Packit Service a8c26c
	NoP(dp);
Packit Service a8c26c
	sfprintf(sp,"[+Control Modes.]{");
Packit Service a8c26c
	listfields(sp,C_FLAG);
Packit Service a8c26c
	listgroup(sp,SPEED,"Attempt to set input and output baud rate to number given.  A value of \b0\b causes immediate hangup");
Packit Service a8c26c
	listchars(sp,NUM);
Packit Service a8c26c
	listgroup(sp,SIZE,"Number of bits in a character");
Packit Service a8c26c
	sfprintf(sp,"}[+Input Modes.]{");
Packit Service a8c26c
	listfields(sp,I_FLAG);
Packit Service a8c26c
	sfprintf(sp,"}[+Output Modes.]{");
Packit Service a8c26c
	listfields(sp,O_FLAG);
Packit Service a8c26c
#ifdef CRDLY
Packit Service a8c26c
	listmask(sp,CRDLY,"Carriage return delay style");
Packit Service a8c26c
#endif
Packit Service a8c26c
#ifdef NLDLY
Packit Service a8c26c
	listmask(sp,NLDLY,"Newline delay style");
Packit Service a8c26c
#endif
Packit Service a8c26c
#ifdef TABDLY
Packit Service a8c26c
	listmask(sp,TABDLY,"Horizontal tab delay style");
Packit Service a8c26c
#endif
Packit Service a8c26c
#ifdef BSDLY
Packit Service a8c26c
	listmask(sp,BSDLY,"Backspace delay style");
Packit Service a8c26c
#endif
Packit Service a8c26c
#ifdef FFDLY
Packit Service a8c26c
	listmask(sp,FFDLY,"Form feed delay style");
Packit Service a8c26c
#endif
Packit Service a8c26c
#ifdef VTDLY
Packit Service a8c26c
	listmask(sp,VTDLY,"Vertical tab delay style");
Packit Service a8c26c
#endif
Packit Service a8c26c
	sfprintf(sp,"}[+Local Modes.]{");
Packit Service a8c26c
	listfields(sp,L_FLAG);
Packit Service a8c26c
	sfprintf(sp,"}[+Control Assignments.?If \ac\a is \bundef\b or an empty "
Packit Service a8c26c
		"string then the control assignment is disabled.]{");
Packit Service a8c26c
	listchars(sp,WIND);
Packit Service a8c26c
	listchars(sp,CHAR);
Packit Service a8c26c
	sfprintf(sp,"}[+Combination Modes.]{");
Packit Service a8c26c
	listmode(sp,"ek");
Packit Service a8c26c
	listmode(sp,"evenp");
Packit Service a8c26c
	listmode(sp,"lcase");
Packit Service a8c26c
	listmode(sp,"oddp");
Packit Service a8c26c
	listmode(sp,"parity");
Packit Service a8c26c
	listmode(sp,"sane");
Packit Service a8c26c
	listmode(sp,"tabs");
Packit Service a8c26c
	listmode(sp,"LCASE");
Packit Service a8c26c
	sfputc(sp,'}');
Packit Service a8c26c
	return(1);
Packit Service a8c26c
}
Packit Service a8c26c
Packit Service a8c26c
#ifndef _lib_tcgetpgrp
Packit Service a8c26c
#  ifdef TIOCGPGRP
Packit Service a8c26c
	   static int _i_;
Packit Service a8c26c
#	   define tcgetpgrp(a) (ioctl(a, TIOCGPGRP, &_i_)>=0?_i_:-1)	
Packit Service a8c26c
#  else
Packit Service a8c26c
#	   define tcgetpgrp(a) (-1)
Packit Service a8c26c
#  endif /* TIOCGPGRP */
Packit Service a8c26c
#endif /* _lib_tcgetpgrp */
Packit Service a8c26c
Packit Service a8c26c
int
Packit Service a8c26c
b_stty(int argc, char** argv, Shbltin_t* context)
Packit Service a8c26c
{
Packit Service a8c26c
	struct termios		tty;
Packit Service a8c26c
	register int		n;
Packit Service a8c26c
	register int		flags = 0;
Packit Service a8c26c
	int			fd = 0;
Packit Service a8c26c
	const Tty_t*		tp;
Packit Service a8c26c
	Optdisc_t		disc;
Packit Service a8c26c
Packit Service a8c26c
	cmdinit(argc, argv, context, ERROR_CATALOG, ERROR_INTERACTIVE);
Packit Service a8c26c
	memset(&disc, 0, sizeof(disc));
Packit Service a8c26c
	disc.version = OPT_VERSION;
Packit Service a8c26c
	disc.infof = infof;
Packit Service a8c26c
	opt_info.disc = &disc;
Packit Service a8c26c
	for (;;)
Packit Service a8c26c
	{
Packit Service a8c26c
		switch (n = optget(argv, usage))
Packit Service a8c26c
		{
Packit Service a8c26c
		case 'f':
Packit Service a8c26c
			fd = (int)opt_info.num;
Packit Service a8c26c
			continue;
Packit Service a8c26c
		case 'a':
Packit Service a8c26c
		case 'g':
Packit Service a8c26c
		case 't':
Packit Service a8c26c
			if (!opt_info.offset || !argv[opt_info.index][opt_info.offset])
Packit Service a8c26c
			{
Packit Service a8c26c
				switch (n)
Packit Service a8c26c
				{
Packit Service a8c26c
				case 'a':
Packit Service a8c26c
					flags |= A_FLAG;
Packit Service a8c26c
					break;
Packit Service a8c26c
				case 'g':
Packit Service a8c26c
					flags |= G_FLAG;
Packit Service a8c26c
					break;
Packit Service a8c26c
				case 't':
Packit Service a8c26c
					flags |= T_FLAG;
Packit Service a8c26c
					break;
Packit Service a8c26c
				}
Packit Service a8c26c
				continue;
Packit Service a8c26c
			}
Packit Service a8c26c
			/*FALLTHROUGH*/
Packit Service a8c26c
		case ':':
Packit Service a8c26c
			if (!opt_info.offset)
Packit Service a8c26c
				error(2, "%s", opt_info.arg);
Packit Service a8c26c
			else if (!(tp = lookup(argv[opt_info.index]+1)) || (tp->type != BIT && tp->type != TABS))
Packit Service a8c26c
				error(ERROR_exit(1), "%s: unknown mode", argv[opt_info.index]);
Packit Service a8c26c
			break;
Packit Service a8c26c
		case '?':
Packit Service a8c26c
			error(ERROR_usage(2), "%s", opt_info.arg);
Packit Service a8c26c
			break;
Packit Service a8c26c
		}
Packit Service a8c26c
		break;
Packit Service a8c26c
	}
Packit Service a8c26c
	argv += opt_info.index;
Packit Service a8c26c
	if (error_info.errors || (flags && *argv) || (flags&(flags-1)))
Packit Service a8c26c
		error(ERROR_usage(2), "%s", optusage(NiL));
Packit Service a8c26c
	if (tcgetattr(fd, &tty) < 0)
Packit Service a8c26c
		error(ERROR_system(1), "not a tty");
Packit Service a8c26c
	if (flags & T_FLAG)
Packit Service a8c26c
		sfprintf(sfstdout, "%d\n", tcgetpgrp(0));
Packit Service a8c26c
	else if (*argv)
Packit Service a8c26c
	{
Packit Service a8c26c
		if (!argv[1] && **argv == ':')
Packit Service a8c26c
			gin(*argv, &tty);
Packit Service a8c26c
		else
Packit Service a8c26c
			set(argv, &tty);
Packit Service a8c26c
		if (tcsetattr(0, TCSANOW, &tty) < 0)
Packit Service a8c26c
			error(ERROR_system(1), "cannot set tty");
Packit Service a8c26c
	}
Packit Service a8c26c
	else
Packit Service a8c26c
		output(&tty, flags);
Packit Service a8c26c
	return error_info.errors;
Packit Service a8c26c
}