1 /* 2 * CDDL HEADER START 3 * 4 * The contents of this file are subject to the terms of the 5 * Common Development and Distribution License, Version 1.0 only 6 * (the "License"). You may not use this file except in compliance 7 * with the License. 8 * 9 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 10 * or http://www.opensolaris.org/os/licensing. 11 * See the License for the specific language governing permissions 12 * and limitations under the License. 13 * 14 * When distributing Covered Code, include this CDDL HEADER in each 15 * file and include the License file at usr/src/OPENSOLARIS.LICENSE. 16 * If applicable, add the following below this CDDL HEADER, with the 17 * fields enclosed by brackets "[]" replaced with your own identifying 18 * information: Portions Copyright [yyyy] [name of copyright owner] 19 * 20 * CDDL HEADER END 21 */ 22 /* 23 * Copyright 1995 Sun Microsystems, Inc. All rights reserved. 24 * Use is subject to license terms. 25 */ 26 27 #pragma ident "%Z%%M% %I% %E% SMI" 28 29 /* 30 * wrappers for posix tty manipulation functions 31 */ 32 33 #include <errno.h> 34 #include <termios.h> 35 #include <termio.h> 36 #include <sys/types.h> 37 38 /* 39 * return the output speed from the struct 40 */ 41 speed_t 42 cfgetospeed(struct termios *termios_p) 43 { 44 return (termios_p->c_cflag & CBAUDEXT ? 45 (termios_p->c_cflag & CBAUD) + CBAUD + 1 : 46 termios_p->c_cflag & CBAUD); 47 } 48 49 /* 50 * set the speed in the struct 51 */ 52 int 53 cfsetospeed(struct termios *termios_p, speed_t speed) 54 { 55 if (speed > (2*CBAUD + 1)) { 56 errno = EINVAL; 57 return (-1); 58 } 59 if (speed > CBAUD) { 60 termios_p->c_cflag |= CBAUDEXT; 61 speed -= (CBAUD + 1); 62 } else 63 termios_p->c_cflag &= ~CBAUDEXT; 64 65 termios_p->c_cflag = 66 (termios_p->c_cflag & ~CBAUD) | (speed & CBAUD); 67 return (0); 68 } 69 70 /* 71 * return the input speed from the struct 72 */ 73 speed_t 74 cfgetispeed(struct termios *termios_p) 75 { 76 return (termios_p->c_cflag & CIBAUDEXT ? 77 ((termios_p->c_cflag & CIBAUD) >> IBSHIFT) 78 + (CIBAUD >> IBSHIFT) + 1 : 79 (termios_p->c_cflag & CIBAUD) >> IBSHIFT); 80 } 81 82 /* 83 * set the input speed in the struct 84 */ 85 int 86 cfsetispeed(struct termios *termios_p, speed_t speed) 87 { 88 if (speed > (2*CBAUD + 1)) { 89 errno = EINVAL; 90 return (-1); 91 } 92 if ((speed << IBSHIFT) > CIBAUD) { 93 termios_p->c_cflag |= CIBAUDEXT; 94 speed -= ((CIBAUD >> IBSHIFT) + 1); 95 } else 96 termios_p->c_cflag &= ~CIBAUDEXT; 97 termios_p->c_cflag = 98 (termios_p->c_cflag & ~CIBAUD) | ((speed << IBSHIFT) & CIBAUD); 99 return (0); 100 } 101 102 /* 103 * grab the modes 104 */ 105 int 106 tcgetattr(int fd, struct termios *termios_p) 107 { 108 return (ioctl(fd, TCGETS, termios_p)); 109 } 110 111 /* 112 * set the modes 113 */ 114 int 115 tcsetattr(int fd, int option, struct termios *termios_p) 116 { 117 struct termios work_area; 118 119 /* If input speed is zero, set it to the output speed. */ 120 if ((((termios_p->c_cflag >> IBSHIFT) & CIBAUD) == 0) && 121 ((termios_p->c_cflag & CIBAUDEXT) == 0)) { 122 work_area = *termios_p; 123 work_area.c_cflag |= (work_area.c_cflag & CBAUD) << IBSHIFT; 124 if (termios_p->c_cflag & CBAUDEXT) 125 work_area.c_cflag |= CIBAUDEXT; 126 termios_p = &work_area; 127 } 128 switch (option) { 129 case TCSADRAIN: 130 return (ioctl(fd, TCSETSW, termios_p)); 131 case TCSAFLUSH: 132 return (ioctl(fd, TCSETSF, termios_p)); 133 case TCSANOW: 134 return (ioctl(fd, TCSETS, termios_p)); 135 default: 136 errno = EINVAL; 137 return (-1); 138 } 139 /*NOTREACHED*/ 140 } 141 142 /* 143 * send a break 144 * This is kludged for duration != 0; it should do something like crank the 145 * baud rate down and then send the break if the duration != 0. 146 */ 147 int 148 tcsendbreak(int fd, int duration) 149 { 150 unsigned d = (unsigned)duration; 151 152 do 153 if (ioctl(fd, TCSBRK, 0) == -1) 154 return (-1); 155 while (d--); 156 return (0); 157 } 158 159 /* 160 * wait for all output to drain from fd 161 */ 162 int 163 tcdrain(int fd) 164 { 165 return (ioctl(fd, TCSBRK, !0)); 166 } 167 168 /* 169 * flow control 170 */ 171 int 172 tcflow(int fd, int action) 173 { 174 switch (action) { 175 default: 176 errno = EINVAL; 177 return (-1); 178 case TCOOFF: 179 case TCOON: 180 case TCIOFF: 181 case TCION: 182 return (ioctl(fd, TCXONC, action)); 183 } 184 /*NOTREACHED*/ 185 } 186 187 /* 188 * flush read/write/both 189 */ 190 int 191 tcflush(int fd, int queue) 192 { 193 switch (queue) { 194 default: 195 errno = EINVAL; 196 return (-1); 197 case TCIFLUSH: 198 case TCOFLUSH: 199 case TCIOFLUSH: 200 return (ioctl(fd, TCFLSH, queue)); 201 } 202 /*NOTREACHED*/ 203 } 204 205 /* 206 * get the foreground process group id 207 */ 208 pid_t 209 tcgetpgrp(int fd) 210 { 211 int grp_id; 212 213 if (ioctl(fd, TIOCGETPGRP, &grp_id) == -1) 214 return ((pid_t)-1); 215 else 216 return ((pid_t)grp_id); 217 } 218 219 /* 220 * set the foreground process group id 221 */ 222 int 223 tcsetpgrp(int fd, int grp_id) 224 { 225 return (ioctl(fd, TIOCSETPGRP, &grp_id)); 226 } 227