diff options
-rw-r--r-- | .gitignore | 1 | ||||
-rw-r--r-- | Makefile | 2 | ||||
-rw-r--r-- | view.c | 79 |
3 files changed, 81 insertions, 1 deletions
diff --git a/.gitignore b/.gitignore index 6b7d5f4..18271b1 100644 --- a/.gitignore +++ b/.gitignore @@ -1,2 +1,3 @@ broadcast tags +view diff --git a/Makefile b/Makefile index a80fc35..b6c3d8d 100644 --- a/Makefile +++ b/Makefile @@ -1,4 +1,4 @@ -BINS = broadcast +BINS = broadcast view CFLAGS += -Wall -Wextra -Wpedantic LDLIBS = -lutil 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 + ); + } +} |