From 395e92b66e35ccbd2f07a4857d6da588ec9f51f2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Timo=20Ter=C3=A4s?= Date: Sat, 17 Jul 2021 19:17:46 +0300 Subject: [PATCH] io: formalize apk_ostream_write() always writing full data --- src/apk_io.h | 7 +++---- src/database.c | 18 +++++++++--------- src/io.c | 45 ++++++++++++++++++--------------------------- src/io_archive.c | 8 ++++---- src/io_gunzip.c | 20 ++++++++------------ src/package.c | 8 ++++---- 6 files changed, 46 insertions(+), 60 deletions(-) diff --git a/src/apk_io.h b/src/apk_io.h index 13ab4a9..d03369e 100644 --- a/src/apk_io.h +++ b/src/apk_io.h @@ -141,7 +141,7 @@ struct apk_istream *apk_istream_tee(struct apk_istream *from, struct apk_ostream struct apk_ostream_ops { void (*set_meta)(struct apk_ostream *os, struct apk_file_meta *meta); - ssize_t (*write)(struct apk_ostream *os, const void *buf, size_t size); + int (*write)(struct apk_ostream *os, const void *buf, size_t size); int (*close)(struct apk_ostream *os); }; @@ -153,12 +153,11 @@ struct apk_ostream { struct apk_ostream *apk_ostream_counter(off_t *); struct apk_ostream *apk_ostream_to_fd(int fd); struct apk_ostream *apk_ostream_to_file(int atfd, const char *file, mode_t mode); -size_t apk_ostream_write_string(struct apk_ostream *os, const char *string); +ssize_t apk_ostream_write_string(struct apk_ostream *os, const char *string); void apk_ostream_copy_meta(struct apk_ostream *os, struct apk_istream *is); static inline int apk_ostream_error(struct apk_ostream *os) { return os->rc; } static inline int apk_ostream_cancel(struct apk_ostream *os, int rc) { if (!os->rc) os->rc = rc; return rc; } -static inline ssize_t apk_ostream_write(struct apk_ostream *os, const void *buf, size_t size) -{ +static inline int apk_ostream_write(struct apk_ostream *os, const void *buf, size_t size) { return os->ops->write(os, buf, size); } static inline int apk_ostream_close(struct apk_ostream *os) diff --git a/src/database.c b/src/database.c index ef05047..b009f74 100644 --- a/src/database.c +++ b/src/database.c @@ -986,15 +986,16 @@ static int apk_db_write_fdb(struct apk_database *db, struct apk_ostream *os) apk_blob_push_blob(&bbuf, APK_BLOB_STR("\n")); } - if (apk_ostream_write(os, buf, bbuf.ptr - buf) != bbuf.ptr - buf) - return -EIO; + r = apk_ostream_write(os, buf, bbuf.ptr - buf); + if (r < 0) return r; bbuf = APK_BLOB_BUF(buf); } - if (apk_ostream_write(os, buf, bbuf.ptr - buf) != bbuf.ptr - buf) - return -EIO; + r = apk_ostream_write(os, buf, bbuf.ptr - buf); + if (r < 0) return r; bbuf = APK_BLOB_BUF(buf); } - apk_ostream_write(os, "\n", 1); + r = apk_ostream_write(os, "\n", 1); + if (r < 0) return r; } return 0; @@ -1194,11 +1195,10 @@ static int write_index_entry(apk_hash_item item, void *ctx) return 0; r = apk_pkg_write_index_entry(pkg, iwctx->os); - if (r < 0) - return r; + if (r < 0) return r; - if (apk_ostream_write(iwctx->os, "\n", 1) != 1) - return apk_ostream_cancel(iwctx->os, -EIO); + r = apk_ostream_write(iwctx->os, "\n", 1); + if (r < 0) return r; iwctx->count++; return 0; diff --git a/src/io.c b/src/io.c index 1f53d3a..bb5c566 100644 --- a/src/io.c +++ b/src/io.c @@ -314,13 +314,10 @@ static void tee_get_meta(struct apk_istream *is, struct apk_file_meta *meta) apk_istream_get_meta(tee->inner_is, meta); } -static ssize_t __tee_write(struct apk_tee_istream *tee, void *ptr, size_t size) +static int __tee_write(struct apk_tee_istream *tee, void *ptr, size_t size) { - ssize_t w = apk_ostream_write(tee->to, ptr, size); - if (size != w) { - if (w < 0) return w; - return -ENOSPC; - } + int r = apk_ostream_write(tee->to, ptr, size); + if (r < 0) return r; tee->size += size; if (tee->cb) tee->cb(tee->cb_ctx, tee->size); return size; @@ -828,11 +825,8 @@ static ssize_t fdo_flush(struct apk_fd_ostream *fos) if (fos->os.rc < 0) return fos->os.rc; if (fos->bytes == 0) return 0; - - if ((r = apk_write_fully(fos->fd, fos->buffer, fos->bytes)) != fos->bytes) { - apk_ostream_cancel(&fos->os, r < 0 ? r : -ENOSPC); - return r; - } + if ((r = apk_write_fully(fos->fd, fos->buffer, fos->bytes)) != fos->bytes) + return apk_ostream_cancel(&fos->os, r < 0 ? r : -ENOSPC); fos->bytes = 0; return 0; @@ -849,7 +843,7 @@ static void fdo_set_meta(struct apk_ostream *os, struct apk_file_meta *meta) futimens(fos->fd, times); } -static ssize_t fdo_write(struct apk_ostream *os, const void *ptr, size_t size) +static int fdo_write(struct apk_ostream *os, const void *ptr, size_t size) { struct apk_fd_ostream *fos = container_of(os, struct apk_fd_ostream, os); ssize_t r; @@ -868,7 +862,7 @@ static ssize_t fdo_write(struct apk_ostream *os, const void *ptr, size_t size) memcpy(&fos->buffer[fos->bytes], ptr, size); fos->bytes += size; - return size; + return 0; } static int fdo_close(struct apk_ostream *os) @@ -877,12 +871,10 @@ static int fdo_close(struct apk_ostream *os) int rc; fdo_flush(fos); + if (fos->fd > STDERR_FILENO && close(fos->fd) < 0) + apk_ostream_cancel(os, -errno); + rc = fos->os.rc; - - if (fos->fd > STDERR_FILENO && - close(fos->fd) < 0) - rc = -errno; - if (fos->file) { char tmpname[PATH_MAX]; @@ -895,7 +887,6 @@ static int fdo_close(struct apk_ostream *os) unlinkat(fos->atfd, tmpname, 0); } } - free(fos); return rc; @@ -954,20 +945,20 @@ struct apk_counter_ostream { off_t *counter; }; -static ssize_t co_write(struct apk_ostream *os, const void *ptr, size_t size) +static int co_write(struct apk_ostream *os, const void *ptr, size_t size) { struct apk_counter_ostream *cos = container_of(os, struct apk_counter_ostream, os); - *cos->counter += size; - return size; + return 0; } static int co_close(struct apk_ostream *os) { struct apk_counter_ostream *cos = container_of(os, struct apk_counter_ostream, os); + int rc = os->rc; free(cos); - return 0; + return rc; } static const struct apk_ostream_ops counter_ostream_ops = { @@ -991,14 +982,14 @@ struct apk_ostream *apk_ostream_counter(off_t *counter) return &cos->os; } -size_t apk_ostream_write_string(struct apk_ostream *os, const char *string) +ssize_t apk_ostream_write_string(struct apk_ostream *os, const char *string) { size_t len; + ssize_t r; len = strlen(string); - if (apk_ostream_write(os, string, len) != len) - return -1; - + r = apk_ostream_write(os, string, len); + if (r < 0) return r; return len; } diff --git a/src/io_archive.c b/src/io_archive.c index 984af09..1164d7c 100644 --- a/src/io_archive.c +++ b/src/io_archive.c @@ -302,15 +302,15 @@ int apk_tar_write_entry(struct apk_ostream *os, const struct apk_file_info *ae, put_octal(buf.chksum, sizeof(buf.chksum)-1, chksum); } - if (apk_ostream_write(os, &buf, sizeof(buf)) != sizeof(buf)) + if (apk_ostream_write(os, &buf, sizeof(buf)) < 0) return -1; if (ae == NULL) { /* End-of-archive is two empty headers */ - if (apk_ostream_write(os, &buf, sizeof(buf)) != sizeof(buf)) + if (apk_ostream_write(os, &buf, sizeof(buf)) < 0) return -1; } else if (data != NULL) { - if (apk_ostream_write(os, data, ae->size) != ae->size) + if (apk_ostream_write(os, data, ae->size) < 0) return -1; if (apk_tar_write_padding(os, ae) != 0) return -1; @@ -326,7 +326,7 @@ int apk_tar_write_padding(struct apk_ostream *os, const struct apk_file_info *ae pad = 512 - (ae->size & 511); if (pad != 512 && - apk_ostream_write(os, padding, pad) != pad) + apk_ostream_write(os, padding, pad) < 0) return -1; return 0; diff --git a/src/io_gunzip.c b/src/io_gunzip.c index 96c66d2..4ad0b6c 100644 --- a/src/io_gunzip.c +++ b/src/io_gunzip.c @@ -176,7 +176,7 @@ struct apk_gzip_ostream { z_stream zs; }; -static ssize_t gzo_write(struct apk_ostream *os, const void *ptr, size_t size) +static int gzo_write(struct apk_ostream *os, const void *ptr, size_t size) { struct apk_gzip_ostream *gos = container_of(os, struct apk_gzip_ostream, os); unsigned char buffer[1024]; @@ -189,16 +189,15 @@ static ssize_t gzo_write(struct apk_ostream *os, const void *ptr, size_t size) gos->zs.next_out = buffer; r = deflate(&gos->zs, Z_NO_FLUSH); if (r == Z_STREAM_ERROR) - return -EIO; + return apk_ostream_cancel(gos->output, -EIO); have = sizeof(buffer) - gos->zs.avail_out; if (have != 0) { r = apk_ostream_write(gos->output, buffer, have); - if (r != have) - return -EIO; + if (r < 0) return r; } } - return size; + return 0; } static int gzo_close(struct apk_ostream *os) @@ -206,24 +205,21 @@ static int gzo_close(struct apk_ostream *os) struct apk_gzip_ostream *gos = container_of(os, struct apk_gzip_ostream, os); unsigned char buffer[1024]; size_t have; - int r, rc = 0; + int r, rc = os->rc; do { gos->zs.avail_out = sizeof(buffer); gos->zs.next_out = buffer; r = deflate(&gos->zs, Z_FINISH); have = sizeof(buffer) - gos->zs.avail_out; - if (apk_ostream_write(gos->output, buffer, have) != have) - rc = -EIO; + if (apk_ostream_write(gos->output, buffer, have) < 0) + break; } while (r == Z_OK); r = apk_ostream_close(gos->output); - if (r != 0) - rc = r; - deflateEnd(&gos->zs); free(gos); - return rc; + return rc ?: r; } static const struct apk_ostream_ops gzip_ostream_ops = { diff --git a/src/package.c b/src/package.c index 542edfd..dee15eb 100644 --- a/src/package.c +++ b/src/package.c @@ -439,7 +439,7 @@ int apk_deps_write(struct apk_database *db, struct apk_dependency_array *deps, s blob = apk_blob_pushed(APK_BLOB_BUF(tmp), blob); if (APK_BLOB_IS_NULL(blob) || - apk_ostream_write(os, blob.ptr, blob.len) != blob.len) + apk_ostream_write(os, blob.ptr, blob.len) < 0) return -1; n += blob.len; @@ -1086,9 +1086,9 @@ static int write_depends(struct apk_ostream *os, const char *field, int r; if (deps->num == 0) return 0; - if (apk_ostream_write(os, field, 2) != 2) return -1; + if (apk_ostream_write(os, field, 2) < 0) return -1; if ((r = apk_deps_write(NULL, deps, os, APK_BLOB_PTR_LEN(" ", 1))) < 0) return r; - if (apk_ostream_write(os, "\n", 1) != 1) return -1; + if (apk_ostream_write(os, "\n", 1) < 0) return -1; return 0; } @@ -1144,7 +1144,7 @@ int apk_pkg_write_index_entry(struct apk_package *info, return apk_ostream_cancel(os, -ENOBUFS); bbuf = apk_blob_pushed(APK_BLOB_BUF(buf), bbuf); - if (apk_ostream_write(os, bbuf.ptr, bbuf.len) != bbuf.len || + if (apk_ostream_write(os, bbuf.ptr, bbuf.len) || write_depends(os, "D:", info->depends) || write_depends(os, "p:", info->provides) || write_depends(os, "i:", info->install_if))