11573Srgrimes/*-
21573Srgrimes * Copyright (c) 1989, 1993
31573Srgrimes *	The Regents of the University of California.  All rights reserved.
41573Srgrimes *
51573Srgrimes * Redistribution and use in source and binary forms, with or without
61573Srgrimes * modification, are permitted provided that the following conditions
71573Srgrimes * are met:
81573Srgrimes * 1. Redistributions of source code must retain the above copyright
91573Srgrimes *    notice, this list of conditions and the following disclaimer.
101573Srgrimes * 2. Redistributions in binary form must reproduce the above copyright
111573Srgrimes *    notice, this list of conditions and the following disclaimer in the
121573Srgrimes *    documentation and/or other materials provided with the distribution.
131573Srgrimes * 4. Neither the name of the University nor the names of its contributors
141573Srgrimes *    may be used to endorse or promote products derived from this software
151573Srgrimes *    without specific prior written permission.
161573Srgrimes *
171573Srgrimes * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
181573Srgrimes * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
191573Srgrimes * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
201573Srgrimes * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
211573Srgrimes * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
221573Srgrimes * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
231573Srgrimes * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
241573Srgrimes * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
251573Srgrimes * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
261573Srgrimes * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
271573Srgrimes * SUCH DAMAGE.
281573Srgrimes */
291573Srgrimes
301573Srgrimes#if defined(LIBC_SCCS) && !defined(lint)
311573Srgrimesstatic char sccsid[] = "@(#)termios.c	8.2 (Berkeley) 2/21/94";
321573Srgrimes#endif /* LIBC_SCCS and not lint */
3390039Sobrien#include <sys/cdefs.h>
3490039Sobrien__FBSDID("$FreeBSD$");
351573Srgrimes
3671579Sdeischen#include "namespace.h"
371573Srgrimes#include <sys/types.h>
3811677Sbde#include <sys/fcntl.h>
391573Srgrimes#include <sys/ioctl.h>
401573Srgrimes#include <sys/time.h>
411573Srgrimes
421573Srgrimes#include <errno.h>
43214680Sed#include <string.h>
44214680Sed#define	TTYDEFCHARS
451573Srgrimes#include <termios.h>
461573Srgrimes#include <unistd.h>
4771579Sdeischen#include "un-namespace.h"
481573Srgrimes
491573Srgrimesint
50200134Sedtcgetattr(int fd, struct termios *t)
511573Srgrimes{
521573Srgrimes
5371579Sdeischen	return (_ioctl(fd, TIOCGETA, t));
541573Srgrimes}
551573Srgrimes
561573Srgrimesint
57200134Sedtcsetattr(int fd, int opt, const struct termios *t)
581573Srgrimes{
591573Srgrimes	struct termios localterm;
601573Srgrimes
611573Srgrimes	if (opt & TCSASOFT) {
621573Srgrimes		localterm = *t;
631573Srgrimes		localterm.c_cflag |= CIGNORE;
641573Srgrimes		t = &localterm;
651573Srgrimes	}
661573Srgrimes	switch (opt & ~TCSASOFT) {
671573Srgrimes	case TCSANOW:
6871579Sdeischen		return (_ioctl(fd, TIOCSETA, t));
691573Srgrimes	case TCSADRAIN:
7071579Sdeischen		return (_ioctl(fd, TIOCSETAW, t));
711573Srgrimes	case TCSAFLUSH:
7271579Sdeischen		return (_ioctl(fd, TIOCSETAF, t));
731573Srgrimes	default:
741573Srgrimes		errno = EINVAL;
751573Srgrimes		return (-1);
761573Srgrimes	}
771573Srgrimes}
781573Srgrimes
791573Srgrimesint
801573Srgrimestcsetpgrp(int fd, pid_t pgrp)
811573Srgrimes{
821573Srgrimes	int s;
831573Srgrimes
841573Srgrimes	s = pgrp;
8571579Sdeischen	return (_ioctl(fd, TIOCSPGRP, &s));
861573Srgrimes}
871573Srgrimes
881573Srgrimespid_t
89200134Sedtcgetpgrp(int fd)
901573Srgrimes{
911573Srgrimes	int s;
921573Srgrimes
9371579Sdeischen	if (_ioctl(fd, TIOCGPGRP, &s) < 0)
941573Srgrimes		return ((pid_t)-1);
951573Srgrimes
961573Srgrimes	return ((pid_t)s);
971573Srgrimes}
981573Srgrimes
99178219Sdavidxupid_t
100178219Sdavidxutcgetsid(int fd)
101178219Sdavidxu{
102178219Sdavidxu	int s;
103178219Sdavidxu
104178219Sdavidxu	if (_ioctl(fd, TIOCGSID, &s) < 0)
105178219Sdavidxu		return ((pid_t)-1);
106178219Sdavidxu
107178219Sdavidxu	return ((pid_t)s);
108178219Sdavidxu}
109178219Sdavidxu
110191882Sedint
111191882Sedtcsetsid(int fd, pid_t pid)
112191882Sed{
113191882Sed
114191882Sed	if (pid != getsid(0)) {
115191882Sed		errno = EINVAL;
116191882Sed		return (-1);
117191882Sed	}
118191882Sed
119191882Sed	return (_ioctl(fd, TIOCSCTTY, NULL));
120191882Sed}
121191882Sed
1221573Srgrimesspeed_t
123200134Sedcfgetospeed(const struct termios *t)
1241573Srgrimes{
1251573Srgrimes
1261573Srgrimes	return (t->c_ospeed);
1271573Srgrimes}
1281573Srgrimes
1291573Srgrimesspeed_t
130200134Sedcfgetispeed(const struct termios *t)
1311573Srgrimes{
1321573Srgrimes
1331573Srgrimes	return (t->c_ispeed);
1341573Srgrimes}
1351573Srgrimes
1361573Srgrimesint
137200134Sedcfsetospeed(struct termios *t, speed_t speed)
1381573Srgrimes{
1391573Srgrimes
1401573Srgrimes	t->c_ospeed = speed;
1411573Srgrimes	return (0);
1421573Srgrimes}
1431573Srgrimes
1441573Srgrimesint
145200134Sedcfsetispeed(struct termios *t, speed_t speed)
1461573Srgrimes{
1471573Srgrimes
1481573Srgrimes	t->c_ispeed = speed;
1491573Srgrimes	return (0);
1501573Srgrimes}
1511573Srgrimes
1521573Srgrimesint
153200134Sedcfsetspeed(struct termios *t, speed_t speed)
1541573Srgrimes{
1551573Srgrimes
1561573Srgrimes	t->c_ispeed = t->c_ospeed = speed;
1571573Srgrimes	return (0);
1581573Srgrimes}
1591573Srgrimes
1601573Srgrimes/*
1611573Srgrimes * Make a pre-existing termios structure into "raw" mode: character-at-a-time
1621573Srgrimes * mode with no characters interpreted, 8-bit data path.
1631573Srgrimes */
1641573Srgrimesvoid
165200134Sedcfmakeraw(struct termios *t)
1661573Srgrimes{
1671573Srgrimes
1687471Sache	t->c_iflag &= ~(IMAXBEL|IXOFF|INPCK|BRKINT|PARMRK|ISTRIP|INLCR|IGNCR|ICRNL|IXON|IGNPAR);
1697471Sache	t->c_iflag |= IGNBRK;
1701573Srgrimes	t->c_oflag &= ~OPOST;
1713799Sache	t->c_lflag &= ~(ECHO|ECHOE|ECHOK|ECHONL|ICANON|ISIG|IEXTEN|NOFLSH|TOSTOP|PENDIN);
17214870Sache	t->c_cflag &= ~(CSIZE|PARENB);
17314858Sache	t->c_cflag |= CS8|CREAD;
1743760Sache	t->c_cc[VMIN] = 1;
1753760Sache	t->c_cc[VTIME] = 0;
1761573Srgrimes}
1771573Srgrimes
178214680Sed/*
179214680Sed * Obtain a termios structure which is similar to the one provided by
180214680Sed * the kernel.
181214680Sed */
182214680Sedvoid
183214680Sedcfmakesane(struct termios *t)
184214680Sed{
185214680Sed
186214680Sed	t->c_cflag = TTYDEF_CFLAG;
187214680Sed	t->c_iflag = TTYDEF_IFLAG;
188214680Sed	t->c_lflag = TTYDEF_LFLAG;
189214680Sed	t->c_oflag = TTYDEF_OFLAG;
190214680Sed	t->c_ispeed = TTYDEF_SPEED;
191214680Sed	t->c_ospeed = TTYDEF_SPEED;
192214680Sed	memcpy(&t->c_cc, ttydefchars, sizeof ttydefchars);
193214680Sed}
194214680Sed
19511677Sbdeint
196200134Sedtcsendbreak(int fd, int len __unused)
1971573Srgrimes{
1981573Srgrimes	struct timeval sleepytime;
1991573Srgrimes
2001573Srgrimes	sleepytime.tv_sec = 0;
2011573Srgrimes	sleepytime.tv_usec = 400000;
20271579Sdeischen	if (_ioctl(fd, TIOCSBRK, 0) == -1)
2031573Srgrimes		return (-1);
20471579Sdeischen	(void)_select(0, 0, 0, 0, &sleepytime);
20571579Sdeischen	if (_ioctl(fd, TIOCCBRK, 0) == -1)
2061573Srgrimes		return (-1);
2071573Srgrimes	return (0);
2081573Srgrimes}
2091573Srgrimes
21011677Sbdeint
211200134Sed__tcdrain(int fd)
2121573Srgrimes{
21371579Sdeischen	return (_ioctl(fd, TIOCDRAIN, 0));
2141573Srgrimes}
2151573Srgrimes
21656698Sjasone__weak_reference(__tcdrain, tcdrain);
21771579Sdeischen__weak_reference(__tcdrain, _tcdrain);
21855837Sjasone
21911677Sbdeint
220200134Sedtcflush(int fd, int which)
2211573Srgrimes{
2221573Srgrimes	int com;
2231573Srgrimes
2241573Srgrimes	switch (which) {
2251573Srgrimes	case TCIFLUSH:
2261573Srgrimes		com = FREAD;
2271573Srgrimes		break;
2281573Srgrimes	case TCOFLUSH:
2291573Srgrimes		com = FWRITE;
2301573Srgrimes		break;
2311573Srgrimes	case TCIOFLUSH:
2321573Srgrimes		com = FREAD | FWRITE;
2331573Srgrimes		break;
2341573Srgrimes	default:
2351573Srgrimes		errno = EINVAL;
2361573Srgrimes		return (-1);
2371573Srgrimes	}
23871579Sdeischen	return (_ioctl(fd, TIOCFLUSH, &com));
2391573Srgrimes}
2401573Srgrimes
24111677Sbdeint
242200134Sedtcflow(int fd, int action)
2431573Srgrimes{
2441573Srgrimes	struct termios term;
2451573Srgrimes	u_char c;
2461573Srgrimes
2471573Srgrimes	switch (action) {
2481573Srgrimes	case TCOOFF:
24971579Sdeischen		return (_ioctl(fd, TIOCSTOP, 0));
2501573Srgrimes	case TCOON:
25171579Sdeischen		return (_ioctl(fd, TIOCSTART, 0));
2521573Srgrimes	case TCION:
2531573Srgrimes	case TCIOFF:
2541573Srgrimes		if (tcgetattr(fd, &term) == -1)
2551573Srgrimes			return (-1);
2561573Srgrimes		c = term.c_cc[action == TCIOFF ? VSTOP : VSTART];
25756698Sjasone		if (c != _POSIX_VDISABLE && _write(fd, &c, sizeof(c)) == -1)
2581573Srgrimes			return (-1);
2591573Srgrimes		return (0);
2601573Srgrimes	default:
2611573Srgrimes		errno = EINVAL;
2621573Srgrimes		return (-1);
2631573Srgrimes	}
2641573Srgrimes	/* NOTREACHED */
2651573Srgrimes}
266