From c5c8d1190fba74f692d156d9bdb037bf97d5c5d1 Mon Sep 17 00:00:00 2001 From: Erich Gubler Date: Thu, 28 May 2020 19:47:14 -0600 Subject: [PATCH] BREAKING CHANGE: feat(lib): skip forward when relative forward seeks are specified on non-seekable streams This is technically a breaking change, since the data and behavior of `Input` is exposed publicly. However, it seems unlikely to me that clients actually depended on a failure in the case that's being changed. --- src/input.rs | 39 ++++++++++++++++++++++++++++----------- 1 file changed, 28 insertions(+), 11 deletions(-) diff --git a/src/input.rs b/src/input.rs index 9d8268d..1e6fb06 100644 --- a/src/input.rs +++ b/src/input.rs @@ -1,5 +1,6 @@ +use std::convert::TryFrom; use std::fs; -use std::io::{self, Read, Seek, SeekFrom}; +use std::io::{self, copy, sink, Read, Seek, SeekFrom}; pub enum Input<'a> { File(fs::File), @@ -17,23 +18,39 @@ impl<'a> Read for Input<'a> { impl<'a> Seek for Input<'a> { fn seek(&mut self, pos: SeekFrom) -> io::Result { + fn try_skip(reader: R, pos: SeekFrom, err_desc: &'static str) -> io::Result + where + R: Read, + { + let cant_seek_abs_err = || Err(io::Error::new(io::ErrorKind::Other, err_desc)); + + let offset = match pos { + SeekFrom::Current(o) => u64::try_from(o).or_else(|_e| cant_seek_abs_err())?, + SeekFrom::Start(_) | SeekFrom::End(_) => cant_seek_abs_err()?, + }; + + copy(&mut reader.take(offset), &mut sink()) + } + match *self { Input::File(ref mut file) => { let seek_res = file.seek(pos); if let Err(Some(libc::ESPIPE)) = seek_res.as_ref().map_err(|err| err.raw_os_error()) { - return Err(io::Error::new( - io::ErrorKind::Other, - "Using '--seek' is not supported when using a pipe", + try_skip( + file, + pos, + "Pipes only support seeking forward with a relative offset", ) - .into()); - }; - seek_res + } else { + seek_res + } } - Input::Stdin(_) => Err(io::Error::new( - io::ErrorKind::Other, - "Using '--seek' is not supported when reading from STDIN", - )), + Input::Stdin(ref mut stdin) => try_skip( + stdin, + pos, + "STDIN only supports seeking forward with a relative offset", + ), } } }