This is the mail archive of the
cygwin-apps
mailing list for the Cygwin project.
[PATCH 6/6] Handle short reads in archive_tar_file::read()
- From: Jon TURNEY <jon dot turney at dronecode dot org dot uk>
- To: cygwin-apps at cygwin dot com
- Cc: Jon TURNEY <jon dot turney at dronecode dot org dot uk>
- Date: Fri, 8 Apr 2011 15:43:52 +0100
- Subject: [PATCH 6/6] Handle short reads in archive_tar_file::read()
- References: <4D9492BD.6020103@redhat.com> <1302273832-432-1-git-send-email-jon.turney@dronecode.org.uk>
archive_tar_file::read() currently considers any short read an error.
These can now occur if the underlying bz2 compressed io_stream starts a
new compression stream in the middle of the read
It also transparently reads to the next 512-byte block in the parent
io_stream after reading all the data expected for a file.
Teach it to do things correctly, even if a short read occurs.
2011-04-08 Jon TURNEY <jon.turney@dronecode.org.uk>
* archive_tar_file.cc (read): Handle short reads
Signed-off-by: Jon TURNEY <jon.turney@dronecode.org.uk>
---
archive_tar_file.cc | 52 +++++++++++++++++++++++++++++++++-----------------
1 files changed, 34 insertions(+), 18 deletions(-)
diff --git a/archive_tar_file.cc b/archive_tar_file.cc
index 5ffb3a1..9a1721b 100644
--- a/archive_tar_file.cc
+++ b/archive_tar_file.cc
@@ -49,24 +49,40 @@ ssize_t archive_tar_file::read (void *buffer, size_t len)
read_something = true;
if (want)
{
- ssize_t
- got = state.parent->read (buffer, want);
- char
- throwaway[512];
- ssize_t
- got2 = state.parent->read (throwaway, roundup);
- if (got == want && got2 == roundup)
- {
- state.file_offset += got;
- return got;
- }
- else
- {
- /* unexpected EOF or read error in the tar parent stream */
- /* the user can query the parent for the error */
- state.lasterr = EIO;
- return -1;
- }
+ int need = want;
+ char *p = (char *)buffer;
+ while (need > 0)
+ {
+ ssize_t got = state.parent->read (p, need);
+ if (got <= 0)
+ {
+ /* unexpected EOF or read error in the tar parent stream */
+ /* the user can query the parent for the error */
+ state.lasterr = EIO;
+ return -1;
+ }
+ p += got;
+ need -= got;
+ }
+
+ char throwaway[512];
+ p = &throwaway[0];
+ while (roundup > 0)
+ {
+ ssize_t got2 = state.parent->read (p, roundup);
+ if (got2 <= 0)
+ {
+ /* unexpected EOF or read error in the tar parent stream */
+ /* the user can query the parent for the error */
+ state.lasterr = EIO;
+ return -1;
+ }
+ p += got2;
+ roundup -= got2;
+ }
+
+ state.file_offset += want;
+ return want;
}
return 0;
}
--
1.7.4