xref: /onnv-gate/usr/src/lib/libbc/libc/gen/common/posix_tty.c (revision 722:636b850d4ee9)
10Sstevel@tonic-gate /*
20Sstevel@tonic-gate  * CDDL HEADER START
30Sstevel@tonic-gate  *
40Sstevel@tonic-gate  * The contents of this file are subject to the terms of the
50Sstevel@tonic-gate  * Common Development and Distribution License, Version 1.0 only
60Sstevel@tonic-gate  * (the "License").  You may not use this file except in compliance
70Sstevel@tonic-gate  * with the License.
80Sstevel@tonic-gate  *
90Sstevel@tonic-gate  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
100Sstevel@tonic-gate  * or http://www.opensolaris.org/os/licensing.
110Sstevel@tonic-gate  * See the License for the specific language governing permissions
120Sstevel@tonic-gate  * and limitations under the License.
130Sstevel@tonic-gate  *
140Sstevel@tonic-gate  * When distributing Covered Code, include this CDDL HEADER in each
150Sstevel@tonic-gate  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
160Sstevel@tonic-gate  * If applicable, add the following below this CDDL HEADER, with the
170Sstevel@tonic-gate  * fields enclosed by brackets "[]" replaced with your own identifying
180Sstevel@tonic-gate  * information: Portions Copyright [yyyy] [name of copyright owner]
190Sstevel@tonic-gate  *
200Sstevel@tonic-gate  * CDDL HEADER END
210Sstevel@tonic-gate  */
220Sstevel@tonic-gate /*
230Sstevel@tonic-gate  * Copyright 1995 Sun Microsystems, Inc.  All rights reserved.
240Sstevel@tonic-gate  * Use is subject to license terms.
250Sstevel@tonic-gate  */
260Sstevel@tonic-gate 
27*722Smuffin #pragma ident	"%Z%%M%	%I%	%E% SMI"
280Sstevel@tonic-gate 
290Sstevel@tonic-gate /*
300Sstevel@tonic-gate  * wrappers for posix tty manipulation functions
310Sstevel@tonic-gate  */
320Sstevel@tonic-gate 
330Sstevel@tonic-gate #include <errno.h>
340Sstevel@tonic-gate #include <termios.h>
350Sstevel@tonic-gate #include <termio.h>
360Sstevel@tonic-gate #include <sys/types.h>
370Sstevel@tonic-gate 
380Sstevel@tonic-gate /*
390Sstevel@tonic-gate  * return the output speed from the struct
400Sstevel@tonic-gate  */
410Sstevel@tonic-gate speed_t
cfgetospeed(struct termios * termios_p)42*722Smuffin cfgetospeed(struct termios *termios_p)
430Sstevel@tonic-gate {
440Sstevel@tonic-gate 	return (termios_p->c_cflag & CBAUDEXT ?
450Sstevel@tonic-gate 			(termios_p->c_cflag & CBAUD) + CBAUD + 1 :
460Sstevel@tonic-gate 			termios_p->c_cflag & CBAUD);
470Sstevel@tonic-gate }
480Sstevel@tonic-gate 
490Sstevel@tonic-gate /*
500Sstevel@tonic-gate  * set the speed in the struct
510Sstevel@tonic-gate  */
52*722Smuffin int
cfsetospeed(struct termios * termios_p,speed_t speed)53*722Smuffin cfsetospeed(struct termios *termios_p, speed_t speed)
540Sstevel@tonic-gate {
550Sstevel@tonic-gate 	if (speed > (2*CBAUD + 1)) {
560Sstevel@tonic-gate 		errno = EINVAL;
570Sstevel@tonic-gate 		return (-1);
580Sstevel@tonic-gate 	}
590Sstevel@tonic-gate 	if (speed > CBAUD) {
600Sstevel@tonic-gate 		termios_p->c_cflag |= CBAUDEXT;
610Sstevel@tonic-gate 		speed -= (CBAUD + 1);
620Sstevel@tonic-gate 	} else
630Sstevel@tonic-gate 		termios_p->c_cflag &= ~CBAUDEXT;
640Sstevel@tonic-gate 
650Sstevel@tonic-gate 	termios_p->c_cflag =
660Sstevel@tonic-gate 	    (termios_p->c_cflag & ~CBAUD) | (speed & CBAUD);
670Sstevel@tonic-gate 	return (0);
680Sstevel@tonic-gate }
690Sstevel@tonic-gate 
700Sstevel@tonic-gate /*
710Sstevel@tonic-gate  * return the input speed from the struct
720Sstevel@tonic-gate  */
730Sstevel@tonic-gate speed_t
cfgetispeed(struct termios * termios_p)74*722Smuffin cfgetispeed(struct termios *termios_p)
750Sstevel@tonic-gate {
760Sstevel@tonic-gate 	return (termios_p->c_cflag & CIBAUDEXT ?
770Sstevel@tonic-gate 	    ((termios_p->c_cflag & CIBAUD) >> IBSHIFT)
780Sstevel@tonic-gate 		+ (CIBAUD >> IBSHIFT) + 1 :
790Sstevel@tonic-gate 	    (termios_p->c_cflag & CIBAUD) >> IBSHIFT);
800Sstevel@tonic-gate }
810Sstevel@tonic-gate 
820Sstevel@tonic-gate /*
830Sstevel@tonic-gate  * set the input speed in the struct
840Sstevel@tonic-gate  */
85*722Smuffin int
cfsetispeed(struct termios * termios_p,speed_t speed)86*722Smuffin cfsetispeed(struct termios *termios_p, speed_t speed)
870Sstevel@tonic-gate {
880Sstevel@tonic-gate 	if (speed > (2*CBAUD + 1)) {
890Sstevel@tonic-gate 		errno = EINVAL;
900Sstevel@tonic-gate 		return (-1);
910Sstevel@tonic-gate 	}
920Sstevel@tonic-gate 	if ((speed << IBSHIFT) > CIBAUD) {
930Sstevel@tonic-gate 		termios_p->c_cflag |= CIBAUDEXT;
940Sstevel@tonic-gate 		speed -= ((CIBAUD >> IBSHIFT) + 1);
950Sstevel@tonic-gate 	} else
960Sstevel@tonic-gate 		termios_p->c_cflag &= ~CIBAUDEXT;
970Sstevel@tonic-gate 	termios_p->c_cflag =
980Sstevel@tonic-gate 	    (termios_p->c_cflag & ~CIBAUD) | ((speed << IBSHIFT) & CIBAUD);
990Sstevel@tonic-gate 	return (0);
1000Sstevel@tonic-gate }
1010Sstevel@tonic-gate 
1020Sstevel@tonic-gate /*
1030Sstevel@tonic-gate  * grab the modes
1040Sstevel@tonic-gate  */
105*722Smuffin int
tcgetattr(int fd,struct termios * termios_p)106*722Smuffin tcgetattr(int fd, struct termios *termios_p)
1070Sstevel@tonic-gate {
1080Sstevel@tonic-gate 	return (ioctl(fd, TCGETS, termios_p));
1090Sstevel@tonic-gate }
1100Sstevel@tonic-gate 
1110Sstevel@tonic-gate /*
1120Sstevel@tonic-gate  * set the modes
1130Sstevel@tonic-gate  */
114*722Smuffin int
tcsetattr(int fd,int option,struct termios * termios_p)115*722Smuffin tcsetattr(int fd, int option, struct termios *termios_p)
1160Sstevel@tonic-gate {
1170Sstevel@tonic-gate 	struct termios	work_area;
1180Sstevel@tonic-gate 
1190Sstevel@tonic-gate 	/* If input speed is zero, set it to the output speed. */
1200Sstevel@tonic-gate 	if ((((termios_p->c_cflag >> IBSHIFT) & CIBAUD) == 0) &&
1210Sstevel@tonic-gate 		((termios_p->c_cflag & CIBAUDEXT) == 0)) {
1220Sstevel@tonic-gate 		work_area = *termios_p;
1230Sstevel@tonic-gate 		work_area.c_cflag |= (work_area.c_cflag & CBAUD) << IBSHIFT;
1240Sstevel@tonic-gate 		if (termios_p->c_cflag & CBAUDEXT)
1250Sstevel@tonic-gate 			work_area.c_cflag |= CIBAUDEXT;
1260Sstevel@tonic-gate 		termios_p = &work_area;
1270Sstevel@tonic-gate 	}
1280Sstevel@tonic-gate 	switch (option) {
1290Sstevel@tonic-gate 	case TCSADRAIN:
1300Sstevel@tonic-gate 		return (ioctl(fd, TCSETSW, termios_p));
1310Sstevel@tonic-gate 	case TCSAFLUSH:
1320Sstevel@tonic-gate 		return (ioctl(fd, TCSETSF, termios_p));
1330Sstevel@tonic-gate 	case TCSANOW:
1340Sstevel@tonic-gate 		return (ioctl(fd, TCSETS, termios_p));
1350Sstevel@tonic-gate 	default:
1360Sstevel@tonic-gate 		errno = EINVAL;
1370Sstevel@tonic-gate 		return (-1);
1380Sstevel@tonic-gate 	}
1390Sstevel@tonic-gate 	/*NOTREACHED*/
1400Sstevel@tonic-gate }
1410Sstevel@tonic-gate 
1420Sstevel@tonic-gate /*
1430Sstevel@tonic-gate  * send a break
1440Sstevel@tonic-gate  * This is kludged for duration != 0; it should do something like crank the
1450Sstevel@tonic-gate  * baud rate down and then send the break if the duration != 0.
1460Sstevel@tonic-gate  */
147*722Smuffin int
tcsendbreak(int fd,int duration)148*722Smuffin tcsendbreak(int fd, int duration)
1490Sstevel@tonic-gate {
150*722Smuffin 	unsigned d = (unsigned)duration;
1510Sstevel@tonic-gate 
1520Sstevel@tonic-gate 	do
1530Sstevel@tonic-gate 		if (ioctl(fd, TCSBRK, 0) == -1)
1540Sstevel@tonic-gate 			return (-1);
1550Sstevel@tonic-gate 	while (d--);
1560Sstevel@tonic-gate 	return (0);
1570Sstevel@tonic-gate }
1580Sstevel@tonic-gate 
1590Sstevel@tonic-gate /*
1600Sstevel@tonic-gate  * wait for all output to drain from fd
1610Sstevel@tonic-gate  */
162*722Smuffin int
tcdrain(int fd)163*722Smuffin tcdrain(int fd)
1640Sstevel@tonic-gate {
1650Sstevel@tonic-gate 	return (ioctl(fd, TCSBRK, !0));
1660Sstevel@tonic-gate }
1670Sstevel@tonic-gate 
1680Sstevel@tonic-gate /*
1690Sstevel@tonic-gate  * flow control
1700Sstevel@tonic-gate  */
171*722Smuffin int
tcflow(int fd,int action)172*722Smuffin tcflow(int fd, int action)
1730Sstevel@tonic-gate {
1740Sstevel@tonic-gate 	switch (action) {
1750Sstevel@tonic-gate 	default:
1760Sstevel@tonic-gate 		errno = EINVAL;
1770Sstevel@tonic-gate 		return (-1);
1780Sstevel@tonic-gate 	case TCOOFF:
1790Sstevel@tonic-gate 	case TCOON:
1800Sstevel@tonic-gate 	case TCIOFF:
1810Sstevel@tonic-gate 	case TCION:
1820Sstevel@tonic-gate 		return (ioctl(fd, TCXONC, action));
1830Sstevel@tonic-gate 	}
1840Sstevel@tonic-gate 	/*NOTREACHED*/
1850Sstevel@tonic-gate }
1860Sstevel@tonic-gate 
1870Sstevel@tonic-gate /*
1880Sstevel@tonic-gate  * flush read/write/both
1890Sstevel@tonic-gate  */
190*722Smuffin int
tcflush(int fd,int queue)191*722Smuffin tcflush(int fd, int queue)
1920Sstevel@tonic-gate {
1930Sstevel@tonic-gate 	switch (queue) {
1940Sstevel@tonic-gate 	default:
1950Sstevel@tonic-gate 		errno = EINVAL;
1960Sstevel@tonic-gate 		return (-1);
1970Sstevel@tonic-gate 	case TCIFLUSH:
1980Sstevel@tonic-gate 	case TCOFLUSH:
1990Sstevel@tonic-gate 	case TCIOFLUSH:
2000Sstevel@tonic-gate 		return (ioctl(fd, TCFLSH, queue));
2010Sstevel@tonic-gate 	}
2020Sstevel@tonic-gate 	/*NOTREACHED*/
2030Sstevel@tonic-gate }
2040Sstevel@tonic-gate 
2050Sstevel@tonic-gate /*
2060Sstevel@tonic-gate  * get the foreground process group id
2070Sstevel@tonic-gate  */
2080Sstevel@tonic-gate pid_t
tcgetpgrp(int fd)209*722Smuffin tcgetpgrp(int fd)
2100Sstevel@tonic-gate {
2110Sstevel@tonic-gate 	int grp_id;
2120Sstevel@tonic-gate 
2130Sstevel@tonic-gate 	if (ioctl(fd, TIOCGETPGRP, &grp_id) == -1)
2140Sstevel@tonic-gate 		return ((pid_t)-1);
2150Sstevel@tonic-gate 	else
2160Sstevel@tonic-gate 		return ((pid_t)grp_id);
2170Sstevel@tonic-gate }
2180Sstevel@tonic-gate 
2190Sstevel@tonic-gate /*
2200Sstevel@tonic-gate  * set the foreground process group id
2210Sstevel@tonic-gate  */
222*722Smuffin int
tcsetpgrp(int fd,int grp_id)223*722Smuffin tcsetpgrp(int fd, int grp_id)
2240Sstevel@tonic-gate {
2250Sstevel@tonic-gate 	return (ioctl(fd, TIOCSETPGRP, &grp_id));
2260Sstevel@tonic-gate }
227