---
st.c | 90 +++++++++++++++++++++++++++---------------------------------
st.h | 2 ++
x.c | 10 +++++--
3 files changed, 51 insertions(+), 51 deletions(-)
diff --git a/st.c b/st.c
index 57c6e96..4fedeb8 100644
--- a/st.c
+++ b/st.c
_AT_@ -152,6 +152,12 @@ typedef struct {
int narg; /* nb of args */
} STREscape;
+typedef struct {
+ char *buf; /* allocated raw string */
+ size_t siz; /* allocation size */
+ size_t len; /* raw string length */
+} TBuffer;
+
static void execsh(char *, char **);
static void stty(char **);
static void sigchld(int);
_AT_@ -223,6 +229,7 @@ static Term term;
static Selection sel;
static CSIEscape csiescseq;
static STREscape strescseq;
+static TBuffer tbuf = { .buf = NULL, .siz = 0, .len = 0 };
static int iofd = 1;
static int cmdfd;
static pid_t pid;
_AT_@ -752,6 +759,30 @@ stty(char **args)
perror("Couldn't call stty");
}
+size_t
+tbuflen(void)
+{
+ return tbuf.len;
+}
+
+size_t
+tbufwrite(void)
+{
+ size_t lim = 256;
+ ssize_t r;
+
+ /*
+ * Migrate the world to Plan 9.
+ */
+ if ((r = write(cmdfd, &tbuf.buf[0], MIN(tbuf.len, lim))) < 0)
+ die("write error on tty: %s\n", strerror(errno));
+
+ tbuf.len -= r;
+ memmove(tbuf.buf, &tbuf.buf[r], tbuf.len);
+
+ return r;
+}
+
int
ttynew(const char *line, char *cmd, const char *out, char **args)
{
_AT_@ -868,61 +899,22 @@ ttywrite(const char *s, size_t n, int may_echo)
}
}
+
void
ttywriteraw(const char *s, size_t n)
{
- fd_set wfd, rfd;
- ssize_t r;
- size_t lim = 256;
-
- /*
- * 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_ZERO(&rfd);
- FD_SET(cmdfd, &wfd);
- FD_SET(cmdfd, &rfd);
-
- /* Check if we can write. */
- if (pselect(cmdfd+1, &rfd, &wfd, NULL, NULL, NULL) < 0) {
- if (errno == EINTR)
- continue;
- die("select failed: %s\n", strerror(errno));
- }
- if (FD_ISSET(cmdfd, &wfd)) {
- /*
- * Only write the bytes written by ttywrite() or the
- * default of 256. This seems to be a reasonable value
- * for a serial line. Bigger values might clog the I/O.
- */
- if ((r = write(cmdfd, s, (n < lim)? n : lim)) < 0)
- goto write_error;
- if (r < n) {
- /*
- * We weren't able to write out everything.
- * This means the buffer is getting full
- * again. Empty it.
- */
- if (n < lim)
- lim = ttyread();
- n -= r;
- s += r;
- } else {
- /* All bytes have been written. */
- break;
- }
- }
- if (FD_ISSET(cmdfd, &rfd))
- lim = ttyread();
+ if (tbuf.siz - tbuf.len < n) {
+ tbuf.siz = tbuf.siz ? tbuf.siz : 256;
+ while (tbuf.siz - tbuf.len < n)
+ tbuf.siz *= 2;
+ tbuf.buf = xrealloc(tbuf.buf, tbuf.siz);
}
+
+ memcpy(&tbuf.buf[tbuf.len], s, n);
+ tbuf.len += n;
+
return;
-write_error:
- die("write error on tty: %s\n", strerror(errno));
}
void
diff --git a/st.h b/st.h
index fd3b0d8..31d6fc4 100644
--- a/st.h
+++ b/st.h
_AT_@ -87,6 +87,8 @@ void sendbreak(const Arg *);
void toggleprinter(const Arg *);
int tattrset(int);
+size_t tbuflen(void);
+size_t tbufwrite(void);
void tnew(int, int);
void tresize(int, int);
void tsetdirtattr(int);
diff --git a/x.c b/x.c
index bd23686..e425ef3 100644
--- a/x.c
+++ b/x.c
_AT_@ -1922,7 +1922,7 @@ run(void)
{
XEvent ev;
int w = win.w, h = win.h;
- fd_set rfd;
+ fd_set rfd, wfd;
int xfd = XConnectionNumber(xw.dpy), ttyfd, xev, drawing;
struct timespec seltv, *tv, now, lastblink, trigger;
double timeout;
_AT_@ -1948,8 +1948,11 @@ run(void)
for (timeout = -1, drawing = 0, lastblink = (struct timespec){0};;) {
FD_ZERO(&rfd);
+ FD_ZERO(&wfd);
FD_SET(ttyfd, &rfd);
FD_SET(xfd, &rfd);
+ if (tbuflen() > 0)
+ FD_SET(ttyfd, &wfd);
if (XPending(xw.dpy))
timeout = 0; /* existing events might not set xfd */
_AT_@ -1958,7 +1961,7 @@ run(void)
seltv.tv_nsec = 1E6 * (timeout - 1E3 * seltv.tv_sec);
tv = timeout >= 0 ? &seltv : NULL;
- if (pselect(MAX(xfd, ttyfd)+1, &rfd, NULL, NULL, tv, NULL) < 0) {
+ if (pselect(MAX(xfd, ttyfd)+1, &rfd, &wfd, NULL, tv, NULL) < 0) {
if (errno == EINTR)
continue;
die("select failed: %s\n", strerror(errno));
_AT_@ -1968,6 +1971,9 @@ run(void)
if (FD_ISSET(ttyfd, &rfd))
ttyread();
+ if (FD_ISSET(ttyfd, &wfd))
+ tbufwrite();
+
xev = 0;
while (XPending(xw.dpy)) {
xev = 1;
--
2.45.2
Received on Sat Jun 29 2024 - 04:46:27 CEST
This archive was generated by hypermail 2.3.0 : Sat Jun 29 2024 - 04:48:35 CEST