From c1441910e00044d85bdb7642bc6d19cd526da5e7 Mon Sep 17 00:00:00 2001 From: Michael Krayer Date: Fri, 26 Mar 2021 11:06:51 +0100 Subject: [PATCH] scrollback buffer patch by Justin Bogner --- dtach.h | 1 + master.c | 67 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 68 insertions(+) diff --git a/dtach.h b/dtach.h index c4d39cb..6f4236c 100644 --- a/dtach.h +++ b/dtach.h @@ -122,6 +122,7 @@ struct packet ** buffer used for the text stream. */ #define BUFSIZE 4096 +#define SCROLLSIZE 8192 /* This hopefully moves to the bottom of the screen */ #define EOS "\033[999H" diff --git a/master.c b/master.c index 5c053e0..e94dd63 100644 --- a/master.c +++ b/master.c @@ -52,6 +52,9 @@ struct client static struct client *clients; /* The pseudo-terminal created for the child process. */ static struct pty the_pty; +/* The scrollback buffer */ +static unsigned char scrollback[SCROLLSIZE]; +static int scroll_end, scroll_full; #ifndef HAVE_FORKPTY pid_t forkpty(int *amaster, char *name, struct termios *termp, @@ -238,6 +241,66 @@ update_socket_modes(int exec) chmod(sockname, newmode); } +/* Write the data in *buf into the scrollback buffer */ +static void +write_scrollback(unsigned char *buf, int len) +{ + int n; + if (len > SCROLLSIZE) + { + buf = buf + (len - SCROLLSIZE); + len = SCROLLSIZE; + } + + n = SCROLLSIZE - scroll_end; + if (n >= len) + { + memcpy(scrollback + scroll_end, buf, + len * sizeof(unsigned char)); + scroll_end += len * sizeof(unsigned char); + scroll_full = 1; + } + else + { + memcpy(scrollback + scroll_end, buf, + n * sizeof(unsigned char)); + scroll_end = len - n; + memcpy(scrollback, buf, + scroll_end * sizeof(unsigned char)); + } +} + +/* Send the data in the scrollback buffer to client */ +static void +send_scrollback(struct client *p) +{ + int written, len; + if (scroll_full) + { + len = SCROLLSIZE - scroll_end; + written = 0; + while (written < len) + { + int n = write(p->fd, scrollback + scroll_end + written, + len - written); + if (n > 0) + written += n; + else if (n == 0 || errno != EINTR) + break; + } + } + len = scroll_end; + written = 0; + while (written < len) + { + int n = write(p->fd, scrollback + written, len - written); + if (n > 0) + written += n; + else if (n == 0 || errno != EINTR) + break; + } +} + /* Process activity on the pty - Input and terminal changes are sent out to ** the attached clients. If the pty goes away, we die. */ static void @@ -320,6 +383,8 @@ top: /* Try again if nothing happened. */ if (!FD_ISSET(s, &readfds) && nclients == 0) goto top; + + write_scrollback( buf, len ); } /* Process activity on the control socket */ @@ -348,6 +413,8 @@ control_activity(int s) if (p->next) p->next->pprev = &p->next; *(p->pprev) = p; + + send_scrollback( p ); } /* Process activity from a client. */