diff options
Diffstat (limited to 'lib/tar')
-rw-r--r-- | lib/tar/Makemodule.am | 2 | ||||
-rw-r--r-- | lib/tar/read_header.c | 4 | ||||
-rw-r--r-- | lib/tar/read_retry.c | 37 | ||||
-rw-r--r-- | lib/tar/read_sparse_map_old.c | 4 | ||||
-rw-r--r-- | lib/tar/skip.c | 2 |
5 files changed, 43 insertions, 6 deletions
diff --git a/lib/tar/Makemodule.am b/lib/tar/Makemodule.am index 129d66f..f0945ff 100644 --- a/lib/tar/Makemodule.am +++ b/lib/tar/Makemodule.am @@ -2,7 +2,7 @@ libtar_a_SOURCES = lib/tar/read_header.c lib/tar/write_header.c lib/tar/skip.c libtar_a_SOURCES += lib/tar/number.c lib/tar/checksum.c lib/tar/cleanup.c libtar_a_SOURCES += lib/tar/read_sparse_map.c lib/tar/read_sparse_map_old.c libtar_a_SOURCES += lib/tar/base64.c lib/tar/urldecode.c lib/tar/internal.h -libtar_a_SOURCES += lib/tar/padd_file.c include/tar.h +libtar_a_SOURCES += lib/tar/padd_file.c lib/tar/read_retry.c include/tar.h libtar_a_CFLAGS = $(AM_CFLAGS) libtar_a_CPPFLAGS = $(AM_CPPFLAGS) diff --git a/lib/tar/read_header.c b/lib/tar/read_header.c index f6d746b..760d36a 100644 --- a/lib/tar/read_header.c +++ b/lib/tar/read_header.c @@ -42,7 +42,7 @@ static char *record_to_memory(int fd, sqfs_u64 size) if (buffer == NULL) goto fail_errno; - if (read_data("reading tar record", fd, buffer, size)) + if (read_retry("reading tar record", fd, buffer, size)) goto fail; if (skip_padding(fd, size)) @@ -368,7 +368,7 @@ int read_header(int fd, tar_header_decoded_t *out) memset(out, 0, sizeof(*out)); for (;;) { - if (read_data("reading tar header", fd, &hdr, sizeof(hdr))) + if (read_retry("reading tar header", fd, &hdr, sizeof(hdr))) goto fail; if (is_zero_block(&hdr)) { diff --git a/lib/tar/read_retry.c b/lib/tar/read_retry.c new file mode 100644 index 0000000..5d06595 --- /dev/null +++ b/lib/tar/read_retry.c @@ -0,0 +1,37 @@ +/* SPDX-License-Identifier: GPL-3.0-or-later */ +/* + * read_retry.c + * + * Copyright (C) 2019 David Oberhollenzer <goliath@infraroot.at> + */ +#include "config.h" + +#include <unistd.h> +#include <errno.h> +#include <stdio.h> + +#include "tar.h" + +int read_retry(const char *errstr, int fd, void *buffer, size_t size) +{ + ssize_t ret; + + while (size > 0) { + ret = read(fd, buffer, size); + if (ret < 0) { + if (errno == EINTR) + continue; + perror(errstr); + return -1; + } + if (ret == 0) { + fprintf(stderr, "%s: short read\n", errstr); + return -1; + } + + size -= ret; + buffer = (char *)buffer + ret; + } + + return 0; +} diff --git a/lib/tar/read_sparse_map_old.c b/lib/tar/read_sparse_map_old.c index fb79eca..959c9a8 100644 --- a/lib/tar/read_sparse_map_old.c +++ b/lib/tar/read_sparse_map_old.c @@ -47,8 +47,8 @@ sparse_map_t *read_gnu_old_sparse(int fd, tar_header_t *hdr) return list; do { - if (read_data("reading GNU sparse header", - fd, &sph, sizeof(sph))) { + if (read_retry("reading GNU sparse header", + fd, &sph, sizeof(sph))) { goto fail; } diff --git a/lib/tar/skip.c b/lib/tar/skip.c index eb91416..0ebe013 100644 --- a/lib/tar/skip.c +++ b/lib/tar/skip.c @@ -21,7 +21,7 @@ static int skip_bytes(int fd, sqfs_u64 size) if (diff > size) diff = size; - if (read_data("reading tar record padding", fd, buffer, diff)) + if (read_retry("reading tar record padding", fd, buffer, diff)) return -1; size -= diff; |