summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorTimo Teräs <timo.teras@iki.fi>2017-06-21 16:07:58 +0300
committerTimo Teräs <timo.teras@iki.fi>2017-06-23 10:07:44 +0300
commit4d9c0c39b033159f4bd6fe279dd38d4f4a67c904 (patch)
treeb316100ea8a03be653c8cb0c729577c24ebcae14
parentca9d476ba39d75b9a197f9ae30e5efe2ebafaf3c (diff)
downloadapk-tools-4d9c0c39b033159f4bd6fe279dd38d4f4a67c904.tar.bz2
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.
-rw-r--r--src/apk.c4
-rw-r--r--src/apk_io.h52
-rw-r--r--src/archive.c30
-rw-r--r--src/database.c52
-rw-r--r--src/fetch.c4
-rw-r--r--src/gunzip.c34
-rw-r--r--src/index.c4
-rw-r--r--src/info.c4
-rw-r--r--src/io.c94
-rw-r--r--src/manifest.c2
-rw-r--r--src/package.c23
-rw-r--r--src/url.c10
-rw-r--r--src/verify.c2
13 files changed, 195 insertions, 120 deletions
diff --git a/src/apk.c b/src/apk.c
index c990102..6cd4a5a 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 b0e15a4..b07035c 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 f84e440..438eb94 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 67cc4f5..4d16900 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 847146f..bb2efa9 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 d1eb0cb..4fac9fa 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 1c39e3c..45d371b 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 262049f..a1bc609 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 8cf867b..bfc9c1c 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 c7ab789..56c9d68 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 0bb3747..4582b10 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 711755a..4d7c7e6 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 986e3c9..8dc2efe 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,