aboutsummaryrefslogtreecommitdiff
path: root/st.c
diff options
context:
space:
mode:
authorChristoph Lohmann <20h@r-36.net>2015-07-10 14:15:39 +0200
committerChristoph Lohmann <20h@r-36.net>2015-07-10 14:15:39 +0200
commit261ea4b7e0b8d979c0c91ec75251c6970caf39e2 (patch)
tree4d4cfe54652d8e7460cc85b67f2d368c71eeafbb /st.c
parentf8c6e7d0419d10c1425cb2c7123c5798ffb3b942 (diff)
downloadst-261ea4b7e0b8d979c0c91ec75251c6970caf39e2.tar.gz
st-261ea4b7e0b8d979c0c91ec75251c6970caf39e2.zip
Implement chunked write to the cmdfd.
This is needed so big input like a paste of several megabyte does not clog our I/O.
Diffstat (limited to 'st.c')
-rw-r--r--st.c53
1 files changed, 51 insertions, 2 deletions
diff --git a/st.c b/st.c
index 17e0a65..e65e981 100644
--- a/st.c
+++ b/st.c
@@ -1478,8 +1478,57 @@ ttyread(void)
1478void 1478void
1479ttywrite(const char *s, size_t n) 1479ttywrite(const char *s, size_t n)
1480{ 1480{
1481 if (xwrite(cmdfd, s, n) == -1) 1481 fd_set wfd;
1482 die("write error on tty: %s\n", strerror(errno)); 1482 struct timespec tv;
1483 ssize_t r;
1484
1485 /*
1486 * Remember that we are using a pty, which might be a modem line.
1487 * Writing too much will clog the line. That's why we are doing this
1488 * dance.
1489 * FIXME: Migrate the world to Plan 9.
1490 */
1491 while (n > 0) {
1492 FD_ZERO(&wfd);
1493 FD_SET(cmdfd, &wfd);
1494 tv.tv_sec = 0;
1495 tv.tv_nsec = 0;
1496
1497 /* Check if we can write. */
1498 if (pselect(cmdfd+1, NULL, &wfd, NULL, &tv, NULL) < 0) {
1499 if (errno == EINTR)
1500 continue;
1501 die("select failed: %s\n", strerror(errno));
1502 }
1503 if(!FD_ISSET(cmdfd, &wfd)) {
1504 /* No, then free some buffer space. */
1505 ttyread();
1506 } else {
1507 /*
1508 * Only write 256 bytes at maximum. This seems to be a
1509 * reasonable value for a serial line. Bigger values
1510 * might clog the I/O.
1511 */
1512 r = write(cmdfd, s, (n < 256)? n : 256);
1513 if (r < 0) {
1514 die("write error on tty: %s\n",
1515 strerror(errno));
1516 }
1517 if (r < n) {
1518 /*
1519 * We weren't able to write out everything.
1520 * This means the buffer is getting full
1521 * again. Empty it.
1522 */
1523 ttyread();
1524 n -= r;
1525 s += r;
1526 } else {
1527 /* All bytes have been written. */
1528 break;
1529 }
1530 }
1531 }
1483} 1532}
1484 1533
1485void 1534void