diff options
Diffstat (limited to 'view.c')
-rw-r--r-- | view.c | 79 |
1 files changed, 79 insertions, 0 deletions
diff --git a/view.c b/view.c new file mode 100644 index 0000000..ca7f206 --- /dev/null +++ b/view.c @@ -0,0 +1,79 @@ +/* Copyright (c) 2018, Curtis McEnroe <programble@gmail.com> + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see <http://www.gnu.org/licenses/>. + */ + +#include <err.h> +#include <fcntl.h> +#include <signal.h> +#include <stdio.h> +#include <stdlib.h> +#include <sys/ioctl.h> +#include <sysexits.h> +#include <unistd.h> + +static struct { + int read; + int write; +} winch; + +static void sigwinch() { + struct winsize localWindow; + int error = ioctl(STDERR_FILENO, TIOCGWINSZ, &localWindow); + if (error) err(EX_IOERR, "ioctl(%d, TIOCGWINSZ, ...)", STDERR_FILENO); + + ssize_t size = write(winch.write, &localWindow, sizeof(localWindow)); + if (size < 0) err(EX_IOERR, "write(%d)", winch.write); + if ((size_t)size < sizeof(localWindow)) { + errx(EX_IOERR, "short write(%d)", winch.write); + } +} + +int main(int argc, char *argv[]) { + if (argc < 2) return EX_USAGE; + const char *path = argv[1]; + + int fd = open(path, O_RDONLY); + if (fd < 0) err(EX_NOINPUT, "%s", path); + + struct winsize remoteWindow; + ssize_t size = read(fd, &remoteWindow, sizeof(remoteWindow)); + if (size < 0) err(EX_IOERR, "%s", path); + if ((size_t)size < sizeof(remoteWindow)) errx(EX_IOERR, "%s: short read", path); + + int error = pipe((int *)&winch); + if (error) err(EX_OSERR, "pipe"); + + signal(SIGWINCH, sigwinch); + sigwinch(); + for (;;) { + struct winsize localWindow; + ssize_t size = read(winch.read, &localWindow, sizeof(localWindow)); + if (size < 0) err(EX_IOERR, "read(%d)", winch.read); + if ((size_t)size < sizeof(localWindow)) { + errx(EX_IOERR, "short read(%d)", winch.read); + } + + if ( + localWindow.ws_col == remoteWindow.ws_col + && localWindow.ws_row == remoteWindow.ws_row + ) break; + + printf( + "%hux%hu -> %hux%hu\n", + localWindow.ws_col, localWindow.ws_row, + remoteWindow.ws_col, remoteWindow.ws_row + ); + } +} |