Serenity Operating System
at master 157 lines 3.0 kB view raw
1/* 2 * Copyright (c) 2018-2020, Andreas Kling <kling@serenityos.org> 3 * 4 * SPDX-License-Identifier: BSD-2-Clause 5 */ 6 7#include <assert.h> 8#include <bits/pthread_cancel.h> 9#include <errno.h> 10#include <sys/ioctl.h> 11#include <termios.h> 12 13extern "C" { 14 15int tcgetattr(int fd, struct termios* t) 16{ 17 return ioctl(fd, TCGETS, t); 18} 19 20int tcsetattr(int fd, int optional_actions, const struct termios* t) 21{ 22 switch (optional_actions) { 23 case TCSANOW: 24 return ioctl(fd, TCSETS, t); 25 case TCSADRAIN: 26 return ioctl(fd, TCSETSW, t); 27 case TCSAFLUSH: 28 return ioctl(fd, TCSETSF, t); 29 } 30 errno = EINVAL; 31 return -1; 32} 33 34// https://pubs.opengroup.org/onlinepubs/009695399/functions/tcsendbreak.html 35int tcsendbreak([[maybe_unused]] int fd, [[maybe_unused]] int duration) 36{ 37 // FIXME: Implement this for real. 38 return 0; 39} 40 41int tcflow([[maybe_unused]] int fd, [[maybe_unused]] int action) 42{ 43 errno = EINVAL; 44 return -1; 45} 46 47int tcflush(int fd, int queue_selector) 48{ 49 return ioctl(fd, TCFLSH, queue_selector); 50} 51 52// https://pubs.opengroup.org/onlinepubs/009695399/functions/tcdrain.html 53int tcdrain([[maybe_unused]] int fd) 54{ 55 __pthread_maybe_cancel(); 56 57 // FIXME: Implement this for real. 58 return 0; 59} 60 61speed_t cfgetispeed(const struct termios* tp) 62{ 63 return tp->c_ispeed; 64} 65 66speed_t cfgetospeed(const struct termios* tp) 67{ 68 return tp->c_ospeed; 69} 70 71static int baud_rate_from_speed(speed_t speed) 72{ 73 int rate = -EINVAL; 74 switch (speed) { 75 case B0: 76 rate = 0; 77 break; 78 case B50: 79 rate = 50; 80 break; 81 case B75: 82 rate = 75; 83 break; 84 case B110: 85 rate = 110; 86 break; 87 case B134: 88 rate = 134; 89 break; 90 case B150: 91 rate = 150; 92 break; 93 case B200: 94 rate = 200; 95 break; 96 case B300: 97 rate = 300; 98 break; 99 case B600: 100 rate = 600; 101 break; 102 case B1200: 103 rate = 1200; 104 break; 105 case B1800: 106 rate = 1800; 107 break; 108 case B2400: 109 rate = 2400; 110 break; 111 case B4800: 112 rate = 4800; 113 break; 114 case B9600: 115 rate = 9600; 116 break; 117 case B19200: 118 rate = 19200; 119 break; 120 case B38400: 121 rate = 38400; 122 break; 123 } 124 125 return rate; 126} 127 128int cfsetispeed(struct termios* tp, speed_t speed) 129{ 130 auto ispeed = baud_rate_from_speed(speed); 131 if (ispeed > 0) { 132 tp->c_ispeed = ispeed; 133 } 134 __RETURN_WITH_ERRNO(ispeed, 0, -1); 135} 136 137int cfsetospeed(struct termios* tp, speed_t speed) 138{ 139 auto ospeed = baud_rate_from_speed(speed); 140 if (ospeed > 0) { 141 tp->c_ispeed = ospeed; 142 } 143 __RETURN_WITH_ERRNO(ospeed, 0, -1); 144} 145 146void cfmakeraw(struct termios* tp) 147{ 148 if (!tp) 149 return; 150 151 auto& termios = *tp; 152 termios.c_iflag &= ~(IGNBRK | BRKINT | PARMRK | ISTRIP | INLCR | IGNCR | ICRNL | IXON); 153 termios.c_lflag &= ~OPOST; 154 termios.c_cflag &= ~(ECHO | ECHONL | ICANON | ISIG | IEXTEN); 155 termios.c_cflag |= CS8; 156} 157}