Michael Forney wrote:
> On Fri, Feb 3, 2017 at 9:35 AM, willy <[email protected]> wrote:
> > Willy Gfn wrote:
> >> Hello,
> >>
> >> The attached patch makes tar read again from a pipe in case less bytes
> >> are read than expected.
> >> This prevent a bug where it fails to extract files correctly because
> >> not enough bytes are read from, eg, a pipe hooked to a decompression
> >> program.
> >
> > Just realised there is a bug in my patch. We should only keep reading
> > if read() returns more than 0 bytes, otherwise the functions returns.
> >
> > Updated patch attached.
> 
> If there is EINTR, s will be decremented by 1 incorrectly since r will
> be -1. I think you need to move s += r to after the if (r < 0). But, I
> don't think you could even get EINTR since tar doesn't set any signal
> handlers. Maybe there is some case I don't know about though.

Here is an updated patch for it. I prefer keeping the EINTR check for
now. It doesn't harm, and in case signal handling is added someday,
this function will be ready for it.
diff --git a/tar.c b/tar.c
index 4a81f8f..35aba55 100644
--- a/tar.c
+++ b/tar.c
@@ -155,16 +155,22 @@ decomp(int fd, const char *tool, const char *flags)
 static ssize_t
 eread(int fd, void *buf, size_t n)
 {
-       ssize_t r;
+       char *tmp = buf;
+       ssize_t r, s = 0;
 
 again:
-       r = read(fd, buf, n);
+       r = read(fd, tmp + s, n - s);
        if (r < 0) {
-               if (errno == EINTR)
+               if (errno == EINTR || errno == EAGAIN)
                        goto again;
                eprintf("read:");
        }
-       return r;
+
+       s += r;
+       if (r && s < n)
+               goto again;
+
+       return s;
 }
 
 static ssize_t

Reply via email to