iImplement chunked write to the cmdfd. - st - Simple Terminal Err gopher.r-36.net 70 i Err gopher.r-36.net 70 1Log /scm/st//log.gph gopher.r-36.net 70 1Files /scm/st//files.gph gopher.r-36.net 70 1Refs /scm/st//refs.gph gopher.r-36.net 70 1README /scm/st//file/README.gph gopher.r-36.net 70 1LICENSE /scm/st//file/LICENSE.gph gopher.r-36.net 70 i--- Err gopher.r-36.net 70 1commit 261ea4b7e0b8d979c0c91ec75251c6970caf39e2 /scm/st//commit/261ea4b7e0b8d979c0c91ec75251c6970caf39e2.gph gopher.r-36.net 70 1parent f8c6e7d0419d10c1425cb2c7123c5798ffb3b942 /scm/st//commit/f8c6e7d0419d10c1425cb2c7123c5798ffb3b942.gph gopher.r-36.net 70 hAuthor: Christoph Lohmann <20h@r-36.net> URL:mailto:20h@r-36.net gopher.r-36.net 70 iDate: Fri, 10 Jul 2015 14:15:39 +0200 Err gopher.r-36.net 70 i Err gopher.r-36.net 70 iImplement chunked write to the cmdfd. Err gopher.r-36.net 70 i Err gopher.r-36.net 70 iThis is needed so big input like a paste of several megabyte does not clog our Err gopher.r-36.net 70 iI/O. Err gopher.r-36.net 70 i Err gopher.r-36.net 70 iDiffstat: Err gopher.r-36.net 70 i st.c | 53 +++++++++++++++++++++++++++++-- Err gopher.r-36.net 70 i Err gopher.r-36.net 70 i1 file changed, 51 insertions(+), 2 deletions(-) Err gopher.r-36.net 70 i--- Err gopher.r-36.net 70 1diff --git a/st.c b/st.c /scm/st//file/st.c.gph gopher.r-36.net 70 i@@ -1478,8 +1478,57 @@ ttyread(void) Err gopher.r-36.net 70 i void Err gopher.r-36.net 70 i tttywrite(const char *s, size_t n) Err gopher.r-36.net 70 i { Err gopher.r-36.net 70 i- if (xwrite(cmdfd, s, n) == -1) Err gopher.r-36.net 70 i- die("write error on tty: %s\n", strerror(errno)); Err gopher.r-36.net 70 i+ fd_set wfd; Err gopher.r-36.net 70 i+ struct timespec tv; Err gopher.r-36.net 70 i+ ssize_t r; Err gopher.r-36.net 70 i+ Err gopher.r-36.net 70 i+ /* Err gopher.r-36.net 70 i+ * Remember that we are using a pty, which might be a modem line. Err gopher.r-36.net 70 i+ * Writing too much will clog the line. That's why we are doing this Err gopher.r-36.net 70 i+ * dance. Err gopher.r-36.net 70 i+ * FIXME: Migrate the world to Plan 9. Err gopher.r-36.net 70 i+ */ Err gopher.r-36.net 70 i+ while (n > 0) { Err gopher.r-36.net 70 i+ FD_ZERO(&wfd); Err gopher.r-36.net 70 i+ FD_SET(cmdfd, &wfd); Err gopher.r-36.net 70 i+ tv.tv_sec = 0; Err gopher.r-36.net 70 i+ tv.tv_nsec = 0; Err gopher.r-36.net 70 i+ Err gopher.r-36.net 70 i+ /* Check if we can write. */ Err gopher.r-36.net 70 i+ if (pselect(cmdfd+1, NULL, &wfd, NULL, &tv, NULL) < 0) { Err gopher.r-36.net 70 i+ if (errno == EINTR) Err gopher.r-36.net 70 i+ continue; Err gopher.r-36.net 70 i+ die("select failed: %s\n", strerror(errno)); Err gopher.r-36.net 70 i+ } Err gopher.r-36.net 70 i+ if(!FD_ISSET(cmdfd, &wfd)) { Err gopher.r-36.net 70 i+ /* No, then free some buffer space. */ Err gopher.r-36.net 70 i+ ttyread(); Err gopher.r-36.net 70 i+ } else { Err gopher.r-36.net 70 i+ /* Err gopher.r-36.net 70 i+ * Only write 256 bytes at maximum. This seems to be a Err gopher.r-36.net 70 i+ * reasonable value for a serial line. Bigger values Err gopher.r-36.net 70 i+ * might clog the I/O. Err gopher.r-36.net 70 i+ */ Err gopher.r-36.net 70 i+ r = write(cmdfd, s, (n < 256)? n : 256); Err gopher.r-36.net 70 i+ if (r < 0) { Err gopher.r-36.net 70 i+ die("write error on tty: %s\n", Err gopher.r-36.net 70 i+ strerror(errno)); Err gopher.r-36.net 70 i+ } Err gopher.r-36.net 70 i+ if (r < n) { Err gopher.r-36.net 70 i+ /* Err gopher.r-36.net 70 i+ * We weren't able to write out everything. Err gopher.r-36.net 70 i+ * This means the buffer is getting full Err gopher.r-36.net 70 i+ * again. Empty it. Err gopher.r-36.net 70 i+ */ Err gopher.r-36.net 70 i+ ttyread(); Err gopher.r-36.net 70 i+ n -= r; Err gopher.r-36.net 70 i+ s += r; Err gopher.r-36.net 70 i+ } else { Err gopher.r-36.net 70 i+ /* All bytes have been written. */ Err gopher.r-36.net 70 i+ break; Err gopher.r-36.net 70 i+ } Err gopher.r-36.net 70 i+ } Err gopher.r-36.net 70 i+ } Err gopher.r-36.net 70 i } Err gopher.r-36.net 70 i Err gopher.r-36.net 70 i void Err gopher.r-36.net 70 .