From 4fa1ec95ac2c6efb7d042af48df30d34011c8c01 Mon Sep 17 00:00:00 2001 From: Giacomo Tesio Date: Fri, 22 Dec 2017 00:04:13 +0100 Subject: [PATCH] jehanne: draft ioctl handling of TIOCGWINSZ and TIOCSWINSZ --- newlib/libc/sys/jehanne/ioctl.c | 85 +++++++++++++++++++++++++++++ newlib/libc/sys/jehanne/sys/ioctl.h | 11 ++++ 2 files changed, 96 insertions(+) diff --git a/newlib/libc/sys/jehanne/ioctl.c b/newlib/libc/sys/jehanne/ioctl.c index eec8832dd..a1cf3b481 100644 --- a/newlib/libc/sys/jehanne/ioctl.c +++ b/newlib/libc/sys/jehanne/ioctl.c @@ -17,13 +17,98 @@ */ #include #include +#include #include #include #include +#include +void +tty_getsize(struct winsize *size) +{ + char *var; + + var = jehanne_getenv("LINES"); + if(var != nil){ + size->ws_row = (unsigned short)atoi(var); + free(var); + } else { + size->ws_row = 0; + } + var = jehanne_getenv("COLS"); + if(var != nil){ + size->ws_col = (unsigned short)atoi(var); + free(var); + } else { + size->ws_row = 0; + } + var = jehanne_getenv("XPIXELS"); + if(var != nil){ + size->ws_xpixel = (unsigned short)atoi(var); + free(var); + } else { + size->ws_row = 0; + } + var = jehanne_getenv("YPIXELS"); + if(var != nil){ + size->ws_ypixel = (unsigned short)atoi(var); + free(var); + } else { + size->ws_row = 0; + } +} +int +tty_setsize(struct winsize *size) +{ + int fd, i, s, w, h; + char buf[64]; + struct winsize old; + + if(size->ws_xpixel && size->ws_ypixel){ +PixelSized: + fd = open("/dev/wctl", OWRITE); + if(fd < 0) + return 0; + i = snprint(buf, sizeof(buf), "resize -dx %su -dy %su", size->ws_xpixel, size->ws_ypixel); + write(fd, buf, i); + close(fd); + return 1; + } + if(size->ws_row && size->ws_col){ + tty_getsize(&old); + s = old.ws_xpixel / old.ws_col; + size->ws_xpixel = (s + 1)*size->ws_col; + s = old.ws_ypixel / old.ws_row; + size->ws_ypixel = (s + 1)*size->ws_row; + goto PixelSized; + } + return 0; +} int ioctl(int fd, int request, ...) { + va_list ap; + void *parg; + + int *errnop = &_REENT->_errno; + if(!POSIX_isatty(errnop, fd)) + return -1; + + va_start(ap, request); + switch(request){ + case TIOCGWINSZ: + parg = va_arg(ap, void*); + tty_getsize(parg); + break; + case TIOCSWINSZ: + parg = va_arg(ap, void*); + if(!tty_setsize(parg)) + *errnop = EPERM; + break; + default: + break; + } + va_end(ap); // blatant lie return 0; } diff --git a/newlib/libc/sys/jehanne/sys/ioctl.h b/newlib/libc/sys/jehanne/sys/ioctl.h index a1359cfb2..4ffa4a822 100644 --- a/newlib/libc/sys/jehanne/sys/ioctl.h +++ b/newlib/libc/sys/jehanne/sys/ioctl.h @@ -18,6 +18,17 @@ #ifndef _SYS_IOCTL_H #define _SYS_IOCTL_H +#define TIOCGWINSZ 1 +#define TIOCSWINSZ 2 + +struct winsize { + unsigned short ws_row; + unsigned short ws_col; + unsigned short ws_xpixel; /* unused */ + unsigned short ws_ypixel; /* unused */ +}; + + int ioctl(int fd, int request, ...); #endif