# st

Unnamed repository; edit this file 'description' to name the repository.

| Log | Files | Refs | README | LICENSE

    commit 261ea4b7e0b8d979c0c91ec75251c6970caf39e2
    parent f8c6e7d0419d10c1425cb2c7123c5798ffb3b942
    Author: Christoph Lohmann <20h@r-36.net>
    Date:   Fri, 10 Jul 2015 14:15:39 +0200

    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:
    Mst.c | 53+++++++++++++++++++++++++++++++++++++++++++++++++++--

    1 file changed, 51 insertions(+), 2 deletions(-)
    diff --git a/st.c b/st.c
    @@ -1478,8 +1478,57 @@ ttyread(void)
     void
     ttywrite(const char *s, size_t n)
     {
    -	if (xwrite(cmdfd, s, n) == -1)
    -		die("write error on tty: %s\n", strerror(errno));
    +	fd_set wfd;
    +	struct timespec tv;
    +	ssize_t r;
    +
    +	/*
    +	 * Remember that we are using a pty, which might be a modem line.
    +	 * Writing too much will clog the line. That's why we are doing this
    +	 * dance.
    +	 * FIXME: Migrate the world to Plan 9.
    +	 */
    +	while (n > 0) {
    +		FD_ZERO(&wfd);
    +		FD_SET(cmdfd, &wfd);
    +		tv.tv_sec = 0;
    +		tv.tv_nsec = 0;
    +
    +		/* Check if we can write. */
    +		if (pselect(cmdfd+1, NULL, &wfd, NULL, &tv, NULL) < 0) {
    +			if (errno == EINTR)
    +				continue;
    +			die("select failed: %s\n", strerror(errno));
    +		}
    +		if(!FD_ISSET(cmdfd, &wfd)) {
    +			/* No, then free some buffer space. */
    +			ttyread();
    +		} else {
    +			/*
    +			 * Only write 256 bytes at maximum. This seems to be a
    +			 * reasonable value for a serial line. Bigger values
    +			 * might clog the I/O.
    +			 */
    +			r = write(cmdfd, s, (n < 256)? n : 256);
    +			if (r < 0) {
    +				die("write error on tty: %s\n",
    +						strerror(errno));
    +			}
    +			if (r < n) {
    +				/*
    +				 * We weren't able to write out everything.
    +				 * This means the buffer is getting full
    +				 * again. Empty it.
    +				 */
    +				ttyread();
    +				n -= r;
    +				s += r;
    +			} else {
    +				/* All bytes have been written. */
    +				break;
    +			}
    +		}
    +	}
     }

     void