#include <termios.h>
#include <unistd.h>
#include <errno.h>
#include <errno_private.h>
int
tcgetattr(int fd, struct termios *termios)
{
return ioctl(fd, TCGETA, termios);
}
int
tcsetattr(int fd, int opt, const struct termios *termios)
{
int method;
switch (opt) {
case TCSANOW:
method = TCSETA;
break;
case TCSADRAIN:
method = TCSETAW;
break;
case TCSAFLUSH:
method = TCSETAF;
break;
default:
__set_errno(EINVAL);
return -1;
}
return ioctl(fd, method, termios);
}
int
tcdrain(int fd)
{
return ioctl(fd, TCSBRK, 1);
}
int
tcflow(int fd, int action)
{
switch (action) {
case TCIOFF:
case TCION:
case TCOOFF:
case TCOON:
break;
default:
__set_errno(EINVAL);
return -1;
}
return ioctl(fd, TCXONC, action);
}
int
tcflush(int fd, int queueSelector)
{
return ioctl(fd, TCFLSH, queueSelector);
}
int
tcsendbreak(int fd, int duration)
{
return ioctl(fd, TCSBRK, 0);
}
speed_t
cfgetispeed(const struct termios *termios)
{
if ((termios->c_cflag & CBAUD) == CBAUD)
return termios->c_ispeed + ((uint32_t)termios->c_ispeed_high << 16);
return termios->c_cflag & CBAUD;
}
int
cfsetispeed(struct termios *termios, speed_t speed)
{
if (speed > B31250) {
termios->c_cflag |= CBAUD;
termios->c_ispeed = speed & 0xFFFF;
termios->c_ispeed_high = speed >> 16;
return 0;
}
termios->c_cflag &= ~CBAUD;
termios->c_cflag |= speed;
return 0;
}
speed_t
cfgetospeed(const struct termios *termios)
{
if ((termios->c_cflag & CBAUD) == CBAUD)
return termios->c_ospeed + ((uint32_t)termios->c_ospeed_high << 16);
return termios->c_cflag & CBAUD;
}
int
cfsetospeed(struct termios *termios, speed_t speed)
{
if (speed > B31250) {
termios->c_cflag |= CBAUD;
termios->c_ospeed = speed & 0xFFFF;
termios->c_ospeed_high = speed >> 16;
return 0;
}
termios->c_cflag &= ~CBAUD;
termios->c_cflag |= speed;
return 0;
}
void
cfmakeraw(struct termios *termios)
{
termios->c_iflag &= ~(IGNBRK | BRKINT | PARMRK | ISTRIP | INLCR | IGNCR
| ICRNL | IXON);
termios->c_oflag &= ~OPOST;
termios->c_lflag &= ~(ECHO | ECHONL | ICANON | ISIG | IEXTEN);
termios->c_cflag &= ~(CSIZE | PARENB);
termios->c_cflag |= CS8;
termios->c_cc[VMIN] = 1;
termios->c_cc[VTIME] = 0;
}
pid_t
tcgetsid(int fd)
{
int sid;
if (ioctl(fd, TIOCGSID, &sid) == 0)
return sid;
return -1;
}
int
tcsetsid(int fd, pid_t pid)
{
if (pid != getsid(0)) {
errno = EINVAL;
return -1;
}
return ioctl(fd, TIOCSCTTY, NULL);
}
int
tcgetwinsize(int fd, struct winsize* winsize)
{
return ioctl(fd, TIOCGWINSZ, winsize, sizeof(*winsize));
}
int
tcsetwinsize(int fd, const struct winsize* winsize)
{
return ioctl(fd, TIOCSWINSZ, winsize, sizeof(*winsize));
}