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 33static speed_t cfgetspeed(const termios* s) { 34 return (s->c_cflag & CBAUD); 35} 36 37speed_t cfgetispeed(const termios* s) { 38 return cfgetspeed(s); 39} 40 41speed_t cfgetospeed(const termios* s) { 42 return cfgetspeed(s); 43} 44 45void 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 53int cfsetispeed(termios* s, speed_t speed) { 54 return cfsetspeed(s, speed); 55} 56 57int cfsetospeed(termios* s, speed_t speed) { 58 return cfsetspeed(s, speed); 59} 60 61int 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 67int 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 73int tcflow(int fd, int action) { 74 return ioctl(fd, TCXONC, static_cast<unsigned long>(action)); 75} 76 77int tcflush(int fd, int queue) { 78 return ioctl(fd, TCFLSH, static_cast<unsigned long>(queue)); 79} 80 81int tcgetattr(int fd, termios* s) { 82 return ioctl(fd, TCGETS, s); 83} 84 85pid_t tcgetsid(int fd) { 86 pid_t sid; 87 if (ioctl(fd, TIOCGSID, &sid) == -1) { 88 return -1; 89 } 90 return sid; 91} 92 93int tcsendbreak(int fd, int duration) { 94 return ioctl(fd, TCSBRKP, static_cast<unsigned long>(duration)); 95} 96 97int 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 108pid_t tcgetpgrp(int fd) { 109 pid_t pid; 110 if (ioctl(fd, TIOCGPGRP, &pid) == -1) { 111 return -1; 112 } 113 return pid; 114} 115 116int tcsetpgrp(int fd, pid_t pid) { 117 return ioctl(fd, TIOCSPGRP, &pid); 118} 119