summaryrefslogtreecommitdiff
path: root/lib/tar
diff options
context:
space:
mode:
Diffstat (limited to 'lib/tar')
-rw-r--r--lib/tar/Makemodule.am2
-rw-r--r--lib/tar/read_header.c4
-rw-r--r--lib/tar/read_retry.c37
-rw-r--r--lib/tar/read_sparse_map_old.c4
-rw-r--r--lib/tar/skip.c2
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;