summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorTimo Teräs <timo.teras@iki.fi>2021-06-21 12:55:32 +0300
committerTimo Teräs <timo.teras@iki.fi>2021-06-21 12:55:32 +0300
commit22281fb4b583a5969a9c902c008e336e7cc421ff (patch)
tree469b88a8e053c669934524caff018c4c8d86e09a /src
parentca784ceab3f504b7cf9f481ccb76dee021abd76c (diff)
downloadapk-tools-22281fb4b583a5969a9c902c008e336e7cc421ff.tar.gz
apk-tools-22281fb4b583a5969a9c902c008e336e7cc421ff.tar.bz2
apk-tools-22281fb4b583a5969a9c902c008e336e7cc421ff.tar.xz
apk-tools-22281fb4b583a5969a9c902c008e336e7cc421ff.zip
print: handle write() errors in apk_print_progress()
Diffstat (limited to 'src')
-rw-r--r--src/apk_io.h2
-rw-r--r--src/io.c36
-rw-r--r--src/print.c6
3 files changed, 25 insertions, 19 deletions
diff --git a/src/apk_io.h b/src/apk_io.h
index 64f1efe..40a0d8c 100644
--- a/src/apk_io.h
+++ b/src/apk_io.h
@@ -18,6 +18,8 @@
#include "apk_atom.h"
#include "apk_crypto.h"
+ssize_t apk_write_fully(int fd, const void *ptr, size_t size);
+
struct apk_id_hash {
int empty;
struct hlist_head by_id[16], by_name[16];
diff --git a/src/io.c b/src/io.c
index 43dfa5a..ece34e4 100644
--- a/src/io.c
+++ b/src/io.c
@@ -33,6 +33,22 @@
size_t apk_io_bufsize = 128*1024;
+ssize_t apk_write_fully(int fd, const void *ptr, size_t size)
+{
+ ssize_t i = 0, r;
+
+ while (i < size) {
+ r = write(fd, ptr + i, size - i);
+ if (r <= 0) {
+ if (r == 0) return i;
+ return -errno;
+ }
+ i += r;
+ }
+
+ return i;
+}
+
static void apk_file_meta_from_fd(int fd, struct apk_file_meta *meta)
{
struct stat st;
@@ -828,22 +844,6 @@ struct apk_fd_ostream {
char buffer[1024];
};
-static ssize_t safe_write(int fd, const void *ptr, size_t size)
-{
- ssize_t i = 0, r;
-
- while (i < size) {
- r = write(fd, ptr + i, size - i);
- if (r < 0)
- return -errno;
- if (r == 0)
- return i;
- i += r;
- }
-
- return i;
-}
-
static ssize_t fdo_flush(struct apk_fd_ostream *fos)
{
ssize_t r;
@@ -851,7 +851,7 @@ static ssize_t fdo_flush(struct apk_fd_ostream *fos)
if (fos->bytes == 0)
return 0;
- if ((r = safe_write(fos->fd, fos->buffer, fos->bytes)) != fos->bytes) {
+ if ((r = apk_write_fully(fos->fd, fos->buffer, fos->bytes)) != fos->bytes) {
apk_ostream_cancel(&fos->os, r < 0 ? r : -EIO);
return r;
}
@@ -870,7 +870,7 @@ static ssize_t fdo_write(struct apk_ostream *os, const void *ptr, size_t size)
if (r != 0)
return r;
if (size >= sizeof(fos->buffer) / 2) {
- r = safe_write(fos->fd, ptr, size);
+ r = apk_write_fully(fos->fd, ptr, size);
if (r != size) apk_ostream_cancel(&fos->os, r < 0 ? r : -EIO);
return r;
}
diff --git a/src/print.c b/src/print.c
index 307033d..3cab694 100644
--- a/src/print.c
+++ b/src/print.c
@@ -18,6 +18,7 @@
#include "apk_defines.h"
#include "apk_print.h"
+#include "apk_io.h"
const char *apk_error_str(int error)
{
@@ -181,7 +182,10 @@ void apk_print_progress(struct apk_progress *p, size_t done, size_t total)
if (p->last_done == done && (!p->out || p->last_out_change == p->out->last_change)) return;
if (p->fd != 0) {
i = snprintf(buf, sizeof(buf), "%zu/%zu\n", done, total);
- write(p->fd, buf, i);
+ if (apk_write_fully(p->fd, buf, i) != i) {
+ close(p->fd);
+ p->fd = 0;
+ }
}
p->last_done = done;