aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRoberto E. Vargas Caballero <k0ga@shike2.com>2015-11-06 20:01:00 +0100
committerRoberto E. Vargas Caballero <k0ga@shike2.com>2015-11-06 20:01:00 +0100
commit9f6d8845df3f81e2bc86f593a2f93e098422b2fa (patch)
treec6eaaddfdd96da5d61126abf8314d92b92ec0fa0
parentf0398db4d172e838ef4b4ae55db3fb6a6fee6717 (diff)
downloadst-patched-9f6d8845df3f81e2bc86f593a2f93e098422b2fa.tar.bz2
st-patched-9f6d8845df3f81e2bc86f593a2f93e098422b2fa.tar.xz
st-patched-9f6d8845df3f81e2bc86f593a2f93e098422b2fa.zip
Fix ttywrite()
ttywrite was assuming that if it could not write then it could read, but this is not necessarily true, there are some situations where you cannot read or write. The correct behaviour is to detect if you can read or/and write.
-rw-r--r--st.c38
1 files changed, 20 insertions, 18 deletions
diff --git a/st.c b/st.c
index 65a1866..900534b 100644
--- a/st.c
+++ b/st.c
@@ -415,7 +415,7 @@ static int32_t tdefcolor(int *, int *, int);
415static void tdeftran(char); 415static void tdeftran(char);
416static inline int match(uint, uint); 416static inline int match(uint, uint);
417static void ttynew(void); 417static void ttynew(void);
418static void ttyread(void); 418static size_t ttyread(void);
419static void ttyresize(void); 419static void ttyresize(void);
420static void ttysend(char *, size_t); 420static void ttysend(char *, size_t);
421static void ttywrite(const char *, size_t); 421static void ttywrite(const char *, size_t);
@@ -1464,7 +1464,7 @@ ttynew(void)
1464 } 1464 }
1465} 1465}
1466 1466
1467void 1467size_t
1468ttyread(void) 1468ttyread(void)
1469{ 1469{
1470 static char buf[BUFSIZ]; 1470 static char buf[BUFSIZ];
@@ -1489,14 +1489,16 @@ ttyread(void)
1489 1489
1490 /* keep any uncomplete utf8 char for the next call */ 1490 /* keep any uncomplete utf8 char for the next call */
1491 memmove(buf, ptr, buflen); 1491 memmove(buf, ptr, buflen);
1492
1493 return ret;
1492} 1494}
1493 1495
1494void 1496void
1495ttywrite(const char *s, size_t n) 1497ttywrite(const char *s, size_t n)
1496{ 1498{
1497 fd_set wfd; 1499 fd_set wfd, rfd;
1498 struct timespec tv;
1499 ssize_t r; 1500 ssize_t r;
1501 size_t lim = 256;
1500 1502
1501 /* 1503 /*
1502 * Remember that we are using a pty, which might be a modem line. 1504 * Remember that we are using a pty, which might be a modem line.
@@ -1506,38 +1508,34 @@ ttywrite(const char *s, size_t n)
1506 */ 1508 */
1507 while (n > 0) { 1509 while (n > 0) {
1508 FD_ZERO(&wfd); 1510 FD_ZERO(&wfd);
1511 FD_ZERO(&rfd);
1509 FD_SET(cmdfd, &wfd); 1512 FD_SET(cmdfd, &wfd);
1510 tv.tv_sec = 0; 1513 FD_SET(cmdfd, &rfd);
1511 tv.tv_nsec = 0;
1512 1514
1513 /* Check if we can write. */ 1515 /* Check if we can write. */
1514 if (pselect(cmdfd+1, NULL, &wfd, NULL, &tv, NULL) < 0) { 1516 if (pselect(cmdfd+1, &rfd, &wfd, NULL, NULL, NULL) < 0) {
1515 if (errno == EINTR) 1517 if (errno == EINTR)
1516 continue; 1518 continue;
1517 die("select failed: %s\n", strerror(errno)); 1519 die("select failed: %s\n", strerror(errno));
1518 } 1520 }
1519 if(!FD_ISSET(cmdfd, &wfd)) { 1521 if (FD_ISSET(cmdfd, &rfd))
1520 /* No, then free some buffer space. */ 1522 lim = ttyread();
1521 ttyread(); 1523 if (FD_ISSET(cmdfd, &wfd)) {
1522 } else {
1523 /* 1524 /*
1524 * Only write 256 bytes at maximum. This seems to be a 1525 * Only write 256 bytes at maximum. This seems to be a
1525 * reasonable value for a serial line. Bigger values 1526 * reasonable value for a serial line. Bigger values
1526 * might clog the I/O. 1527 * might clog the I/O.
1527 */ 1528 */
1528 r = write(cmdfd, s, (n < 256)? n : 256); 1529 if ((r = write(cmdfd, s, (n < 256)? n : 256)) < 0)
1529 if (r < 0) { 1530 goto write_error;
1530 die("write error on tty: %s\n",
1531 strerror(errno));
1532 }
1533 if (r < n) { 1531 if (r < n) {
1534 /* 1532 /*
1535 * We weren't able to write out everything. 1533 * We weren't able to write out everything.
1536 * This means the buffer is getting full 1534 * This means the buffer is getting full
1537 * again. Empty it. 1535 * again. Empty it.
1538 */ 1536 */
1539 if (n < 256) 1537 if (n < lim)
1540 ttyread(); 1538 lim = ttyread();
1541 n -= r; 1539 n -= r;
1542 s += r; 1540 s += r;
1543 } else { 1541 } else {
@@ -1546,6 +1544,10 @@ ttywrite(const char *s, size_t n)
1546 } 1544 }
1547 } 1545 }
1548 } 1546 }
1547 return;
1548
1549write_error:
1550 die("write error on tty: %s\n", strerror(errno));
1549} 1551}
1550 1552
1551void 1553void