ttyrex

ttyrec with more options
git clone https://a3nm.net/git/ttyrex/
Log | Files | Refs | README

commit 851ea67da115a4d8b30eeebf59b8a4247854f418
parent b1d49c1a66d383fe03893e155c24068c8434241d
Author: Antoine Amarilli <a3nm@a3nm.net>
Date:   Wed,  3 Oct 2012 00:56:16 +0200

make things work

Diffstat:
ttyrec | 0
ttyrec.c | 157+++++++++++++++++++++++++++++++++++++++++++++++--------------------------------
2 files changed, 93 insertions(+), 64 deletions(-)

diff --git a/ttyrec b/ttyrec Binary files differ. diff --git a/ttyrec.c b/ttyrec.c @@ -89,7 +89,6 @@ #endif /* SVR4 && ! CDEL */ void done(void); -void dofail(void); void fail(void); void fixtty(void); void getmaster(void); @@ -97,6 +96,8 @@ void getslave(void); void doinput(void); void dooutput(void); void doshell(const char*); +void spawnshell(); +void dowrites(Header, int, char*); char *shell; FILE *fscript; @@ -139,7 +140,7 @@ main(argc, argv) void finish(); char *getenv(); - while ((ch = getopt(argc, argv, "aue:h?")) != EOF) + while ((ch = getopt(argc, argv, "auefl:h?")) != EOF) switch((char)ch) { case 'a': aflg++; @@ -152,6 +153,7 @@ main(argc, argv) break; case 'l': limit = atoi(optarg); + printf("limit %d\n", limit); break; case 'f': force = 1; @@ -169,44 +171,45 @@ main(argc, argv) fname = argv[0]; else fname = "ttyrecord"; - if ((fscript = fopen(fname, aflg ? "a" : "w")) == NULL) { - if (!force) perror(fname); - fail(); - } - setbuf(fscript, NULL); shell = getenv("SHELL"); if (shell == NULL) shell = "/bin/sh"; - getmaster(); - fixtty(); + if ((fscript = fopen(fname, aflg ? "a" : "w")) == NULL) { + if (!force) perror(fname); + fail(); + } + setbuf(fscript, NULL); + + getmaster(); + fixtty(); sigemptyset(&sa.sa_mask); sa.sa_flags = 0; sa.sa_handler = finish; sigaction(SIGCHLD, &sa, NULL); - child = fork(); - if (child < 0) { - if (!force) perror("fork"); - fail(); - } - if (child == 0) { - subchild = child = fork(); - if (child < 0) { - if (!force) perror("fork"); - fail(); - } - if (child) { - sa.sa_flags = SA_RESTART; - sigaction(SIGCHLD, &sa, NULL); - dooutput(); - } else - doshell(command); - } - sa.sa_handler = resize; - sa.sa_flags = SA_RESTART; - sigaction(SIGWINCH, &sa, NULL); + child = fork(); + if (child < 0) { + if (!force) perror("fork"); + fail(); + } + if (child == 0) { + subchild = child = fork(); + if (child < 0) { + if (!force) perror("fork"); + fail(); + } + if (child) { + sa.sa_flags = SA_RESTART; + sigaction(SIGCHLD, &sa, NULL); + dooutput(); + } else + doshell(command); + } + sa.sa_handler = resize; + sa.sa_flags = SA_RESTART; + sigaction(SIGWINCH, &sa, NULL); doinput(); return 0; @@ -319,12 +322,24 @@ check_output(char *str, int len) } void +dowrites(Header h, int cc, char *obuf) { + if ((cc = check_output(obuf, cc))) { + (void) write_header(fscript, &h); + (void) fwrite(obuf, 1, cc, fscript); + } +} + +void dooutput() { int cc; + int lcc = 0; char obuf[BUFSIZ]; - time_t lastsec; - int readsec; + char lobuf[BUFSIZ]; + time_t lastsec = 0; + int readsec = 0; + Header h; + Header lh; setbuf(stdout, NULL); (void) close(0); @@ -332,33 +347,42 @@ dooutput() (void) close(slave); #endif for (;;) { - Header h; cc = read(master, obuf, BUFSIZ); - if (cc <= 0) + if (cc <= 0) { + if (lcc) { + // do the last chunk of ignored data + dowrites(lh, lcc, lobuf); + lcc = 0; + } break; + } if (uflg) uu_check_output(obuf, cc); h.len = cc; gettimeofday(&h.tv, NULL); + (void) write(1, obuf, cc); if (limit) { if (h.tv.tv_sec == lastsec) { - if (readsec >= limit) + if (readsec >= limit) { + // TODO: avoid this by cycling between two buffers + strncpy(lobuf, obuf, BUFSIZ); + lcc = cc; + lh = h; continue; - readsec += cc; - if (readsec > limit) { - cc -= readsec - limit; } + readsec += cc; } else { + if (lcc) { + // do the last chunk of ignored data + dowrites(lh, lcc, lobuf); + lcc = 0; + } lastsec = h.tv.tv_sec; readsec = cc; } } - (void) write(1, obuf, cc); - if ((cc = check_output(obuf, cc))) { - (void) write_header(fscript, &h); - (void) fwrite(obuf, 1, cc, fscript); - } + dowrites(h, cc, obuf); } done(); } @@ -383,13 +407,9 @@ doshell(const char* command) (void) dup2(slave, 2); (void) close(slave); - if (!command) { - execl(shell, strrchr(shell, '/') + 1, "-i", NULL); - } else { - execl(shell, strrchr(shell, '/') + 1, "-c", command, NULL); - } + spawnshell(); perror(shell); - dofail(); + fail(); } void @@ -419,20 +439,17 @@ fixtty() } void -dofail() +fail() { + if (force) { + spawnshell(); + perror(shell); + } (void) kill(0, SIGTERM); done(); } void -fail() -{ - if (force) doshell(command); - dofail(); -} - -void done() { if (subchild) { @@ -451,7 +468,7 @@ getmaster() (void) tcgetattr(0, &tt); (void) ioctl(0, TIOCGWINSZ, (char *)&win); if ((master = open("/dev/ptmx", O_RDWR)) < 0) { - perror("open(\"/dev/ptmx\", O_RDWR)"); + if (!force) perror("open(\"/dev/ptmx\", O_RDWR)"); fail(); } #else /* !SVR4 */ @@ -465,7 +482,7 @@ getmaster() #else #ifdef HAVE_getpt if ((master = getpt()) < 0) { - perror("getpt()"); + if (!force) perror("getpt()"); fail(); } #else @@ -514,21 +531,21 @@ getslave() grantpt( master); unlockpt(master); if ((slave = open((const char *)ptsname(master), O_RDWR)) < 0) { - perror("open(fd, O_RDWR)"); + if (!force) perror("open(fd, O_RDWR)"); fail(); } if (isastream(slave)) { if (ioctl(slave, I_PUSH, "ptem") < 0) { - perror("ioctl(fd, I_PUSH, ptem)"); + if (!force) perror("ioctl(fd, I_PUSH, ptem)"); fail(); } if (ioctl(slave, I_PUSH, "ldterm") < 0) { - perror("ioctl(fd, I_PUSH, ldterm)"); + if (!force) perror("ioctl(fd, I_PUSH, ldterm)"); fail(); } #ifndef _HPUX_SOURCE if (ioctl(slave, I_PUSH, "ttcompat") < 0) { - perror("ioctl(fd, I_PUSH, ttcompat)"); + if (!force) perror("ioctl(fd, I_PUSH, ttcompat)"); fail(); } #endif @@ -541,7 +558,7 @@ getslave() line[strlen("/dev/")] = 't'; slave = open(line, O_RDWR); if (slave < 0) { - perror(line); + if (!force) perror(line); fail(); } (void) tcsetattr(slave, TCSAFLUSH, &tt); @@ -551,3 +568,15 @@ getslave() (void) ioctl(slave, TIOCSCTTY, 0); #endif /* SVR4 */ } + +void +spawnshell() +{ + force = 0; + + if (!command) { + execl(shell, strrchr(shell, '/') + 1, "-i", NULL); + } else { + execl(shell, strrchr(shell, '/') + 1, "-c", command, NULL); + } +}