diff options
author | Rob Landley <rob@landley.net> | 2019-05-11 02:34:29 -0500 |
---|---|---|
committer | Rob Landley <rob@landley.net> | 2019-05-11 02:34:29 -0500 |
commit | 706477ba3d7f12b48089a0d2ac3785f7652b4ef2 (patch) | |
tree | 79c6b2cf5d6d53daec3a4ef8133e64dba7b9efcc /lib | |
parent | 4ed8782eddfa0faf52ec5c273559166840fec776 (diff) | |
download | toybox-706477ba3d7f12b48089a0d2ac3785f7652b4ef2.tar.gz |
Teach tar to extract type 'S' sparse file headers.
Diffstat (limited to 'lib')
-rw-r--r-- | lib/lib.h | 2 | ||||
-rw-r--r-- | lib/xwrap.c | 21 |
2 files changed, 13 insertions, 10 deletions
@@ -234,7 +234,7 @@ void loopfiles_rw(char **argv, int flags, int permissions, void (*function)(int fd, char *name)); void loopfiles(char **argv, void (*function)(int fd, char *name)); void loopfiles_lines(char **argv, void (*function)(char **pline, long len)); -long long sendfile_len(int in, int out, long long len); +long long sendfile_len(int in, int out, long long len, long long *consumed); long long xsendfile_len(int in, int out, long long len); void xsendfile_pad(int in, int out, long long len); long long xsendfile(int in, int out); diff --git a/lib/xwrap.c b/lib/xwrap.c index a242cd53..e4f8f013 100644 --- a/lib/xwrap.c +++ b/lib/xwrap.c @@ -805,20 +805,22 @@ void xpidfile(char *name) } // Return bytes copied from in to out. If bytes <0 copy all of in to out. -long long sendfile_len(int in, int out, long long bytes) +// If consuemd isn't null, amount read saved there (return is written or error) +long long sendfile_len(int in, int out, long long bytes, long long *consumed) { - long long total = 0; - long len; + long long total = 0, len; + if (consumed) *consumed = 0; if (in<0) return 0; - for (;;) { - if (bytes == total) break; + while (bytes != total) { len = bytes-total; if (bytes<0 || len>sizeof(libbuf)) len = sizeof(libbuf); - len = xread(in, libbuf, len); + len = read(in, libbuf, len); + if (!len && errno==EAGAIN) continue; if (len<1) break; - xwrite(out, libbuf, len); + if (consumed) *consumed += len; + if (writeall(out, libbuf, len) != len) return -1; total += len; } @@ -828,9 +830,10 @@ long long sendfile_len(int in, int out, long long bytes) // error_exit if we couldn't copy all bytes long long xsendfile_len(int in, int out, long long bytes) { - long long len = sendfile_len(in, out, bytes); + long long len = sendfile_len(in, out, bytes, 0); - if (bytes != -1 && bytes != len) error_exit("short file"); + if (bytes != -1 && bytes != len) + error_exit("short %s", (len<0) ? "write" : "read"); return len; } |