From 4d9c0c39b033159f4bd6fe279dd38d4f4a67c904 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Timo=20Ter=C3=A4s?= Date: Wed, 21 Jun 2017 16:07:58 +0300 Subject: io: make io vtables const struct, and add accessors for them This reduces function pointers in heap, and unifies how the io functions are called. --- src/apk.c | 4 +-- src/apk_io.h | 52 +++++++++++++++++++++++++++++--- src/archive.c | 30 +++++++++++-------- src/database.c | 52 ++++++++++++++++---------------- src/fetch.c | 4 +-- src/gunzip.c | 34 +++++++++++++-------- src/index.c | 4 +-- src/info.c | 4 +-- src/io.c | 94 ++++++++++++++++++++++++++++++++++++---------------------- src/manifest.c | 2 +- src/package.c | 23 +++++--------- src/url.c | 10 +++++-- src/verify.c | 2 +- 13 files changed, 195 insertions(+), 120 deletions(-) (limited to 'src') diff --git a/src/apk.c b/src/apk.c index c9901023c3..6cd4a5a07f 100644 --- a/src/apk.c +++ b/src/apk.c @@ -548,7 +548,7 @@ int main(int argc, char **argv) struct apk_bstream *bs = apk_bstream_from_file(AT_FDCWD, test_installed_db); if (!IS_ERR_OR_NULL(bs)) { apk_db_index_read(&db, bs, -1); - bs->close(bs, NULL); + apk_bstream_close(bs, NULL); } } for (i = 0; i < test_repos->num; i++) { @@ -576,7 +576,7 @@ int main(int argc, char **argv) } apk_db_index_read(&db, bs, repo); - bs->close(bs, NULL); + apk_bstream_close(bs, NULL); if (repo != -2) { if (!(apk_flags & APK_NO_NETWORK)) db.available_repos |= BIT(repo); diff --git a/src/apk_io.h b/src/apk_io.h index b0e15a4ce1..b07035c29f 100644 --- a/src/apk_io.h +++ b/src/apk_io.h @@ -54,27 +54,39 @@ struct apk_file_info { struct apk_xattr_array *xattrs; }; -struct apk_istream { +struct apk_istream_ops { void (*get_meta)(void *stream, struct apk_file_meta *meta); ssize_t (*read)(void *stream, void *ptr, size_t size); void (*close)(void *stream); }; +struct apk_istream { + const struct apk_istream_ops *ops; +}; + #define APK_BSTREAM_SINGLE_READ 0x0001 #define APK_BSTREAM_EOF 0x0002 -struct apk_bstream { - unsigned int flags; +struct apk_bstream_ops { void (*get_meta)(void *stream, struct apk_file_meta *meta); apk_blob_t (*read)(void *stream, apk_blob_t token); void (*close)(void *stream, size_t *size); }; -struct apk_ostream { +struct apk_bstream { + unsigned int flags; + const struct apk_bstream_ops *ops; +}; + +struct apk_ostream_ops { ssize_t (*write)(void *stream, const void *buf, size_t size); int (*close)(void *stream); }; +struct apk_ostream { + const struct apk_ostream_ops *ops; +}; + #define APK_MPART_DATA 1 /* data processed so far */ #define APK_MPART_BOUNDARY 2 /* final part of data, before boundary */ #define APK_MPART_END 3 /* signals end of stream */ @@ -118,6 +130,18 @@ static inline struct apk_istream *apk_istream_from_url_if_modified(const char *u { return apk_istream_from_fd_url_if_modified(AT_FDCWD, url, since); } +static inline void apk_istream_get_meta(struct apk_istream *is, struct apk_file_meta *meta) +{ + is->ops->get_meta(is, meta); +} +static inline ssize_t apk_istream_read(struct apk_istream *is, void *ptr, size_t size) +{ + return is->ops->read(is, ptr, size); +} +static inline void apk_istream_close(struct apk_istream *is) +{ + is->ops->close(is); +} struct apk_bstream *apk_bstream_from_istream(struct apk_istream *istream); struct apk_bstream *apk_bstream_from_fd_pid(int fd, pid_t pid, int (*translate_status)(int)); @@ -143,11 +167,31 @@ static inline struct apk_bstream *apk_bstream_from_url_if_modified(const char *u { return apk_bstream_from_fd_url_if_modified(AT_FDCWD, url, since); } +static inline void apk_bstream_get_meta(struct apk_bstream *bs, struct apk_file_meta *meta) +{ + bs->ops->get_meta(bs, meta); +} +static inline apk_blob_t apk_bstream_read(struct apk_bstream *bs, apk_blob_t token) +{ + return bs->ops->read(bs, token); +} +static inline void apk_bstream_close(struct apk_bstream *bs, size_t *size) +{ + bs->ops->close(bs, size); +} struct apk_ostream *apk_ostream_to_fd(int fd); struct apk_ostream *apk_ostream_to_file(int atfd, const char *file, const char *tmpfile, mode_t mode); struct apk_ostream *apk_ostream_to_file_gz(int atfd, const char *file, const char *tmpfile, mode_t mode); size_t apk_ostream_write_string(struct apk_ostream *ostream, const char *string); +static inline ssize_t 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) +{ + return os->ops->close(os); +} apk_blob_t apk_blob_from_istream(struct apk_istream *istream, size_t size); apk_blob_t apk_blob_from_file(int atfd, const char *file); diff --git a/src/archive.c b/src/archive.c index f84e440c07..438eb949e3 100644 --- a/src/archive.c +++ b/src/archive.c @@ -108,7 +108,7 @@ static ssize_t tar_entry_read(void *stream, void *ptr, size_t size) if (size == 0) return 0; - r = teis->tar_is->read(teis->tar_is, ptr, size); + r = apk_istream_read(teis->tar_is, ptr, size); if (r <= 0) { /* If inner stream returned zero (end-of-stream), we * are getting short read, because tar header indicated @@ -133,6 +133,12 @@ static void tar_entry_close(void *stream) { } +static const struct apk_istream_ops tar_istream_ops = { + .get_meta = tar_entry_get_meta, + .read = tar_entry_read, + .close = tar_entry_close, +}; + static int blob_realloc(apk_blob_t *b, size_t newsize) { char *tmp; @@ -191,9 +197,7 @@ int apk_tar_parse(struct apk_istream *is, apk_archive_entry_parser parser, { struct apk_file_info entry; struct apk_tar_entry_istream teis = { - .is.get_meta = tar_entry_get_meta, - .is.read = tar_entry_read, - .is.close = tar_entry_close, + .is.ops = &tar_istream_ops, .tar_is = is, }; struct tar_header buf; @@ -206,7 +210,7 @@ int apk_tar_parse(struct apk_istream *is, apk_archive_entry_parser parser, odi = (struct apk_tar_digest_info *) &buf.linkname[3]; EVP_MD_CTX_init(&teis.mdctx); memset(&entry, 0, sizeof(entry)); - while ((r = is->read(is, &buf, 512)) == 512) { + while ((r = apk_istream_read(is, &buf, 512)) == 512) { offset += 512; if (buf.name[0] == '\0') { if (end) break; @@ -243,7 +247,7 @@ int apk_tar_parse(struct apk_istream *is, apk_archive_entry_parser parser, switch (buf.typeflag) { case 'L': /* GNU long name extension */ if ((r = blob_realloc(&longname, entry.size+1)) != 0 || - (r = is->read(is, longname.ptr, entry.size)) != entry.size) + (r = apk_istream_read(is, longname.ptr, entry.size)) != entry.size) goto err; entry.name = longname.ptr; entry.name[entry.size] = 0; @@ -293,7 +297,7 @@ int apk_tar_parse(struct apk_istream *is, apk_archive_entry_parser parser, paxlen = entry.size; entry.size = 0; if ((r = blob_realloc(&pax, (paxlen + 511) & -512)) != 0 || - (r = is->read(is, pax.ptr, paxlen)) != paxlen) + (r = apk_istream_read(is, pax.ptr, paxlen)) != paxlen) goto err; offset += paxlen; break; @@ -321,7 +325,7 @@ int apk_tar_parse(struct apk_istream *is, apk_archive_entry_parser parser, toskip += 512 - ((offset + toskip) & 511); offset += toskip; if (toskip != 0) { - if ((r = is->read(is, NULL, toskip)) != toskip) + if ((r = apk_istream_read(is, NULL, toskip)) != toskip) goto err; } } @@ -329,7 +333,7 @@ int apk_tar_parse(struct apk_istream *is, apk_archive_entry_parser parser, /* Read remaining end-of-archive records, to ensure we read all of * the file. The underlying istream is likely doing checksumming. */ if (r == 512) { - while ((r = is->read(is, &buf, 512)) == 512) { + while ((r = apk_istream_read(is, &buf, 512)) == 512) { if (buf.name[0] != 0) break; } } @@ -381,15 +385,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 (os->write(os, &buf, sizeof(buf)) != sizeof(buf)) + if (apk_ostream_write(os, &buf, sizeof(buf)) != sizeof(buf)) return -1; if (ae == NULL) { /* End-of-archive is two empty headers */ - if (os->write(os, &buf, sizeof(buf)) != sizeof(buf)) + if (apk_ostream_write(os, &buf, sizeof(buf)) != sizeof(buf)) return -1; } else if (data != NULL) { - if (os->write(os, data, ae->size) != ae->size) + if (apk_ostream_write(os, data, ae->size) != ae->size) return -1; if (apk_tar_write_padding(os, ae) != 0) return -1; @@ -405,7 +409,7 @@ int apk_tar_write_padding(struct apk_ostream *os, const struct apk_file_info *ae pad = 512 - (ae->size & 511); if (pad != 512 && - os->write(os, padding, pad) != pad) + apk_ostream_write(os, padding, pad) != pad) return -1; return 0; diff --git a/src/database.c b/src/database.c index 67cc4f5068..4d16900e0b 100644 --- a/src/database.c +++ b/src/database.c @@ -658,12 +658,12 @@ int apk_cache_download(struct apk_database *db, struct apk_repository *repo, if (fd >= 0) { struct apk_file_meta meta; r = apk_istream_splice(is, fd, APK_SPLICE_ALL, cb, cb_ctx); - is->get_meta(is, &meta); + apk_istream_get_meta(is, &meta); apk_file_meta_to_fd(fd, &meta); close(fd); } } - if (!IS_ERR_OR_NULL(is)) is->close(is); + if (!IS_ERR_OR_NULL(is)) apk_istream_close(is); if (r == -EALREADY) return 0; if (r < 0) { unlinkat(db->cache_fd, tmpcacheitem, 0); @@ -720,7 +720,7 @@ int apk_db_read_overlay(struct apk_database *db, struct apk_bstream *bs) diri_node = hlist_tail_ptr(&ipkg->owned_dirs); - while (!APK_BLOB_IS_NULL(line = bs->read(bs, token))) { + while (!APK_BLOB_IS_NULL(line = apk_bstream_read(bs, token))) { if (!apk_blob_rsplit(line, '/', &bdir, &bfile)) break; @@ -757,7 +757,7 @@ int apk_db_index_read(struct apk_database *db, struct apk_bstream *bs, int repo) gid_t gid; int field, r, lineno = 0; - while (!APK_BLOB_IS_NULL(l = bs->read(bs, token))) { + while (!APK_BLOB_IS_NULL(l = apk_bstream_read(bs, token))) { lineno++; if (l.len < 2 || l.ptr[1] != ':') { @@ -968,15 +968,15 @@ static int apk_db_write_fdb(struct apk_database *db, struct apk_ostream *os) apk_blob_push_blob(&bbuf, APK_BLOB_STR("\n")); } - if (os->write(os, buf, bbuf.ptr - buf) != bbuf.ptr - buf) + if (apk_ostream_write(os, buf, bbuf.ptr - buf) != bbuf.ptr - buf) return -EIO; bbuf = APK_BLOB_BUF(buf); } - if (os->write(os, buf, bbuf.ptr - buf) != bbuf.ptr - buf) + if (apk_ostream_write(os, buf, bbuf.ptr - buf) != bbuf.ptr - buf) return -EIO; bbuf = APK_BLOB_BUF(buf); } - os->write(os, "\n", 1); + apk_ostream_write(os, "\n", 1); } return 0; @@ -1088,13 +1088,13 @@ static void apk_db_triggers_write(struct apk_database *db, struct apk_ostream *o bfn = APK_BLOB_BUF(buf); apk_blob_push_csum(&bfn, &ipkg->pkg->csum); bfn = apk_blob_pushed(APK_BLOB_BUF(buf), bfn); - os->write(os, bfn.ptr, bfn.len); + apk_ostream_write(os, bfn.ptr, bfn.len); foreach_array_item(trigger, ipkg->triggers) { - os->write(os, " ", 1); + apk_ostream_write(os, " ", 1); apk_ostream_write_string(os, *trigger); } - os->write(os, "\n", 1); + apk_ostream_write(os, "\n", 1); } } @@ -1105,7 +1105,7 @@ static void apk_db_triggers_read(struct apk_database *db, struct apk_bstream *bs struct apk_installed_package *ipkg; apk_blob_t l; - while (!APK_BLOB_IS_NULL(l = bs->read(bs, APK_BLOB_STR("\n")))) { + while (!APK_BLOB_IS_NULL(l = apk_bstream_read(bs, APK_BLOB_STR("\n")))) { apk_blob_pull_csum(&l, &csum); apk_blob_pull_char(&l, ' '); @@ -1148,14 +1148,14 @@ static int apk_db_read_state(struct apk_database *db, int flags) bs = apk_bstream_from_file(db->root_fd, apk_installed_file); if (!IS_ERR_OR_NULL(bs)) { r = apk_db_index_read(db, bs, -1); - bs->close(bs, NULL); + apk_bstream_close(bs, NULL); if (r != 0) return -1; } bs = apk_bstream_from_file(db->root_fd, apk_triggers_file); if (!IS_ERR_OR_NULL(bs)) { apk_db_triggers_read(db, bs); - bs->close(bs, NULL); + apk_bstream_close(bs, NULL); } } @@ -1164,7 +1164,7 @@ static int apk_db_read_state(struct apk_database *db, int flags) if (!IS_ERR_OR_NULL(is)) { apk_tar_parse(is, apk_read_script_archive_entry, db, FALSE, &db->id_cache); - is->close(is); + apk_istream_close(is); } } @@ -1190,7 +1190,7 @@ static int write_index_entry(apk_hash_item item, void *ctx) if (r < 0) return r; - if (iwctx->os->write(iwctx->os, "\n", 1) != 1) + if (apk_ostream_write(iwctx->os, "\n", 1) != 1) return -EIO; iwctx->count++; @@ -1224,7 +1224,7 @@ static int apk_db_index_write_nr_cache(struct apk_database *db) if (r != 0) return r; } - r = os->close(os); + r = apk_ostream_close(os); if (r < 0) return r; @@ -1656,7 +1656,7 @@ int apk_db_open(struct apk_database *db, struct apk_db_options *dbopts) bs = apk_bstream_from_file(db->cache_fd, "installed"); if (!IS_ERR_OR_NULL(bs)) { apk_db_index_read(db, bs, -2); - bs->close(bs, NULL); + apk_bstream_close(bs, NULL); } } } @@ -1727,8 +1727,8 @@ int apk_db_write_config(struct apk_database *db) 0644); if (IS_ERR_OR_NULL(os)) return PTR_ERR(os); apk_deps_write(db, db->world, os, APK_BLOB_PTR_LEN("\n", 1)); - os->write(os, "\n", 1); - r = os->close(os); + apk_ostream_write(os, "\n", 1); + r = apk_ostream_close(os); if (r < 0) return r; os = apk_ostream_to_file(db->root_fd, @@ -1737,7 +1737,7 @@ int apk_db_write_config(struct apk_database *db) 0644); if (IS_ERR_OR_NULL(os)) return PTR_ERR(os); apk_db_write_fdb(db, os); - r = os->close(os); + r = apk_ostream_close(os); if (r < 0) return r; os = apk_ostream_to_file(db->root_fd, @@ -1746,7 +1746,7 @@ int apk_db_write_config(struct apk_database *db) 0644); if (IS_ERR_OR_NULL(os)) return PTR_ERR(os); apk_db_scriptdb_write(db, os); - r = os->close(os); + r = apk_ostream_close(os); if (r < 0) return r; apk_db_index_write_nr_cache(db); @@ -1757,7 +1757,7 @@ int apk_db_write_config(struct apk_database *db) 0644); if (IS_ERR_OR_NULL(os)) return PTR_ERR(os); apk_db_triggers_write(db, os); - r = os->close(os); + r = apk_ostream_close(os); if (r < 0) return r; return 0; @@ -2150,7 +2150,7 @@ static int load_apkindex(void *sctx, const struct apk_file_info *fi, bs = apk_bstream_from_istream(is); if (!IS_ERR_OR_NULL(bs)) { apk_db_index_read(ctx->db, bs, ctx->repo); - bs->close(bs, NULL); + apk_bstream_close(bs, NULL); } } @@ -2174,7 +2174,7 @@ static int load_index(struct apk_database *db, struct apk_bstream *bs, apk_sign_ctx_init(&ctx.sctx, APK_SIGN_VERIFY, NULL, db->keys_fd); is = apk_bstream_gunzip_mpart(bs, apk_sign_ctx_mpart_cb, &ctx.sctx); r = apk_tar_parse(is, load_apkindex, &ctx, FALSE, &db->id_cache); - is->close(is); + apk_istream_close(is); apk_sign_ctx_free(&ctx.sctx); if (r >= 0 && ctx.found == 0) @@ -2183,7 +2183,7 @@ static int load_index(struct apk_database *db, struct apk_bstream *bs, bs = apk_bstream_from_istream(apk_bstream_gunzip(bs)); if (!IS_ERR_OR_NULL(bs)) { apk_db_index_read(db, bs, repo); - bs->close(bs, NULL); + apk_bstream_close(bs, NULL); } } return r; @@ -2737,7 +2737,7 @@ static int apk_db_unpack_pkg(struct apk_database *db, tar = apk_bstream_gunzip_mpart(bs, apk_sign_ctx_mpart_cb, &ctx.sctx); r = apk_tar_parse(tar, apk_db_install_archive_entry, &ctx, TRUE, &db->id_cache); apk_sign_ctx_free(&ctx.sctx); - tar->close(tar); + apk_istream_close(tar); if (need_copy) { if (r == 0) { diff --git a/src/fetch.c b/src/fetch.c index 847146f473..bb2efa9369 100644 --- a/src/fetch.c +++ b/src/fetch.c @@ -178,11 +178,11 @@ static int fetch_package(apk_hash_item item, void *pctx) r = apk_istream_splice(is, fd, pkg->size, progress_cb, ctx); if (fd != STDOUT_FILENO) { struct apk_file_meta meta; - is->get_meta(is, &meta); + apk_istream_get_meta(is, &meta); apk_file_meta_to_fd(fd, &meta); close(fd); } - is->close(is); + apk_istream_close(is); if (r != pkg->size) { unlinkat(ctx->outdir_fd, filename, 0); diff --git a/src/gunzip.c b/src/gunzip.c index d1eb0cb155..4fac9faf0b 100644 --- a/src/gunzip.c +++ b/src/gunzip.c @@ -34,7 +34,7 @@ static void gzi_get_meta(void *stream, struct apk_file_meta *meta) { struct apk_gzip_istream *gis = container_of(stream, struct apk_gzip_istream, is); - gis->bs->get_meta(gis->bs, meta); + apk_bstream_get_meta(gis->bs, meta); } static ssize_t gzi_read(void *stream, void *ptr, size_t size) @@ -77,7 +77,7 @@ static ssize_t gzi_read(void *stream, void *ptr, size_t size) APK_BLOB_PTR_LEN(gis->cbprev, (void *)gis->zs.next_in - gis->cbprev)); } - blob = gis->bs->read(gis->bs, APK_BLOB_NULL); + blob = apk_bstream_read(gis->bs, APK_BLOB_NULL); gis->cbprev = blob.ptr; gis->zs.avail_in = blob.len; gis->zs.next_in = (void *) gis->cbprev; @@ -147,10 +147,16 @@ static void gzi_close(void *stream) container_of(stream, struct apk_gzip_istream, is); inflateEnd(&gis->zs); - gis->bs->close(gis->bs, NULL); + apk_bstream_close(gis->bs, NULL); free(gis); } +static const struct apk_istream_ops gunzip_istream_ops = { + .get_meta = gzi_get_meta, + .read = gzi_read, + .close = gzi_close, +}; + struct apk_istream *apk_bstream_gunzip_mpart(struct apk_bstream *bs, apk_multipart_cb cb, void *ctx) { @@ -162,9 +168,7 @@ struct apk_istream *apk_bstream_gunzip_mpart(struct apk_bstream *bs, if (!gis) goto err; *gis = (struct apk_gzip_istream) { - .is.get_meta = gzi_get_meta, - .is.read = gzi_read, - .is.close = gzi_close, + .is.ops = &gunzip_istream_ops, .bs = bs, .cb = cb, .cbctx = ctx, @@ -177,7 +181,7 @@ struct apk_istream *apk_bstream_gunzip_mpart(struct apk_bstream *bs, return &gis->is; err: - bs->close(bs, NULL); + apk_bstream_close(bs, NULL); return ERR_PTR(-ENOMEM); } @@ -203,7 +207,7 @@ static ssize_t gzo_write(void *stream, const void *ptr, size_t size) return -EIO; have = sizeof(buffer) - gos->zs.avail_out; if (have != 0) { - r = gos->output->write(gos->output, buffer, have); + r = apk_ostream_write(gos->output, buffer, have); if (r != have) return -EIO; } @@ -224,10 +228,10 @@ static int gzo_close(void *stream) gos->zs.next_out = buffer; r = deflate(&gos->zs, Z_FINISH); have = sizeof(buffer) - gos->zs.avail_out; - if (gos->output->write(gos->output, buffer, have) != have) + if (apk_ostream_write(gos->output, buffer, have) != have) rc = -EIO; } while (r == Z_OK); - r = gos->output->close(gos->output); + r = apk_ostream_close(gos->output); if (r != 0) rc = r; @@ -237,6 +241,11 @@ static int gzo_close(void *stream) return rc; } +static const struct apk_ostream_ops gzip_ostream_ops = { + .write = gzo_write, + .close = gzo_close, +}; + struct apk_ostream *apk_ostream_gzip(struct apk_ostream *output) { struct apk_gzip_ostream *gos; @@ -247,8 +256,7 @@ struct apk_ostream *apk_ostream_gzip(struct apk_ostream *output) if (gos == NULL) goto err; *gos = (struct apk_gzip_ostream) { - .os.write = gzo_write, - .os.close = gzo_close, + .os.ops = &gzip_ostream_ops, .output = output, }; @@ -260,7 +268,7 @@ struct apk_ostream *apk_ostream_gzip(struct apk_ostream *output) return &gos->os; err: - output->close(output); + apk_ostream_close(output); return ERR_PTR(-ENOMEM); } diff --git a/src/index.c b/src/index.c index 1c39e3c1ff..45d371b78d 100644 --- a/src/index.c +++ b/src/index.c @@ -215,7 +215,7 @@ static int index_main(void *ctx, struct apk_database *db, struct apk_string_arra fi.name = "APKINDEX"; counter = apk_ostream_counter(&fi.size); r = apk_db_index_write(db, counter); - counter->close(counter); + apk_ostream_close(counter); if (r >= 0) { os = apk_ostream_gzip(os); @@ -237,7 +237,7 @@ static int index_main(void *ctx, struct apk_database *db, struct apk_string_arra } else { r = apk_db_index_write(db, os); } - os->close(os); + apk_ostream_close(os); if (r < 0) { apk_error("Index generation failed: %s", apk_error_str(r)); diff --git a/src/info.c b/src/info.c index 262049fe57..a1bc609049 100644 --- a/src/info.c +++ b/src/info.c @@ -140,8 +140,8 @@ static void info_who_owns(struct info_ctx *ctx, struct apk_database *db, os = apk_ostream_to_fd(STDOUT_FILENO); if (!IS_ERR_OR_NULL(os)) { apk_deps_write(db, deps, os, APK_BLOB_PTR_LEN(" ", 1)); - os->write(os, "\n", 1); - os->close(os); + apk_ostream_write(os, "\n", 1); + apk_ostream_close(os); } } apk_dependency_array_free(&deps); diff --git a/src/io.c b/src/io.c index 8cf867bcc3..bfc9c1c7b4 100644 --- a/src/io.c +++ b/src/io.c @@ -110,6 +110,12 @@ static void fdi_close(void *stream) free(fis); } +static const struct apk_istream_ops fd_istream_ops = { + .get_meta = fdi_get_meta, + .read = fdi_read, + .close = fdi_close, +}; + struct apk_istream *apk_istream_from_fd_pid(int fd, pid_t pid, int (*translate_status)(int)) { struct apk_fd_istream *fis; @@ -123,9 +129,7 @@ struct apk_istream *apk_istream_from_fd_pid(int fd, pid_t pid, int (*translate_s } *fis = (struct apk_fd_istream) { - .is.get_meta = fdi_get_meta, - .is.read = fdi_read, - .is.close = fdi_close, + .is.ops = &fd_istream_ops, .fd = fd, .pid = pid, .translate_status = translate_status, @@ -153,7 +157,7 @@ size_t apk_istream_skip(struct apk_istream *is, size_t size) togo = size - done; if (togo > sizeof(buf)) togo = sizeof(buf); - r = is->read(is, buf, togo); + r = apk_istream_read(is, buf, togo); if (r < 0) return r; done += r; @@ -202,7 +206,7 @@ size_t apk_istream_splice(void *stream, int fd, size_t size, togo = size - done; if (togo > bufsz) togo = bufsz; - r = is->read(is, buf, togo); + r = apk_istream_read(is, buf, togo); if (r < 0) goto err; if (r == 0) @@ -240,7 +244,7 @@ static void is_bs_get_meta(void *stream, struct apk_file_meta *meta) { struct apk_istream_bstream *isbs = container_of(stream, struct apk_istream_bstream, bs); - return isbs->is->get_meta(isbs->is, meta); + return apk_istream_get_meta(isbs->is, meta); } static apk_blob_t is_bs_read(void *stream, apk_blob_t token) @@ -268,8 +272,8 @@ static apk_blob_t is_bs_read(void *stream, apk_blob_t token) if (isbs->left.len != 0) memmove(isbs->buffer, isbs->left.ptr, isbs->left.len); isbs->left.ptr = isbs->buffer; - size = isbs->is->read(isbs->is, isbs->buffer + isbs->left.len, - sizeof(isbs->buffer) - isbs->left.len); + size = apk_istream_read(isbs->is, isbs->buffer + isbs->left.len, + sizeof(isbs->buffer) - isbs->left.len); if (size > 0) { isbs->size += size; isbs->left.len += size; @@ -306,10 +310,16 @@ static void is_bs_close(void *stream, size_t *size) if (size != NULL) *size = isbs->size; - isbs->is->close(isbs->is); + apk_istream_close(isbs->is); free(isbs); } +static const struct apk_bstream_ops is_bstream_ops = { + .get_meta = is_bs_get_meta, + .read = is_bs_read, + .close = is_bs_close, +}; + struct apk_bstream *apk_bstream_from_istream(struct apk_istream *istream) { struct apk_istream_bstream *isbs; @@ -320,9 +330,7 @@ struct apk_bstream *apk_bstream_from_istream(struct apk_istream *istream) if (isbs == NULL) return ERR_PTR(-ENOMEM); isbs->bs = (struct apk_bstream) { - .get_meta = is_bs_get_meta, - .read = is_bs_read, - .close = is_bs_close, + .ops = &is_bstream_ops, }; isbs->is = istream; isbs->left = APK_BLOB_PTR_LEN(isbs->buffer, 0), @@ -376,6 +384,12 @@ static void mmap_close(void *stream, size_t *size) free(mbs); } +static const struct apk_bstream_ops mmap_bstream_ops = { + .get_meta = mmap_get_meta, + .read = mmap_read, + .close = mmap_close, +}; + static struct apk_bstream *apk_mmap_bstream_from_fd(int fd) { struct apk_mmap_bstream *mbs; @@ -395,9 +409,7 @@ static struct apk_bstream *apk_mmap_bstream_from_fd(int fd) mbs->bs = (struct apk_bstream) { .flags = APK_BSTREAM_SINGLE_READ, - .get_meta = mmap_get_meta, - .read = mmap_read, - .close = mmap_close, + .ops = &mmap_bstream_ops, }; mbs->fd = fd; mbs->size = st.st_size; @@ -446,7 +458,7 @@ static void tee_get_meta(void *stream, struct apk_file_meta *meta) { struct apk_tee_bstream *tbs = container_of(stream, struct apk_tee_bstream, bs); - tbs->inner_bs->get_meta(tbs->inner_bs, meta); + apk_bstream_get_meta(tbs->inner_bs, meta); } static apk_blob_t tee_read(void *stream, apk_blob_t token) @@ -455,11 +467,10 @@ static apk_blob_t tee_read(void *stream, apk_blob_t token) container_of(stream, struct apk_tee_bstream, bs); apk_blob_t blob; - blob = tbs->inner_bs->read(tbs->inner_bs, token); + blob = apk_bstream_read(tbs->inner_bs, token); if (!APK_BLOB_IS_NULL(blob)) { tbs->size += write(tbs->fd, blob.ptr, blob.len); - if (tbs->cb) - tbs->cb(tbs->cb_ctx, tbs->size); + if (tbs->cb) tbs->cb(tbs->cb_ctx, tbs->size); } return blob; @@ -472,16 +483,21 @@ static void tee_close(void *stream, size_t *size) container_of(stream, struct apk_tee_bstream, bs); /* copy info */ - tbs->inner_bs->get_meta(tbs->inner_bs, &meta); + apk_bstream_get_meta(tbs->inner_bs, &meta); apk_file_meta_to_fd(tbs->fd, &meta); - tbs->inner_bs->close(tbs->inner_bs, NULL); - if (size != NULL) - *size = tbs->size; + apk_bstream_close(tbs->inner_bs, NULL); + if (size != NULL) *size = tbs->size; close(tbs->fd); free(tbs); } +static const struct apk_bstream_ops tee_bstream_ops = { + .get_meta = tee_get_meta, + .read = tee_read, + .close = tee_close, +}; + struct apk_bstream *apk_bstream_tee(struct apk_bstream *from, int atfd, const char *to, apk_progress_cb cb, void *cb_ctx) { struct apk_tee_bstream *tbs; @@ -493,7 +509,7 @@ struct apk_bstream *apk_bstream_tee(struct apk_bstream *from, int atfd, const ch S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH); if (fd < 0) { r = errno; - from->close(from, NULL); + apk_bstream_close(from, NULL); return ERR_PTR(-r); } @@ -501,14 +517,12 @@ struct apk_bstream *apk_bstream_tee(struct apk_bstream *from, int atfd, const ch if (!tbs) { r = errno; close(fd); - from->close(from, NULL); + apk_bstream_close(from, NULL); return ERR_PTR(-r); } tbs->bs = (struct apk_bstream) { - .get_meta = tee_get_meta, - .read = tee_read, - .close = tee_close, + .ops = &tee_bstream_ops, }; tbs->inner_bs = from; tbs->fd = fd; @@ -528,7 +542,7 @@ apk_blob_t apk_blob_from_istream(struct apk_istream *is, size_t size) if (ptr == NULL) return APK_BLOB_NULL; - rsize = is->read(is, ptr, size); + rsize = apk_istream_read(is, ptr, size); if (rsize < 0) { free(ptr); return APK_BLOB_NULL; @@ -720,12 +734,12 @@ int apk_fileinfo_get(int atfd, const char *filename, unsigned int flags, EVP_DigestInit(&mdctx, apk_checksum_evp(checksum)); if (bs->flags & APK_BSTREAM_SINGLE_READ) EVP_MD_CTX_set_flags(&mdctx, EVP_MD_CTX_FLAG_ONESHOT); - while (!APK_BLOB_IS_NULL(blob = bs->read(bs, APK_BLOB_NULL))) + while (!APK_BLOB_IS_NULL(blob = apk_bstream_read(bs, APK_BLOB_NULL))) EVP_DigestUpdate(&mdctx, (void*) blob.ptr, blob.len); fi->csum.type = EVP_MD_CTX_size(&mdctx); EVP_DigestFinal(&mdctx, fi->csum.data, NULL); - bs->close(bs, NULL); + apk_bstream_close(bs, NULL); } } @@ -865,6 +879,11 @@ static int fdo_close(void *stream) return rc; } +static const struct apk_ostream_ops fd_ostream_ops = { + .write = fdo_write, + .close = fdo_close, +}; + struct apk_ostream *apk_ostream_to_fd(int fd) { struct apk_fd_ostream *fos; @@ -878,8 +897,7 @@ struct apk_ostream *apk_ostream_to_fd(int fd) } *fos = (struct apk_fd_ostream) { - .os.write = fdo_write, - .os.close = fdo_close, + .os.ops = &fd_ostream_ops, .fd = fd, }; @@ -935,6 +953,11 @@ static int co_close(void *stream) return 0; } +static const struct apk_ostream_ops counter_ostream_ops = { + .write = co_write, + .close = co_close, +}; + struct apk_ostream *apk_ostream_counter(off_t *counter) { struct apk_counter_ostream *cos; @@ -944,8 +967,7 @@ struct apk_ostream *apk_ostream_counter(off_t *counter) return NULL; *cos = (struct apk_counter_ostream) { - .os.write = co_write, - .os.close = co_close, + .os.ops = &counter_ostream_ops, .counter = counter, }; @@ -957,7 +979,7 @@ size_t apk_ostream_write_string(struct apk_ostream *os, const char *string) size_t len; len = strlen(string); - if (os->write(os, string, len) != len) + if (apk_ostream_write(os, string, len) != len) return -1; return len; diff --git a/src/manifest.c b/src/manifest.c index c7ab789726..56c9d68f22 100644 --- a/src/manifest.c +++ b/src/manifest.c @@ -100,7 +100,7 @@ static void process_file(struct apk_database *db, const char *match) } (void) apk_tar_parse(is, read_file_entry, &ctx, FALSE, &db->id_cache); - is->close(is); + apk_istream_close(is); } static void process_match(struct apk_database *db, const char *match, struct apk_name *name, void *ctx) diff --git a/src/package.c b/src/package.c index 0bb37473c5..4582b10996 100644 --- a/src/package.c +++ b/src/package.c @@ -434,7 +434,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) || - os->write(os, blob.ptr, blob.len) != blob.len) + apk_ostream_write(os, blob.ptr, blob.len) != blob.len) return -1; n += blob.len; @@ -930,7 +930,7 @@ int apk_pkg_read(struct apk_database *db, const char *file, tar = apk_bstream_gunzip_mpart(bs, apk_sign_ctx_mpart_cb, sctx); r = apk_tar_parse(tar, read_info_entry, &ctx, FALSE, &db->id_cache); - tar->close(tar); + apk_istream_close(tar); if (r < 0 && r != -ECANCELED) goto err; if (ctx.pkg->name == NULL || ctx.pkg->uninstallable) { @@ -979,7 +979,7 @@ int apk_ipkg_add_script(struct apk_installed_package *ipkg, return -1; ptr = malloc(size); - r = is->read(is, ptr, size); + r = apk_istream_read(is, ptr, size); if (r < 0) { free(ptr); return r; @@ -1073,17 +1073,10 @@ static int write_depends(struct apk_ostream *os, const char *field, { int r; - if (deps->num == 0) - return 0; - - if (os->write(os, field, 2) != 2) - return -1; - r = apk_deps_write(NULL, deps, os, APK_BLOB_PTR_LEN(" ", 1)); - if (r < 0) - return r; - if (os->write(os, "\n", 1) != 1) - return -1; - + if (deps->num == 0) return 0; + if (apk_ostream_write(os, field, 2) != 2) 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; return 0; } @@ -1138,7 +1131,7 @@ int apk_pkg_write_index_entry(struct apk_package *info, } bbuf = apk_blob_pushed(APK_BLOB_BUF(buf), bbuf); - if (os->write(os, bbuf.ptr, bbuf.len) != bbuf.len || + if (apk_ostream_write(os, bbuf.ptr, bbuf.len) != bbuf.len || write_depends(os, "D:", info->depends) || write_depends(os, "p:", info->provides) || write_depends(os, "i:", info->install_if)) diff --git a/src/url.c b/src/url.c index 711755ac06..4d7c7e6d71 100644 --- a/src/url.c +++ b/src/url.c @@ -102,6 +102,12 @@ static void fetch_close(void *stream) free(fis); } +static const struct apk_istream_ops fetch_istream_ops = { + .get_meta = fetch_get_meta, + .read = fetch_read, + .close = fetch_close, +}; + static struct apk_istream *apk_istream_fetch(const char *url, time_t since) { struct apk_fetch_istream *fis; @@ -121,9 +127,7 @@ static struct apk_istream *apk_istream_fetch(const char *url, time_t since) } *fis = (struct apk_fetch_istream) { - .is.get_meta = fetch_get_meta, - .is.read = fetch_read, - .is.close = fetch_close, + .is.ops = &fetch_istream_ops, .fetchIO = io, .urlstat = fis->urlstat, }; diff --git a/src/verify.c b/src/verify.c index 986e3c9109..8dc2efee7b 100644 --- a/src/verify.c +++ b/src/verify.c @@ -38,7 +38,7 @@ static int verify_main(void *ctx, struct apk_database *db, struct apk_string_arr continue; } r = apk_tar_parse(is, apk_sign_ctx_verify_tar, &sctx, FALSE, &db->id_cache); - is->close(is); + apk_istream_close(is); ok = sctx.control_verified && sctx.data_verified; if (apk_verbosity >= 1) apk_message("%s: %d - %s", *parg, r, -- cgit v1.2.3