From 84debb883ad3b9c5c6aa1c671c06209f8e9ac312 Mon Sep 17 00:00:00 2001 From: Curtis McEnroe Date: Thu, 22 Feb 2018 00:03:23 -0500 Subject: Handle truncation in view --- view.c | 66 ++++++++++++++++++++++++++++++++++++++++++++++++------------------ 1 file changed, 48 insertions(+), 18 deletions(-) diff --git a/view.c b/view.c index d7ca456..732aeca 100644 --- a/view.c +++ b/view.c @@ -18,8 +18,10 @@ #include #include #include +#include #include #include +#include #include #include #include @@ -47,6 +49,13 @@ static void sigwinch() { } } +static struct winsize remoteWindow; +static void readRemoteWindow(int remote) { + ssize_t size = read(remote, &remoteWindow, sizeof(remoteWindow)); + if (size < 0) err(EX_IOERR, "read(%d)", remote); + if ((size_t)size < sizeof(remoteWindow)) errx(EX_IOERR, "short read(%d)", remote); +} + int main(int argc, char *argv[]) { int error; @@ -65,27 +74,35 @@ int main(int argc, char *argv[]) { error = tcsetattr(local, TCSADRAIN, &term); if (error) err(EX_IOERR, "tcsetattr"); - int remote = open(path, O_RDONLY); - if (remote < 0) err(EX_NOINPUT, "%s", path); - - struct winsize remoteWindow; - ssize_t size = read(remote, &remoteWindow, sizeof(remoteWindow)); - if (size < 0) err(EX_IOERR, "%s", path); - if ((size_t)size < sizeof(remoteWindow)) errx(EX_IOERR, "%s: short read", path); - error = pipe((int *)&winch); if (error) err(EX_OSERR, "pipe"); signal(SIGWINCH, sigwinch); sigwinch(); - char buf[4096]; - struct pollfd fds[3] = { - { .fd = winch.read, .events = POLLIN }, - { .fd = input, .events = POLLIN }, - { .fd = remote, .events = POLLIN }, + int remote = open(path, O_RDONLY); + if (remote < 0) err(EX_NOINPUT, "%s", path); + readRemoteWindow(remote); + + int kq = kqueue(); + if (kq < 0) err(EX_OSERR, "kqueue"); + + struct kevent events[3] = { + { .ident = winch.read, .filter = EVFILT_READ, .flags = EV_ADD }, + { .ident = input, .filter = EVFILT_READ, .flags = EV_ADD }, + { .ident = remote, .filter = EVFILT_READ, .flags = EV_ADD }, }; - while (0 < poll(fds, 3, -1)) { - if (fds[0].revents) { + int nevents = kevent(kq, events, 3, NULL, 0, NULL); + if (nevents < 0) err(EX_OSERR, "kevent"); + + char buf[4096]; + bool truncated = false; + for (;;) { + struct kevent event; + int nevents = kevent(kq, NULL, 0, &event, 1, NULL); + if (nevents < 0) err(EX_OSERR, "kevent"); + if (!nevents) continue; + + if (event.ident == (uintptr_t)winch.read) { for (;;) { struct winsize localWindow; ssize_t size = read(winch.read, &localWindow, sizeof(localWindow)); @@ -107,13 +124,27 @@ int main(int argc, char *argv[]) { } } - if (fds[1].revents) { + if (event.ident == (uintptr_t)input) { ssize_t size = read(input, buf, sizeof(buf)); if (size < 0) err(EX_IOERR, "read(%d)", input); if (size == 1 && buf[0] == 'q') return EX_OK; } - if (fds[2].revents) { + if (event.ident == (uintptr_t)remote) { + if (event.data < 0) { + off_t offset = lseek(remote, 0, SEEK_SET); + if (offset < 0) err(EX_IOERR, "lseek(%d)", remote); + truncated = true; + continue; + } + + if (truncated) { + readRemoteWindow(remote); + sigwinch(); + truncated = false; + continue; + } + ssize_t readSize = read(remote, buf, sizeof(buf)); if (readSize < 0) err(EX_IOERR, "read(%d)", remote); @@ -122,5 +153,4 @@ int main(int argc, char *argv[]) { if (writeSize < readSize) errx(EX_IOERR, "short write(%d)", local); } } - err(EX_IOERR, "poll"); } -- cgit 1.4.1 tls: Revert accidentally(?) reverted upstream 3.4.2June McEnroe 2021-11-29Import LibreSSL 3.4.2June McEnroe 2021-10-14Import LibreSSL 3.4.1June McEnroe 2021-09-17Import LibreSSL 3.4.0June McEnroe 2021-08-24Import LibreSSL 3.3.4June McEnroe 2021-05-25Bump version to 3.3.3p1 3.3.3p1June McEnroe 2021-05-25build: Add scripts to EXTRA_DISTJune McEnroe 2021-05-25import: Add missing scripts/wrap-compiler-for-flag-checkJune McEnroe 2021-05-08Import LibreSSL 3.3.3June McEnroe 2021-04-18build: Remove added x509_verify.3 links 3.3.2June McEnroe 2021-04-18tls: Use EC_KEY_set_ex_dataJune McEnroe 2021-04-18Import LibreSSL 3.3.2June McEnroe 2021-03-05Bump version to 3.3.1p1 3.3.1p1June McEnroe 2021-03-05build: Add OpenSSL includes to libcompatJune McEnroe Some compat sources (getentropy_linux.c for example) require OpenSSL. Reported by Robert Scheck. 2020-12-15Import LibreSSL 3.3.1June McEnroe 2020-11-24Import LibreSSL 3.3.0June McEnroe 2020-10-22Import LibreSSL 3.2.2June McEnroe 2020-09-29Import LibreSSL 3.2.1June McEnroe 2020-09-29import: Add m4/ax_add_fortify_source.m4June McEnroe 2020-08-05build: Add README.7 to EXTRA_DIST 3.2.0June McEnroe 2020-08-03doc: Indicate that only OpenSSL 1.1.1b and newer workJune McEnroe