commit 6c3c9a304c570c4c3852dfb6db37e13573bdbcd7
parent 73b825713a0dd7be02a387423b032f940a5cf15f
Author: Antoine Amarilli <a3nm@a3nm.net>
Date: Wed, 3 Oct 2012 00:24:18 +0200
+debian
Diffstat:
Makefile | | | 8 | +++++++- |
io.c | | | 57 | +++++++++++++++++++-------------------------------------- |
io.h | | | 1 | + |
ttyplay.1 | | | 3 | +++ |
ttyplay.c | | | 47 | ++++++++++++++++++++++++++++++++++++++--------- |
ttyrec.1 | | | 2 | +- |
ttyrec.c | | | 68 | ++++++++++++++++++++++++++++++++++++++++++++++++++++---------------- |
7 files changed, 121 insertions(+), 65 deletions(-)
diff --git a/Makefile b/Makefile
@@ -1,7 +1,10 @@
CC = gcc
-CFLAGS = -O2
+DEFS= -DSVR4 -D_GNU_SOURCE
+CFLAGS = -O2 -g -fomit-frame-pointer -Wall $(DEFS)
VERSION = 1.0.8
+DESTDIR=
+
TARGET = ttyrec ttyplay ttytime
DIST = ttyrec.c ttyplay.c ttyrec.h io.c io.h ttytime.c\
@@ -18,6 +21,9 @@ ttyplay: ttyplay.o io.o
ttytime: ttytime.o io.o
$(CC) $(CFLAGS) -o ttytime ttytime.o io.o
+install:
+ install ttyrec ttyplay ttytime $(DESTDIR)/usr/bin
+
clean:
rm -f *.o $(TARGET) ttyrecord *~
diff --git a/io.c b/io.c
@@ -33,6 +33,8 @@
#include <assert.h>
#include <errno.h>
+#include <endian.h>
+#include <stdint.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
@@ -40,50 +42,28 @@
#include "ttyrec.h"
-#define SWAP_ENDIAN(val) ((unsigned int) ( \
- (((unsigned int) (val) & (unsigned int) 0x000000ffU) << 24) | \
- (((unsigned int) (val) & (unsigned int) 0x0000ff00U) << 8) | \
- (((unsigned int) (val) & (unsigned int) 0x00ff0000U) >> 8) | \
- (((unsigned int) (val) & (unsigned int) 0xff000000U) >> 24)))
+#define SWAP_ENDIAN(val) ((uint32_t) ( \
+ (((uint32_t) (val) & (uint32_t) 0x000000ffU) << 24) | \
+ (((uint32_t) (val) & (uint32_t) 0x0000ff00U) << 8) | \
+ (((uint32_t) (val) & (uint32_t) 0x00ff0000U) >> 8) | \
+ (((uint32_t) (val) & (uint32_t) 0xff000000U) >> 24)))
-static int
-is_little_endian ()
+static uint32_t
+convert_to_little_endian (uint32_t x)
{
- static int retval = -1;
-
- if (retval == -1) {
- int n = 1;
- char *p = (char *)&n;
- char x[] = {1, 0, 0, 0};
-
- assert(sizeof(int) == 4);
-
- if (memcmp(p, x, 4) == 0) {
- retval = 1;
- } else {
- retval = 0;
- }
- }
-
- return retval;
-}
-
-static int
-convert_to_little_endian (int x)
-{
- if (is_little_endian()) {
- return x;
- } else {
- return SWAP_ENDIAN(x);
- }
+#if BYTE_ORDER == LITTLE_ENDIAN
+ return x;
+#else
+ return SWAP_ENDIAN(x);
+#endif
}
int
read_header (FILE *fp, Header *h)
{
- int buf[3];
+ uint32_t buf[3];
- if (fread(buf, sizeof(int), 3, fp) == 0) {
+ if (fread(buf, sizeof(uint32_t), 3, fp) == 0) {
return 0;
}
@@ -97,13 +77,13 @@ read_header (FILE *fp, Header *h)
int
write_header (FILE *fp, Header *h)
{
- int buf[3];
+ uint32_t buf[3];
buf[0] = convert_to_little_endian(h->tv.tv_sec);
buf[1] = convert_to_little_endian(h->tv.tv_usec);
buf[2] = convert_to_little_endian(h->len);
- if (fwrite(buf, sizeof(int), 3, fp) == 0) {
+ if (fwrite(buf, sizeof(uint32_t), 3, fp) == 0) {
return 0;
}
@@ -158,4 +138,5 @@ efdopen (int fd, const char *mode)
fprintf(stderr, "%s: fdopen failed: %s\n", progname, strerror(errno));
exit(EXIT_FAILURE);
}
+ return fp;
}
diff --git a/io.h b/io.h
@@ -9,5 +9,6 @@ FILE* efopen (const char *path, const char *mode);
int edup (int oldfd);
int edup2 (int oldfd, int newfd);
FILE* efdopen (int fd, const char *mode);
+void set_progname (const char *name);
#endif
diff --git a/ttyplay.1 b/ttyplay.1
@@ -38,6 +38,9 @@ Additionally, there are some special keys defined:
.BI \- " or " s
halve the speed of playback.
.TP
+.BI 0
+set playback speed to 0, pausing playback.
+.TP
.BI 1
set playback to speed 1.0 again.
diff --git a/ttyplay.c b/ttyplay.c
@@ -83,16 +83,21 @@ ttywait (struct timeval prev, struct timeval cur, double speed)
static struct timeval drift = {0, 0};
struct timeval start;
struct timeval diff = timeval_diff(prev, cur);
+ struct timeval *diffp = &diff;
fd_set readfs;
gettimeofday(&start, NULL);
- assert(speed != 0);
- diff = timeval_diff(drift, timeval_div(diff, speed));
+ if (speed == 0.0)
+ diffp = NULL;
+ else
+ diff = timeval_diff(drift, timeval_div(diff, speed));
+
if (diff.tv_sec < 0) {
diff.tv_sec = diff.tv_usec = 0;
}
+ FD_ZERO(&readfs);
FD_SET(STDIN_FILENO, &readfs);
/*
* We use select() for sleeping with subsecond precision.
@@ -101,9 +106,10 @@ ttywait (struct timeval prev, struct timeval cur, double speed)
* Save "diff" since select(2) may overwrite it to {0, 0}.
*/
struct timeval orig_diff = diff;
- select(1, &readfs, NULL, NULL, &diff);
+ int r;
+ r = select(1, &readfs, NULL, NULL, diffp); /* skip if a user hits any key */
diff = orig_diff; /* Restore the original diff value. */
- if (FD_ISSET(0, &readfs)) { /* a user hits a character? */
+ if (r > 0 && FD_ISSET(0, &readfs)) { /* a user hits a character? */
char c;
read(STDIN_FILENO, &c, 1); /* drain the character */
switch (c) {
@@ -118,6 +124,9 @@ ttywait (struct timeval prev, struct timeval cur, double speed)
case '1':
speed = 1.0;
break;
+ case '0':
+ speed = 0.0;
+ break;
}
drift.tv_sec = drift.tv_usec = 0;
} else {
@@ -136,14 +145,21 @@ double
ttynowait (struct timeval prev, struct timeval cur, double speed)
{
/* do nothing */
- return 0; /* Speed isn't important. */
+ return 1.0; /* Speed isn't important. */
}
int
ttyread (FILE *fp, Header *h, char **buf)
{
+ fpos_t pos;
+ int can_seek=0;
+ if (fgetpos(fp, &pos) == 0) {
+ can_seek=1;
+ }
+ clearerr(fp);
+
if (read_header(fp, h) == 0) {
- return 0;
+ goto err;
}
*buf = malloc(h->len);
@@ -152,9 +168,21 @@ ttyread (FILE *fp, Header *h, char **buf)
}
if (fread(*buf, 1, h->len, fp) == 0) {
- perror("fread");
+ goto err;
}
return 1;
+
+err:
+ if (ferror(fp)) {
+ perror("fread");
+ }
+ else {
+ /* Short read. Seek back to before header, to set up for retry. */
+ if (can_seek) {
+ fsetpos(fp, &pos);
+ }
+ }
+ return 0;
}
int
@@ -202,7 +230,9 @@ ttyplay (FILE *fp, double speed, ReadFunc read_func,
}
if (!first_time) {
- speed = wait_func(prev, h.tv, speed);
+ do {
+ speed = wait_func(prev, h.tv, speed);
+ } while (speed == 0.0);
}
first_time = 0;
@@ -252,7 +282,6 @@ usage (void)
FILE *
input_from_stdin (void)
{
- FILE *fp;
int fd = edup(STDIN_FILENO);
edup2(STDOUT_FILENO, STDIN_FILENO);
return efdopen(fd, "r");
diff --git a/ttyrec.1 b/ttyrec.1
@@ -7,7 +7,7 @@ ttyrec \- a tty recorder
.SH SYNOPSIS
.br
.B ttyrec
-.I "[\-a][\-u] [file]"
+.I "[\-a] [\-u] [\-e command] [file]"
.br
.SH DESCRIPTION
.B Ttyrec
diff --git a/ttyrec.c b/ttyrec.c
@@ -113,11 +113,19 @@ char line[] = "/dev/ptyXX";
int aflg;
int uflg;
+static void
+resize(int dummy) {
+ /* transmit window change information to the child */
+ (void) ioctl(0, TIOCGWINSZ, (char *)&win);
+ (void) ioctl(master, TIOCSWINSZ, (char *)&win);
+}
+
int
main(argc, argv)
int argc;
char *argv[];
{
+ struct sigaction sa;
extern int optind;
int ch;
void finish();
@@ -161,7 +169,10 @@ main(argc, argv)
getmaster();
fixtty();
- (void) signal(SIGCHLD, finish);
+ sigemptyset(&sa.sa_mask);
+ sa.sa_flags = 0;
+ sa.sa_handler = finish;
+ sigaction(SIGCHLD, &sa, NULL);
child = fork();
if (child < 0) {
perror("fork");
@@ -173,11 +184,16 @@ main(argc, argv)
perror("fork");
fail();
}
- if (child)
+ if (child) {
+ sa.sa_flags = SA_RESTART;
+ sigaction(SIGCHLD, &sa, NULL);
dooutput();
- else
+ } else
doshell(command);
}
+ sa.sa_handler = resize;
+ sa.sa_flags = SA_RESTART;
+ sigaction(SIGWINCH, &sa, NULL);
doinput();
return 0;
@@ -209,14 +225,10 @@ finish()
union wait status;
#endif /* !SVR4 */
register int pid;
- register int die = 0;
while ((pid = wait3((int *)&status, WNOHANG, 0)) > 0)
if (pid == child)
- die = 1;
-
- if (die)
- done();
+ break;
}
struct linebuf {
@@ -250,8 +262,8 @@ check_line (const char *line)
}
}
-void
-check_output(const char *str, int len)
+static void
+uu_check_output(const char *str, int len)
{
static struct linebuf lbuf = {"", 0};
int i;
@@ -276,6 +288,23 @@ check_output(const char *str, int len)
}
}
+static int
+check_output(char *str, int len)
+{
+ char *p;
+
+ /* If we see query string, remove it */
+ /* ESC [ > 0 c : Send Device Attributes */
+ if (len >= 5 && (p = strstr(str, "\e[>0c")) != NULL) {
+ if (len == 5)
+ return 0;
+ memmove(p, p+5, len-5+1-(p-str));
+ return len-5;
+ }
+
+ return len;
+}
+
void
dooutput()
{
@@ -294,12 +323,14 @@ dooutput()
if (cc <= 0)
break;
if (uflg)
- check_output(obuf, cc);
+ uu_check_output(obuf, cc);
h.len = cc;
gettimeofday(&h.tv, NULL);
(void) write(1, obuf, cc);
- (void) write_header(fscript, &h);
- (void) fwrite(obuf, 1, cc, fscript);
+ if ((cc = check_output(obuf, cc))) {
+ (void) write_header(fscript, &h);
+ (void) fwrite(obuf, 1, cc, fscript);
+ }
}
done();
}
@@ -325,9 +356,9 @@ doshell(const char* command)
(void) close(slave);
if (!command) {
- execl(shell, strrchr(shell, '/') + 1, "-i", 0);
+ execl(shell, strrchr(shell, '/') + 1, "-i", NULL);
} else {
- execl(shell, strrchr(shell, '/') + 1, "-c", command, 0);
+ execl(shell, strrchr(shell, '/') + 1, "-c", command, NULL);
}
perror(shell);
fail();
@@ -340,6 +371,9 @@ fixtty()
rtt = tt;
#if defined(SVR4)
+#if !defined(XCASE)
+#define XCASE 0
+#endif
rtt.c_iflag = 0;
rtt.c_lflag &= ~(ISIG|ICANON|XCASE|ECHO|ECHOE|ECHOK|ECHONL);
rtt.c_oflag = OPOST;
@@ -464,8 +498,10 @@ getslave()
fail();
}
#endif
- (void) ioctl(0, TIOCGWINSZ, (char *)&win);
}
+ (void) tcsetattr(slave, TCSAFLUSH, &tt);
+ (void) ioctl(slave, TIOCSWINSZ, (char *)&win);
+ (void) ioctl(slave, TIOCSCTTY, 0);
#else /* !SVR4 */
#ifndef HAVE_openpty
line[strlen("/dev/")] = 't';