summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJakob Kaivo <jkk@ung.org>2020-08-15 12:33:24 -0400
committerJakob Kaivo <jkk@ung.org>2020-08-15 12:33:24 -0400
commit661977b6f44652cf7d14c38e4b888c51e399cdd4 (patch)
tree792cf5c284cc9f90c0f662b503a928164314b5f0
parent05f52c10c527ce911a2880b4ddd4c9ee299172a8 (diff)
sadly Linux-specific implementation
-rw-r--r--src/termios/_termios.h61
-rw-r--r--src/termios/tcdrain.c3
-rw-r--r--src/termios/tcflow.c4
-rw-r--r--src/termios/tcflush.c5
-rw-r--r--src/termios/tcgetattr.c10
-rw-r--r--src/termios/tcgetsid.c7
-rw-r--r--src/termios/tcsendbreak.c4
-rw-r--r--src/termios/tcsetattr.c28
8 files changed, 110 insertions, 12 deletions
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 <termios.h>
+#include <string.h>
+
+#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 <termios.h>
+#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 <termios.h>
+#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 <termios.h>
+#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 <termios.h>
+#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 <termios.h>
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 <termios.h>
+#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 <termios.h>
+#include <errno.h>
+#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)