aboutsummaryrefslogtreecommitdiff
path: root/lib
diff options
context:
space:
mode:
authorRob Landley <rob@landley.net>2019-05-11 02:34:29 -0500
committerRob Landley <rob@landley.net>2019-05-11 02:34:29 -0500
commit706477ba3d7f12b48089a0d2ac3785f7652b4ef2 (patch)
tree79c6b2cf5d6d53daec3a4ef8133e64dba7b9efcc /lib
parent4ed8782eddfa0faf52ec5c273559166840fec776 (diff)
downloadtoybox-706477ba3d7f12b48089a0d2ac3785f7652b4ef2.tar.gz
Teach tar to extract type 'S' sparse file headers.
Diffstat (limited to 'lib')
-rw-r--r--lib/lib.h2
-rw-r--r--lib/xwrap.c21
2 files changed, 13 insertions, 10 deletions
diff --git a/lib/lib.h b/lib/lib.h
index 7572a8a3..707e388c 100644
--- a/lib/lib.h
+++ b/lib/lib.h
@@ -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;
}