diff options
author | Guy Harris <guy@alum.mit.edu> | 2012-06-05 07:24:17 +0000 |
---|---|---|
committer | Guy Harris <guy@alum.mit.edu> | 2012-06-05 07:24:17 +0000 |
commit | 7ed3d0e959c466d46c2e8328c9cfa553c09ccd56 (patch) | |
tree | 2a1c0404eaa9aa7c48da222653f4843be9508508 /wiretap/file_wrappers.c | |
parent | 9fe3d4b4f356084e8631a972e0217f02e344ff3e (diff) |
From Jakub Zawadzki: when seeking backwards, if the seek will put you at
a position that's in our data buffer, just reposition within the
buffer, don't do any seeks or I/O on the underlying file. This lets us
do some backwards seeking on a pipe, to allow the rewind-and-try scheme
we use to try to identify capture file types to work, at least for some
capture file formats (those that have magic numbers at the beginning or
have heuristics that don't require much data), on pipes, allowing, for
example, TShark to read those formats from a pipe.
svn path=/trunk/; revision=43102
Diffstat (limited to 'wiretap/file_wrappers.c')
-rw-r--r-- | wiretap/file_wrappers.c | 14 |
1 files changed, 13 insertions, 1 deletions
diff --git a/wiretap/file_wrappers.c b/wiretap/file_wrappers.c index 96ca7d603f..443bd5ce6d 100644 --- a/wiretap/file_wrappers.c +++ b/wiretap/file_wrappers.c @@ -920,6 +920,16 @@ file_seek(FILE_T file, gint64 offset, int whence, int *err) offset += file->skip; file->seek = 0; + if (offset < 0 && file->next) { + ptrdiff_t had = file->next - file->out; + if (-offset <= had) { + file->have -= offset; + file->next += offset; + file->pos += offset; + return file->pos; + } + } + /* XXX, profile */ if ((here = fast_seek_find(file, file->pos + offset)) && (offset < 0 || offset > SPAN || here->compression == UNCOMPRESSED)) { gint64 off, off2; @@ -1003,7 +1013,9 @@ file_seek(FILE_T file, gint64 offset, int whence, int *err) } /* if within raw area while reading, just go there */ - if (file->compression == UNCOMPRESSED && file->pos + offset >= file->raw) { + if (file->compression == UNCOMPRESSED && file->pos + offset >= file->raw + && (offset < 0 || offset >= file->have) /* seek only when we don't have that offset in buffer */) + { if (ws_lseek64(file->fd, offset - file->have, SEEK_CUR) == -1) { *err = errno; return -1; |