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);
+ }
+}