From 661977b6f44652cf7d14c38e4b888c51e399cdd4 Mon Sep 17 00:00:00 2001 From: Jakob Kaivo Date: Sat, 15 Aug 2020 12:33:24 -0400 Subject: sadly Linux-specific implementation --- src/termios/_termios.h | 61 +++++++++++++++++++++++++++++++++++++++++++++++ src/termios/tcdrain.c | 3 ++- src/termios/tcflow.c | 4 ++-- src/termios/tcflush.c | 5 ++-- src/termios/tcgetattr.c | 10 ++++++-- src/termios/tcgetsid.c | 7 +++++- src/termios/tcsendbreak.c | 4 ++-- src/termios/tcsetattr.c | 28 ++++++++++++++++++++-- 8 files changed, 110 insertions(+), 12 deletions(-) create mode 100644 src/termios/_termios.h (limited to 'src') diff --git a/src/termios/_termios.h b/src/termios/_termios.h new file mode 100644 index 00000000..ce35d32e --- /dev/null +++ b/src/termios/_termios.h @@ -0,0 +1,61 @@ +#ifndef ___TERMIOS_H__ +#define ___TERMIOS_H__ + +#include +#include + +#ifdef __linux__ +#include "_syscall.h" + +#define KNCCS 19 +#define MINCCS (KNCCS < NCCS ? KNCCS : NCCS) + +#define TCGETS 0x5401 +#define TCSETS 0x5402 +#define TCSETSW 0x5403 +#define TCSETSF 0x5404 +#define TCSBRK 0x5409 +#define TCSBRKP 0x5425 +#define TCXONC 0x540A +#define TCFLSH 0x540B +#define TIOCGPGRP 0x540F + +#define ioctl(_fd, _cmd, _arg) __syscall(16, _fd, _cmd, _arg) + +struct kernel_termios { + tcflag_t c_iflag; + tcflag_t c_oflag; + tcflag_t c_cflag; + tcflag_t c_lflag; + cc_t c_line; + cc_t c_cc[KNCCS]; + speed_t c_ispeed; + speed_t c_ospeed; +}; + +#define ktou(_u, _k) do { \ + (_u).c_iflag = (_k).c_iflag; \ + (_u).c_oflag = (_k).c_oflag; \ + (_u).c_cflag = (_k).c_cflag; \ + (_u).c_lflag = (_k).c_lflag; \ + memcpy((_u).c_cc, (_k).c_cc, MINCCS); \ +} while (0) + /* and the speeds */ + +#define utok(_k, _u) do { \ + (_k).c_iflag = (_u).c_iflag; \ + (_k).c_oflag = (_u).c_oflag; \ + (_k).c_cflag = (_u).c_cflag; \ + (_k).c_lflag = (_u).c_lflag; \ + (_k).c_line = 0; \ + memcpy((_k).c_cc, (_u).c_cc, MINCCS); \ +} while (0) + /* and the speeds */ + +#else +#define kernel_termios termios +#define ktou(_u, _k) (memcpy(_u, _k, sizeof(_u)) +#define utok(_k, _u) (memcpy(_k, _u, sizeof(_u)) +#endif + +#endif diff --git a/src/termios/tcdrain.c b/src/termios/tcdrain.c index a0963b83..8f117ac1 100644 --- a/src/termios/tcdrain.c +++ b/src/termios/tcdrain.c @@ -1,8 +1,9 @@ #include +#include "_termios.h" int tcdrain(int fildes) { - return fildes; + return ioctl(fildes, TCSBRK, 1); } /* POSIX(1) diff --git a/src/termios/tcflow.c b/src/termios/tcflow.c index 05898373..41fdcfbc 100644 --- a/src/termios/tcflow.c +++ b/src/termios/tcflow.c @@ -1,9 +1,9 @@ #include +#include "_termios.h" int tcflow(int fildes, int action) { - (void)fildes; - return action; + return ioctl(fildes, TCXONC, action); } /* diff --git a/src/termios/tcflush.c b/src/termios/tcflush.c index 28933528..98a89749 100644 --- a/src/termios/tcflush.c +++ b/src/termios/tcflush.c @@ -1,10 +1,11 @@ #include +#include "_termios.h" int tcflush(int fildes, int queue_selector) { - (void)queue_selector; - return fildes; + return ioctl(fildes, TCFLSH, queue_selector); } + /* POSIX(1) */ diff --git a/src/termios/tcgetattr.c b/src/termios/tcgetattr.c index f9ebe024..0f74be5c 100644 --- a/src/termios/tcgetattr.c +++ b/src/termios/tcgetattr.c @@ -1,10 +1,16 @@ #include +#include "_termios.h" int tcgetattr(int fildes, struct termios *termios_p) { - (void)termios_p; - return fildes; + int ret = -1; + struct kernel_termios kt; + utok(kt, *termios_p); + ret = ioctl(fildes, TCGETS, &kt); + ktou(*termios_p, kt); + return ret; } + /* POSIX(1) */ diff --git a/src/termios/tcgetsid.c b/src/termios/tcgetsid.c index 8b095363..2ebfb425 100644 --- a/src/termios/tcgetsid.c +++ b/src/termios/tcgetsid.c @@ -1,8 +1,13 @@ +#include "sys/types.h" #include pid_t tcgetsid(int fildes) { - return 0; + pid_t pid = -1; + if (ioctl(fildes, TIOCGPGRP, &pid) == -1) { + return (pid_t)-1; + } + return pid; } /* diff --git a/src/termios/tcsendbreak.c b/src/termios/tcsendbreak.c index 7c728aa3..fab5927e 100644 --- a/src/termios/tcsendbreak.c +++ b/src/termios/tcsendbreak.c @@ -1,9 +1,9 @@ #include +#include "_termios.h" int tcsendbreak(int fildes, int duration) { - (void)duration; - return fildes; + return ioctl(fildes, TCSBRKP, duration); } /* POSIX(1) diff --git a/src/termios/tcsetattr.c b/src/termios/tcsetattr.c index b68652ad..a40439a2 100644 --- a/src/termios/tcsetattr.c +++ b/src/termios/tcsetattr.c @@ -1,9 +1,33 @@ #include +#include +#include "_termios.h" int tcsetattr(int fildes, int optional_actions, struct termios *termios_p) { - (void)optional_actions; (void)termios_p; - return fildes; + int ret = -1; + struct kernel_termios kt; + utok(kt, *termios_p); + + switch (optional_actions) { + case TCSANOW: + ret = ioctl(fildes, TCSETS, &kt); + break; + + case TCSADRAIN: + ret = ioctl(fildes, TCSETSW, &kt); + break; + + case TCSAFLUSH: + ret = ioctl(fildes, TCSETSF, &kt); + break; + + default: + errno = EINVAL; + return -1; + } + + ktou(*termios_p, kt); + return ret; } /* POSIX(1) -- cgit v1.2.1