1 /* 2 * Copyright 2004-2005, Axel Dörfler, axeld@pinc-software.de. All rights reserved. 3 * Copyright 2003, Daniel Reinhold, danielre@users.sf.net. All rights reserved. 4 * 5 * Distributed under the terms of the MIT License. 6 */ 7 8 9 #include <termios.h> 10 #include <unistd.h> 11 #include <errno.h> 12 13 #include <errno_private.h> 14 15 16 /*! get the attributes of the TTY device at fd */ 17 int 18 tcgetattr(int fd, struct termios *termios) 19 { 20 return ioctl(fd, TCGETA, termios); 21 } 22 23 24 /*! set the attributes for the TTY device at fd */ 25 int 26 tcsetattr(int fd, int opt, const struct termios *termios) 27 { 28 int method; 29 30 switch (opt) { 31 case TCSANOW: 32 // set the attributes immediately 33 method = TCSETA; 34 break; 35 case TCSADRAIN: 36 // wait for ouput to finish before setting the attributes 37 method = TCSETAW; 38 break; 39 case TCSAFLUSH: 40 method = TCSETAF; 41 break; 42 43 default: 44 // no other valid options 45 __set_errno(EINVAL); 46 return -1; 47 } 48 49 return ioctl(fd, method, termios); 50 } 51 52 53 /*! wait for all output to be transmitted */ 54 int 55 tcdrain(int fd) 56 { 57 /* Some termios implementations have a TIOCDRAIN command 58 * expressly for this purpose (e.g. ioctl(fd, TIOCDRAIN, 0). 59 * However, the BeOS implementation adheres to another 60 * interface which uses a non-zero last parameter to the 61 * TCSBRK ioctl to signify this functionality. 62 */ 63 return ioctl(fd, TCSBRK, 1); 64 } 65 66 67 /*! suspend or restart transmission */ 68 int 69 tcflow(int fd, int action) 70 { 71 switch (action) { 72 case TCIOFF: 73 case TCION: 74 case TCOOFF: 75 case TCOON: 76 break; 77 78 default: 79 __set_errno(EINVAL); 80 return -1; 81 } 82 83 return ioctl(fd, TCXONC, action); 84 } 85 86 87 /*! flush all pending data (input or output) */ 88 int 89 tcflush(int fd, int queueSelector) 90 { 91 return ioctl(fd, TCFLSH, queueSelector); 92 } 93 94 95 /*! send zero bits for the specified duration */ 96 int 97 tcsendbreak(int fd, int duration) 98 { 99 // Posix spec says this should take ~ 0.25 to 0.5 seconds. 100 // As the interpretation of the duration is undefined, we'll just ignore it 101 return ioctl(fd, TCSBRK, 0); 102 } 103 104 105 speed_t 106 cfgetispeed(const struct termios *termios) 107 { 108 return termios->c_cflag & CBAUD; 109 } 110 111 112 int 113 cfsetispeed(struct termios *termios, speed_t speed) 114 { 115 /* Check for values that the system cannot handle: 116 greater values than B230400 which is 117 the maximum value defined in termios.h 118 Note that errors from hardware device are detected only 119 until the tcsetattr() function is called */ 120 if (speed > B230400 || (speed & CBAUD) != speed) { 121 __set_errno(EINVAL); 122 return -1; 123 } 124 125 termios->c_cflag &= ~CBAUD; 126 termios->c_cflag |= speed; 127 return 0; 128 } 129 130 131 speed_t 132 cfgetospeed(const struct termios *termios) 133 { 134 return termios->c_cflag & CBAUD; 135 } 136 137 138 int 139 cfsetospeed(struct termios *termios, speed_t speed) 140 { 141 /* Check for unaccepted speed values (see above) */ 142 if (speed > B230400 || (speed & CBAUD) != speed) { 143 __set_errno(EINVAL); 144 return -1; 145 } 146 147 termios->c_cflag &= ~CBAUD; 148 termios->c_cflag |= speed; 149 return 0; 150 } 151 152 153 void 154 cfmakeraw(struct termios *termios) 155 { 156 termios->c_iflag &= ~(IGNBRK | BRKINT | PARMRK | ISTRIP | INLCR | IGNCR 157 | ICRNL | IXON); 158 termios->c_oflag &= ~OPOST; 159 termios->c_lflag &= ~(ECHO | ECHONL | ICANON | ISIG | IEXTEN); 160 termios->c_cflag &= ~(CSIZE | PARENB); 161 termios->c_cflag |= CS8; 162 } 163