From dcb8bef3ed7b3adcdb54fcd0cd5a4065091019a7 Mon Sep 17 00:00:00 2001 From: coast Date: Sat, 10 Oct 2026 22:13:10 +0330 Subject: init --- src/term.c | 120 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 120 insertions(+) create mode 100644 src/term.c (limited to 'src/term.c') diff --git a/src/term.c b/src/term.c new file mode 100644 index 0000000..dda5f65 --- /dev/null +++ b/src/term.c @@ -0,0 +1,120 @@ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +static struct termios saved; +static int active = 0; +static volatile sig_atomic_t stopped = 0; + +static void on_signal(int sig) +{ + (void)sig; + stopped = 1; +} + +int zm_enter(void) +{ + struct termios t; + if (tcgetattr(STDIN_FILENO, &saved) != 0) + return -1; + t = saved; + t.c_lflag &= ~(tcflag_t)(ISIG | ICANON | ECHO); + t.c_cc[VMIN] = 0; + t.c_cc[VTIME] = 0; + if (tcsetattr(STDIN_FILENO, TCSANOW, &t) != 0) + return -1; + active = 1; + return 0; +} + +void zm_leave(void) +{ + if (active) { + tcsetattr(STDIN_FILENO, TCSAFLUSH, &saved); + active = 0; + } +} + +void zm_install(int lock) +{ + struct sigaction handle; + struct sigaction ignore; + memset(&handle, 0, sizeof handle); + memset(&ignore, 0, sizeof ignore); + handle.sa_handler = on_signal; + ignore.sa_handler = SIG_IGN; + sigemptyset(&handle.sa_mask); + sigemptyset(&ignore.sa_mask); + sigaction(SIGTERM, &handle, NULL); + sigaction(SIGHUP, &handle, NULL); + sigaction(SIGINT, lock ? &ignore : &handle, NULL); +} + +int zm_stopped(void) +{ + return stopped ? 1 : 0; +} + +int zm_size(int *rows, int *cols) +{ + struct winsize ws; + memset(&ws, 0, sizeof ws); + if (ioctl(STDOUT_FILENO, TIOCGWINSZ, &ws) != 0 || ws.ws_row == 0 || ws.ws_col == 0) { + memset(&ws, 0, sizeof ws); + if (ioctl(STDIN_FILENO, TIOCGWINSZ, &ws) != 0 || ws.ws_row == 0 || ws.ws_col == 0) + return -1; + } + *rows = (int)ws.ws_row; + *cols = (int)ws.ws_col; + return 0; +} + +int zm_wait(int ms) +{ + struct pollfd p; + int r; + p.fd = STDIN_FILENO; + p.events = POLLIN; + p.revents = 0; + r = poll(&p, 1, ms); + return (r > 0 && (p.revents & POLLIN)) ? 1 : 0; +} + +ssize_t zm_read(unsigned char *buf, size_t n) +{ + return read(STDIN_FILENO, buf, n); +} + +void zm_write(int fd, const unsigned char *buf, size_t n) +{ + size_t off = 0; + while (off < n) { + ssize_t r = write(fd, buf + off, n - off); + if (r < 0) { + if (errno == EINTR || errno == EAGAIN) + continue; + return; + } + off += (size_t)r; + } +} + +unsigned long long zm_seed(void) +{ + struct timespec ts; + unsigned long long a; + unsigned long long b; + unsigned long long p; + clock_gettime(CLOCK_REALTIME, &ts); + a = (unsigned long long)ts.tv_sec; + b = (unsigned long long)ts.tv_nsec; + p = (unsigned long long)getpid(); + return (a * 1000000007ULL) ^ b ^ (p << 32); +} -- cgit v1.3