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