summaryrefslogtreecommitdiff
path: root/lib/tar
diff options
context:
space:
mode:
Diffstat (limited to 'lib/tar')
-rw-r--r--lib/tar/Makemodule.am1
-rw-r--r--lib/tar/padd_file.c4
-rw-r--r--lib/tar/write_header.c6
-rw-r--r--lib/tar/write_retry.c37
4 files changed, 43 insertions, 5 deletions
diff --git a/lib/tar/Makemodule.am b/lib/tar/Makemodule.am
index f0945ff..abc0209 100644
--- a/lib/tar/Makemodule.am
+++ b/lib/tar/Makemodule.am
@@ -3,6 +3,7 @@ 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 lib/tar/read_retry.c include/tar.h
+libtar_a_SOURCES += lib/tar/write_retry.c
libtar_a_CFLAGS = $(AM_CFLAGS)
libtar_a_CPPFLAGS = $(AM_CPPFLAGS)
diff --git a/lib/tar/padd_file.c b/lib/tar/padd_file.c
index 471370d..f58cfbf 100644
--- a/lib/tar/padd_file.c
+++ b/lib/tar/padd_file.c
@@ -25,8 +25,8 @@ int padd_file(int outfd, sqfs_u64 size)
if (buffer == NULL)
goto fail_errno;
- if (write_data("padding output file to block size",
- outfd, buffer, padd_sz)) {
+ if (write_retry("padding output file to block size",
+ outfd, buffer, padd_sz)) {
goto out;
}
diff --git a/lib/tar/write_header.c b/lib/tar/write_header.c
index 14802c0..84aa2d3 100644
--- a/lib/tar/write_header.c
+++ b/lib/tar/write_header.c
@@ -88,7 +88,7 @@ static int write_header(int fd, const struct stat *sb, const char *name,
update_checksum(&hdr);
- return write_data("writing tar header record", fd, &hdr, sizeof(hdr));
+ return write_retry("writing tar header record", fd, &hdr, sizeof(hdr));
}
static int write_gnu_header(int fd, const struct stat *orig,
@@ -104,8 +104,8 @@ static int write_gnu_header(int fd, const struct stat *orig,
if (write_header(fd, &sb, name, NULL, type))
return -1;
- if (write_data("writing GNU extension header",
- fd, payload, payload_len)) {
+ if (write_retry("writing GNU extension header",
+ fd, payload, payload_len)) {
return -1;
}
diff --git a/lib/tar/write_retry.c b/lib/tar/write_retry.c
new file mode 100644
index 0000000..1ff1a7e
--- /dev/null
+++ b/lib/tar/write_retry.c
@@ -0,0 +1,37 @@
+/* SPDX-License-Identifier: LGPL-3.0-or-later */
+/*
+ * write_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 write_retry(const char *errstr, int fd, const void *data, size_t size)
+{
+ ssize_t ret;
+
+ while (size > 0) {
+ ret = write(fd, data, size);
+ if (ret == 0) {
+ fprintf(stderr, "%s: write truncated\n", errstr);
+ return -1;
+ }
+ if (ret < 0) {
+ if (errno == EINTR)
+ continue;
+ perror(errstr);
+ return -1;
+ }
+
+ data = (const char *)data + ret;
+ size -= ret;
+ }
+
+ return 0;
+}