Package: ttyrec Version: 1:1.0.8-4 Severity: normal Tag: patch If using ttyplay -p to peek at a live shell session, you may occasionally see it print:
fread: Success Followed by possibly, some garbage. I have been able to reproduce this problem about 4 times in 2 days. Typing a lot of fast little shell commands seems the best way. If you have trouble reproducing the problem, you can simulate it by modifying ttyrec to sleep(1) between write_header and fwrite. The problem occurs if ttyread is reading from the last record, which is in the process of being written to the file. That write is not atomic, so it's possible for the header to be written to the file, and read by ttyread, before the payload gets written. (It may also be possible for a partial payload, or even a partial header to be seen by ttyread.) When this happens, the fread will reach EOF and return 0. One approach to fix the problem might be to make ttyplay use a single fwrite to write both the header and the record payload. Then it would make only one write() system call, and the chances of a partial write being seen would be lower. However, maybe still not zero? Up to the kernel. My approach is to have ttyread record the starting file position before it reads the header. Then when it notices EOF, it can rewind back to before that read, so it will work next time it's called. -- System Information: Debian Release: squeeze/sid APT prefers unstable APT policy: (500, 'unstable'), (500, 'testing'), (500, 'stable') Architecture: i386 (i686) Kernel: Linux 2.6.31-1-686 (SMP w/2 CPU cores) Locale: LANG=en_US.UTF-8, LC_CTYPE=en_US.UTF-8 (charmap=UTF-8) Shell: /bin/sh linked to /bin/bash Versions of packages ttyrec depends on: ii libc6 2.10.2-2 GNU C Library: Shared libraries ttyrec recommends no packages. ttyrec suggests no packages. -- debconf-show failed -- see shy jo
diff --git a/ttyplay.c b/ttyplay.c index 787dfa9..f62168d 100644 --- a/ttyplay.c +++ b/ttyplay.c @@ -142,8 +142,14 @@ ttynowait (struct timeval prev, struct timeval cur, double speed) int ttyread (FILE *fp, Header *h, char **buf) { + fpos_t pos; + int can_seek=0; + if (fgetpos(fp, &pos) == 0) { + can_seek=1; + } + if (read_header(fp, h) == 0) { - return 0; + goto err; } *buf = malloc(h->len); @@ -152,9 +158,21 @@ ttyread (FILE *fp, Header *h, char **buf) } if (fread(*buf, 1, h->len, fp) == 0) { - perror("fread"); + goto err; } return 1; + +err: + if (feof(fp)) { + /* Short read. Seek back to before header, to set up for retry. */ + if (can_seek) { + fsetpos(fp, &pos); + } + } + else { + perror("fread"); + } + return 0; } int
signature.asc
Description: Digital signature