1 /* 2 * Copyright (C) 2008 The Android Open Source Project 3 * All rights reserved. 4 * 5 * Redistribution and use in source and binary forms, with or without 6 * modification, are permitted provided that the following conditions 7 * are met: 8 * * Redistributions of source code must retain the above copyright 9 * notice, this list of conditions and the following disclaimer. 10 * * Redistributions in binary form must reproduce the above copyright 11 * notice, this list of conditions and the following disclaimer in 12 * the documentation and/or other materials provided with the 13 * distribution. 14 * 15 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 16 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 17 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS 18 * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE 19 * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, 20 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, 21 * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS 22 * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED 23 * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, 24 * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT 25 * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 26 * SUCH DAMAGE. 27 */ 28 29 #include <errno.h> 30 #include <termios.h> 31 #include <unistd.h> 32 33 static speed_t cfgetspeed(const termios* s) { 34 return (s->c_cflag & CBAUD); 35 } 36 37 speed_t cfgetispeed(const termios* s) { 38 return cfgetspeed(s); 39 } 40 41 speed_t cfgetospeed(const termios* s) { 42 return cfgetspeed(s); 43 } 44 45 void cfmakeraw(termios* s) { 46 s->c_iflag &= ~(IGNBRK|BRKINT|PARMRK|ISTRIP|INLCR|IGNCR|ICRNL|IXON); 47 s->c_oflag &= ~OPOST; 48 s->c_lflag &= ~(ECHO|ECHONL|ICANON|ISIG|IEXTEN); 49 s->c_cflag &= ~(CSIZE|PARENB); 50 s->c_cflag |= CS8; 51 } 52 53 int cfsetispeed(termios* s, speed_t speed) { 54 return cfsetspeed(s, speed); 55 } 56 57 int cfsetospeed(termios* s, speed_t speed) { 58 return cfsetspeed(s, speed); 59 } 60 61 int cfsetspeed(termios* s, speed_t speed) { 62 // TODO: check 'speed' is valid. 63 s->c_cflag = (s->c_cflag & ~CBAUD) | (speed & CBAUD); 64 return 0; 65 } 66 67 int tcdrain(int fd) { 68 // A non-zero argument to TCSBRK means "don't send a break". 69 // The drain is a side-effect of the ioctl! 70 return ioctl(fd, TCSBRK, static_cast<unsigned long>(1)); 71 } 72 73 int tcflow(int fd, int action) { 74 return ioctl(fd, TCXONC, static_cast<unsigned long>(action)); 75 } 76 77 int tcflush(int fd, int queue) { 78 return ioctl(fd, TCFLSH, static_cast<unsigned long>(queue)); 79 } 80 81 int tcgetattr(int fd, termios* s) { 82 return ioctl(fd, TCGETS, s); 83 } 84 85 pid_t tcgetsid(int fd) { 86 pid_t sid; 87 if (ioctl(fd, TIOCGSID, &sid) == -1) { 88 return -1; 89 } 90 return sid; 91 } 92 93 int tcsendbreak(int fd, int duration) { 94 return ioctl(fd, TCSBRKP, static_cast<unsigned long>(duration)); 95 } 96 97 int tcsetattr(int fd, int optional_actions, const termios* s) { 98 int cmd; 99 switch (optional_actions) { 100 case TCSANOW: cmd = TCSETS; break; 101 case TCSADRAIN: cmd = TCSETSW; break; 102 case TCSAFLUSH: cmd = TCSETSF; break; 103 default: errno = EINVAL; return -1; 104 } 105 return ioctl(fd, cmd, s); 106 } 107 108 pid_t tcgetpgrp(int fd) { 109 pid_t pid; 110 if (ioctl(fd, TIOCGPGRP, &pid) == -1) { 111 return -1; 112 } 113 return pid; 114 } 115 116 int tcsetpgrp(int fd, pid_t pid) { 117 return ioctl(fd, TIOCSPGRP, &pid); 118 } 119