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