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.
This commit is contained in:
parent
f0398db4d1
commit
9f6d8845df
38
st.c
38
st.c
@ -415,7 +415,7 @@ static int32_t tdefcolor(int *, int *, int);
|
|||||||
static void tdeftran(char);
|
static void tdeftran(char);
|
||||||
static inline int match(uint, uint);
|
static inline int match(uint, uint);
|
||||||
static void ttynew(void);
|
static void ttynew(void);
|
||||||
static void ttyread(void);
|
static size_t ttyread(void);
|
||||||
static void ttyresize(void);
|
static void ttyresize(void);
|
||||||
static void ttysend(char *, size_t);
|
static void ttysend(char *, size_t);
|
||||||
static void ttywrite(const char *, size_t);
|
static void ttywrite(const char *, size_t);
|
||||||
@ -1464,7 +1464,7 @@ ttynew(void)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
size_t
|
||||||
ttyread(void)
|
ttyread(void)
|
||||||
{
|
{
|
||||||
static char buf[BUFSIZ];
|
static char buf[BUFSIZ];
|
||||||
@ -1489,14 +1489,16 @@ ttyread(void)
|
|||||||
|
|
||||||
/* keep any uncomplete utf8 char for the next call */
|
/* keep any uncomplete utf8 char for the next call */
|
||||||
memmove(buf, ptr, buflen);
|
memmove(buf, ptr, buflen);
|
||||||
|
|
||||||
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
ttywrite(const char *s, size_t n)
|
ttywrite(const char *s, size_t n)
|
||||||
{
|
{
|
||||||
fd_set wfd;
|
fd_set wfd, rfd;
|
||||||
struct timespec tv;
|
|
||||||
ssize_t r;
|
ssize_t r;
|
||||||
|
size_t lim = 256;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Remember that we are using a pty, which might be a modem line.
|
* Remember that we are using a pty, which might be a modem line.
|
||||||
@ -1506,38 +1508,34 @@ ttywrite(const char *s, size_t n)
|
|||||||
*/
|
*/
|
||||||
while (n > 0) {
|
while (n > 0) {
|
||||||
FD_ZERO(&wfd);
|
FD_ZERO(&wfd);
|
||||||
|
FD_ZERO(&rfd);
|
||||||
FD_SET(cmdfd, &wfd);
|
FD_SET(cmdfd, &wfd);
|
||||||
tv.tv_sec = 0;
|
FD_SET(cmdfd, &rfd);
|
||||||
tv.tv_nsec = 0;
|
|
||||||
|
|
||||||
/* Check if we can write. */
|
/* Check if we can write. */
|
||||||
if (pselect(cmdfd+1, NULL, &wfd, NULL, &tv, NULL) < 0) {
|
if (pselect(cmdfd+1, &rfd, &wfd, NULL, NULL, NULL) < 0) {
|
||||||
if (errno == EINTR)
|
if (errno == EINTR)
|
||||||
continue;
|
continue;
|
||||||
die("select failed: %s\n", strerror(errno));
|
die("select failed: %s\n", strerror(errno));
|
||||||
}
|
}
|
||||||
if(!FD_ISSET(cmdfd, &wfd)) {
|
if (FD_ISSET(cmdfd, &rfd))
|
||||||
/* No, then free some buffer space. */
|
lim = ttyread();
|
||||||
ttyread();
|
if (FD_ISSET(cmdfd, &wfd)) {
|
||||||
} else {
|
|
||||||
/*
|
/*
|
||||||
* Only write 256 bytes at maximum. This seems to be a
|
* Only write 256 bytes at maximum. This seems to be a
|
||||||
* reasonable value for a serial line. Bigger values
|
* reasonable value for a serial line. Bigger values
|
||||||
* might clog the I/O.
|
* might clog the I/O.
|
||||||
*/
|
*/
|
||||||
r = write(cmdfd, s, (n < 256)? n : 256);
|
if ((r = write(cmdfd, s, (n < 256)? n : 256)) < 0)
|
||||||
if (r < 0) {
|
goto write_error;
|
||||||
die("write error on tty: %s\n",
|
|
||||||
strerror(errno));
|
|
||||||
}
|
|
||||||
if (r < n) {
|
if (r < n) {
|
||||||
/*
|
/*
|
||||||
* We weren't able to write out everything.
|
* We weren't able to write out everything.
|
||||||
* This means the buffer is getting full
|
* This means the buffer is getting full
|
||||||
* again. Empty it.
|
* again. Empty it.
|
||||||
*/
|
*/
|
||||||
if (n < 256)
|
if (n < lim)
|
||||||
ttyread();
|
lim = ttyread();
|
||||||
n -= r;
|
n -= r;
|
||||||
s += r;
|
s += r;
|
||||||
} else {
|
} else {
|
||||||
@ -1546,6 +1544,10 @@ ttywrite(const char *s, size_t n)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
return;
|
||||||
|
|
||||||
|
write_error:
|
||||||
|
die("write error on tty: %s\n", strerror(errno));
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
|
Loading…
Reference in New Issue
Block a user