summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorTimo Teräs <timo.teras@iki.fi>2020-05-19 11:39:21 +0300
committerTimo Teräs <timo.teras@iki.fi>2020-05-19 12:02:56 +0300
commitd0edeec8fb8fa5abee8b3065cea5e4882d0c51c4 (patch)
tree10dbc6d72c9cef13a26cb539df43e92e4bf78d74
parent12fdf6fc219321d22825042ae08efd322acc0310 (diff)
downloadapk-tools-d0edeec8fb8fa5abee8b3065cea5e4882d0c51c4.tar.gz
apk-tools-d0edeec8fb8fa5abee8b3065cea5e4882d0c51c4.tar.bz2
apk-tools-d0edeec8fb8fa5abee8b3065cea5e4882d0c51c4.tar.xz
apk-tools-d0edeec8fb8fa5abee8b3065cea5e4882d0c51c4.zip
make the atom functions not use global state
This greatly helps with memory management on applications that may want to daemonize and open/close database several times. Also the lifetime and "owner" of memory for all data is now explicitly bound to owning struct apk_database, which might be helpful when writing language bindings. As side effect, the interned "atoms" are unique only within what apk_database, so comparing packages from different apk_database may not work as expected. Fixes #10697
-rw-r--r--src/Makefile2
-rw-r--r--src/apk.c1
-rw-r--r--src/apk_atom.h33
-rw-r--r--src/apk_blob.h5
-rw-r--r--src/apk_database.h2
-rw-r--r--src/apk_io.h3
-rw-r--r--src/app_add.c6
-rw-r--r--src/app_audit.c4
-rw-r--r--src/app_fetch.c4
-rw-r--r--src/app_index.c27
-rw-r--r--src/app_info.c2
-rw-r--r--src/app_list.c30
-rw-r--r--src/app_stats.c4
-rw-r--r--src/app_upgrade.c2
-rw-r--r--src/app_version.c2
-rw-r--r--src/atom.c64
-rw-r--r--src/blob.c76
-rw-r--r--src/commit.c4
-rw-r--r--src/database.c36
-rw-r--r--src/hash.c3
-rw-r--r--src/io.c11
-rw-r--r--src/lua-apk.c1
-rw-r--r--src/package.c18
-rw-r--r--src/solver.c24
24 files changed, 185 insertions, 179 deletions
diff --git a/src/Makefile b/src/Makefile
index 4a055ce..3bbd51e 100644
--- a/src/Makefile
+++ b/src/Makefile
@@ -18,7 +18,7 @@ ZLIB_LIBS := $(shell $(PKG_CONFIG) --libs zlib)
# Dynamic library
libapk.so.$(VERSION)-objs := \
common.o database.o package.o commit.o solver.o \
- version.o blob.o hash.o print.o \
+ version.o atom.o blob.o hash.o print.o \
io.o io_url.o io_gunzip.o io_archive.o
libapk.so.$(VERSION)-libs := libfetch/libfetch.a
diff --git a/src/apk.c b/src/apk.c
index 8fbc3e8..79aef3e 100644
--- a/src/apk.c
+++ b/src/apk.c
@@ -518,7 +518,6 @@ int main(int argc, char **argv)
memset(&dbopts, 0, sizeof(dbopts));
list_init(&dbopts.repository_list);
- apk_atom_init();
umask(0);
setup_terminal();
diff --git a/src/apk_atom.h b/src/apk_atom.h
new file mode 100644
index 0000000..1b6ad6c
--- /dev/null
+++ b/src/apk_atom.h
@@ -0,0 +1,33 @@
+/* apk_atom.h - Alpine Package Keeper (APK)
+ *
+ * Copyright (C) 2005-2008 Natanael Copa <n@tanael.org>
+ * Copyright (C) 2008-2020 Timo Teräs <timo.teras@iki.fi>
+ * All rights reserved.
+ *
+ * SPDX-License-Identifier: GPL-2.0-only
+ */
+
+#ifndef APK_ATOM_H
+#define APK_ATOM_H
+
+#include "apk_hash.h"
+#include "apk_blob.h"
+
+extern apk_blob_t apk_atom_null;
+
+struct apk_atom_pool {
+ struct apk_hash hash;
+};
+
+void apk_atom_init(struct apk_atom_pool *);
+void apk_atom_free(struct apk_atom_pool *);
+apk_blob_t *apk_atom_get(struct apk_atom_pool *atoms, apk_blob_t blob, int duplicate);
+
+static inline apk_blob_t *apk_atomize(struct apk_atom_pool *atoms, apk_blob_t blob) {
+ return apk_atom_get(atoms, blob, 0);
+}
+static inline apk_blob_t *apk_atomize_dup(struct apk_atom_pool *atoms, apk_blob_t blob) {
+ return apk_atom_get(atoms, blob, 1);
+}
+
+#endif
diff --git a/src/apk_blob.h b/src/apk_blob.h
index 84bd143..008666e 100644
--- a/src/apk_blob.h
+++ b/src/apk_blob.h
@@ -25,7 +25,6 @@ struct apk_blob {
};
typedef struct apk_blob apk_blob_t;
typedef int (*apk_blob_cb)(void *ctx, apk_blob_t blob);
-extern apk_blob_t apk_null_blob;
#define BLOB_FMT "%.*s"
#define BLOB_PRINTF(b) (int)(b).len, (b).ptr
@@ -130,10 +129,6 @@ void apk_blob_pull_base64(apk_blob_t *b, apk_blob_t to);
void apk_blob_pull_hexdump(apk_blob_t *b, apk_blob_t to);
int apk_blob_pull_blob_match(apk_blob_t *b, apk_blob_t match);
-void apk_atom_init(void);
-apk_blob_t *apk_blob_atomize(apk_blob_t blob);
-apk_blob_t *apk_blob_atomize_dup(apk_blob_t blob);
-
#if defined(__GLIBC__) && !defined(__UCLIBC__)
extern size_t strlcpy(char *dest, const char *src, size_t size);
#endif
diff --git a/src/apk_database.h b/src/apk_database.h
index dc6525f..3488031 100644
--- a/src/apk_database.h
+++ b/src/apk_database.h
@@ -12,6 +12,7 @@
#include "apk_version.h"
#include "apk_hash.h"
+#include "apk_atom.h"
#include "apk_archive.h"
#include "apk_package.h"
#include "apk_io.h"
@@ -166,6 +167,7 @@ struct apk_database {
struct apk_repository repos[APK_MAX_REPOS];
struct apk_repository_tag repo_tags[APK_MAX_TAGS];
struct apk_id_cache id_cache;
+ struct apk_atom_pool atoms;
struct {
struct apk_hash names;
diff --git a/src/apk_io.h b/src/apk_io.h
index e4759b0..18b8ecc 100644
--- a/src/apk_io.h
+++ b/src/apk_io.h
@@ -16,6 +16,7 @@
#include "apk_defines.h"
#include "apk_blob.h"
#include "apk_hash.h"
+#include "apk_atom.h"
struct apk_id_cache {
int root_fd;
@@ -167,7 +168,7 @@ int apk_blob_to_file(int atfd, const char *file, apk_blob_t b, unsigned int flag
#define APK_FI_XATTR_CSUM(x) (((x) & 0xff) << 8)
#define APK_FI_CSUM(x) (((x) & 0xff))
int apk_fileinfo_get(int atfd, const char *filename, unsigned int flags,
- struct apk_file_info *fi);
+ struct apk_file_info *fi, struct apk_atom_pool *atoms);
void apk_fileinfo_hash_xattr(struct apk_file_info *fi);
void apk_fileinfo_free(struct apk_file_info *fi);
diff --git a/src/app_add.c b/src/app_add.c
index fb6e0e0..1f6c875 100644
--- a/src/app_add.c
+++ b/src/app_add.c
@@ -100,9 +100,9 @@ static struct apk_package *create_virtual_package(struct apk_database *db, struc
if (virtpkg == NULL) return 0;
virtpkg->name = name;
- virtpkg->version = apk_blob_atomize_dup(APK_BLOB_STR(ver));
+ virtpkg->version = apk_atomize_dup(&db->atoms, APK_BLOB_STR(ver));
virtpkg->description = strdup("virtual meta package");
- virtpkg->arch = apk_blob_atomize(APK_BLOB_STR("noarch"));
+ virtpkg->arch = apk_atomize(&db->atoms, APK_BLOB_STR("noarch"));
mdctx = EVP_MD_CTX_new();
EVP_DigestInit_ex(mdctx, apk_checksum_default(), NULL);
@@ -135,7 +135,7 @@ static int add_main(void *ctx, struct apk_database *db, struct apk_string_array
apk_blob_pull_dep(&b, db, &virtdep);
if (APK_BLOB_IS_NULL(b) || virtdep.conflict ||
virtdep.result_mask != APK_DEPMASK_ANY ||
- virtdep.version != &apk_null_blob) {
+ virtdep.version != &apk_atom_null) {
apk_error("%s: bad package specifier");
return -1;
}
diff --git a/src/app_audit.c b/src/app_audit.c
index fb2a0ee..011a26c 100644
--- a/src/app_audit.c
+++ b/src/app_audit.c
@@ -107,7 +107,7 @@ static int audit_file(struct audit_ctx *actx,
APK_FI_NOFOLLOW |
APK_FI_XATTR_CSUM(dbf->acl->xattr_csum.type ?: APK_CHECKSUM_DEFAULT) |
APK_FI_CSUM(dbf->csum.type),
- &fi) != 0)
+ &fi, &db->atoms) != 0)
return -EPERM;
if (dbf->csum.type != APK_CHECKSUM_NONE &&
@@ -183,7 +183,7 @@ static int audit_directory_tree_item(void *ctx, int dirfd, const char *name)
int reason = 0;
if (bdir.len + bent.len + 1 >= sizeof(atctx->path)) return 0;
- if (apk_fileinfo_get(dirfd, name, APK_FI_NOFOLLOW, &fi) < 0) return 0;
+ if (apk_fileinfo_get(dirfd, name, APK_FI_NOFOLLOW, &fi, &db->atoms) < 0) return 0;
memcpy(&atctx->path[atctx->pathlen], bent.ptr, bent.len);
atctx->pathlen += bent.len;
diff --git a/src/app_fetch.c b/src/app_fetch.c
index 8e73c0e..e6f4fbe 100644
--- a/src/app_fetch.c
+++ b/src/app_fetch.c
@@ -145,7 +145,7 @@ static int fetch_package(apk_hash_item item, void *pctx)
}
if (!(ctx->flags & FETCH_STDOUT)) {
- if (apk_fileinfo_get(ctx->outdir_fd, filename, APK_CHECKSUM_NONE, &fi) == 0 &&
+ if (apk_fileinfo_get(ctx->outdir_fd, filename, APK_CHECKSUM_NONE, &fi, &db->atoms) == 0 &&
fi.size == pkg->size)
return 0;
}
@@ -227,7 +227,7 @@ static void mark_name_flags(struct apk_database *db, const char *match, struct a
struct fetch_ctx *ctx = (struct fetch_ctx *) pctx;
struct apk_dependency dep = (struct apk_dependency) {
.name = name,
- .version = &apk_null_blob,
+ .version = &apk_atom_null,
.result_mask = APK_DEPMASK_ANY,
};
diff --git a/src/app_index.c b/src/app_index.c
index 4c0b0d1..53e53b0 100644
--- a/src/app_index.c
+++ b/src/app_index.c
@@ -27,7 +27,7 @@ struct index_ctx {
const char *index;
const char *output;
const char *description;
- apk_blob_t *rewrite_arch;
+ const char *rewrite_arch;
time_t index_mtime;
int method;
unsigned short index_flags;
@@ -64,7 +64,7 @@ static int option_parse_applet(void *ctx, struct apk_db_options *dbopts, int opt
ictx->output = optarg;
break;
case OPT_INDEX_rewrite_arch:
- ictx->rewrite_arch = apk_blob_atomize(APK_BLOB_STR(optarg));
+ ictx->rewrite_arch = optarg;
break;
case OPT_INDEX_no_warnings:
ictx->index_flags |= APK_INDEXF_NO_WARNINGS;
@@ -86,7 +86,7 @@ static int index_read_file(struct apk_database *db, struct index_ctx *ictx)
if (ictx->index == NULL)
return 0;
- if (apk_fileinfo_get(AT_FDCWD, ictx->index, APK_CHECKSUM_NONE, &fi) < 0)
+ if (apk_fileinfo_get(AT_FDCWD, ictx->index, APK_CHECKSUM_NONE, &fi, &db->atoms) < 0)
return 0;
ictx->index_mtime = fi.mtime;
@@ -121,6 +121,7 @@ static int index_main(void *ctx, struct apk_database *db, struct apk_string_arra
struct index_ctx *ictx = (struct index_ctx *) ctx;
struct apk_package *pkg;
char **parg;
+ apk_blob_t *rewrite_arch = NULL;
if (isatty(STDOUT_FILENO) && ictx->output == NULL &&
!(apk_force & APK_FORCE_BINARY_STDOUT)) {
@@ -137,8 +138,11 @@ static int index_main(void *ctx, struct apk_database *db, struct apk_string_arra
return r;
}
+ if (ictx->rewrite_arch)
+ rewrite_arch = apk_atomize(&db->atoms, APK_BLOB_STR(ictx->rewrite_arch));
+
foreach_array_item(parg, args) {
- if (apk_fileinfo_get(AT_FDCWD, *parg, APK_CHECKSUM_NONE, &fi) < 0) {
+ if (apk_fileinfo_get(AT_FDCWD, *parg, APK_CHECKSUM_NONE, &fi, &db->atoms) < 0) {
apk_warning("File '%s' is unaccessible", *parg);
continue;
}
@@ -174,15 +178,11 @@ static int index_main(void *ctx, struct apk_database *db, struct apk_string_arra
foreach_array_item(p, name->providers) {
pkg = p->pkg;
- if (pkg->name != name)
- continue;
- if (apk_blob_compare(bver, *pkg->version) != 0)
- continue;
- if (pkg->size != fi.size)
- continue;
+ if (pkg->name != name) continue;
+ if (apk_blob_compare(bver, *pkg->version) != 0) continue;
+ if (pkg->size != fi.size) continue;
pkg->filename = strdup(*parg);
- if (ictx->rewrite_arch != NULL)
- pkg->arch = ictx->rewrite_arch;
+ if (rewrite_arch) pkg->arch = rewrite_arch;
found = TRUE;
break;
}
@@ -197,8 +197,7 @@ static int index_main(void *ctx, struct apk_database *db, struct apk_string_arra
errors++;
} else {
newpkgs++;
- if (ictx->rewrite_arch != NULL)
- pkg->arch = ictx->rewrite_arch;
+ if (rewrite_arch) pkg->arch = rewrite_arch;
}
apk_sign_ctx_free(&sctx);
}
diff --git a/src/app_info.c b/src/app_info.c
index 41d6a99..b444b80 100644
--- a/src/app_info.c
+++ b/src/app_info.c
@@ -125,7 +125,7 @@ static void info_who_owns(struct info_ctx *ctx, struct apk_database *db,
if (apk_verbosity < 1) {
dep = (struct apk_dependency) {
.name = pkg->name,
- .version = apk_blob_atomize(APK_BLOB_NULL),
+ .version = &apk_atom_null,
.result_mask = APK_DEPMASK_ANY,
};
apk_deps_add(&deps, &dep);
diff --git a/src/app_list.c b/src/app_list.c
index ab5c846..24d1a88 100644
--- a/src/app_list.c
+++ b/src/app_list.c
@@ -67,33 +67,25 @@ static const struct apk_package *is_upgradable(struct apk_name *name, const stru
{
struct apk_provider *p;
struct apk_package *ipkg;
- apk_blob_t *latest = apk_blob_atomize(APK_BLOB_STR(""));
+ apk_blob_t no_version = APK_BLOB_STR("");
+ apk_blob_t *latest = &no_version;
+ int r;
- if (name == NULL)
- return NULL;
+ if (!name) return NULL;
ipkg = apk_pkg_get_installed(name);
- if (ipkg == NULL)
- return NULL;
+ if (!ipkg) return NULL;
- if (pkg0 == NULL)
- {
- foreach_array_item(p, name->providers)
- {
+ if (!pkg0) {
+ foreach_array_item(p, name->providers) {
pkg0 = p->pkg;
- int r;
-
- if (pkg0 == ipkg)
- continue;
-
+ if (pkg0 == ipkg) continue;
r = apk_version_compare_blob(*pkg0->version, *latest);
- if (r == APK_VERSION_GREATER)
- latest = pkg0->version;
+ if (r == APK_VERSION_GREATER) latest = pkg0->version;
}
- }
- else
+ } else {
latest = pkg0->version;
-
+ }
return apk_version_compare_blob(*ipkg->version, *latest) == APK_VERSION_LESS ? ipkg : NULL;
}
diff --git a/src/app_stats.c b/src/app_stats.c
index 583e4c6..7e60494 100644
--- a/src/app_stats.c
+++ b/src/app_stats.c
@@ -24,8 +24,6 @@ static int list_count(struct list_head *h)
static int stats_main(void *ctx, struct apk_database *db, struct apk_string_array *args)
{
- extern struct apk_hash atom_hash;
-
printf(
"installed:\n"
" packages: %d\n"
@@ -46,7 +44,7 @@ static int stats_main(void *ctx, struct apk_database *db, struct apk_string_arra
list_count(&db->installed.triggers),
db->available.names.num_items,
db->available.packages.num_items,
- atom_hash.num_items
+ db->atoms.hash.num_items
);
return 0;
}
diff --git a/src/app_upgrade.c b/src/app_upgrade.c
index 0c8d4dd..7e5347f 100644
--- a/src/app_upgrade.c
+++ b/src/app_upgrade.c
@@ -174,7 +174,7 @@ static int upgrade_main(void *ctx, struct apk_database *db, struct apk_string_ar
foreach_array_item(dep, world) {
if (dep->result_mask == APK_DEPMASK_CHECKSUM) {
dep->result_mask = APK_DEPMASK_ANY;
- dep->version = apk_blob_atomize(APK_BLOB_NULL);
+ dep->version = &apk_atom_null;
}
}
} else {
diff --git a/src/app_version.c b/src/app_version.c
index df2506c..2dc3bcd 100644
--- a/src/app_version.c
+++ b/src/app_version.c
@@ -121,7 +121,7 @@ static void ver_print_package_status(struct apk_database *db, const char *match,
struct apk_provider *p0;
char pkgname[41];
const char *opstr;
- apk_blob_t *latest = apk_blob_atomize(APK_BLOB_STR(""));
+ apk_blob_t *latest = apk_atomize(&db->atoms, APK_BLOB_STR(""));
unsigned int latest_repos = 0;
int i, r = -1;
unsigned short tag, allowed_repos;
diff --git a/src/atom.c b/src/atom.c
new file mode 100644
index 0000000..e2ff83e
--- /dev/null
+++ b/src/atom.c
@@ -0,0 +1,64 @@
+/* apk_atom.c - Alpine Package Keeper (APK)
+ *
+ * Copyright (C) 2005-2008 Natanael Copa <n@tanael.org>
+ * Copyright (C) 2008-2020 Timo Teräs <timo.teras@iki.fi>
+ * All rights reserved.
+ *
+ * SPDX-License-Identifier: GPL-2.0-only
+ */
+
+#include "apk_atom.h"
+
+apk_blob_t apk_atom_null = APK_BLOB_NULL;
+
+struct apk_atom_hashnode {
+ struct hlist_node hash_node;
+ apk_blob_t blob;
+};
+
+static apk_blob_t atom_hash_get_key(apk_hash_item item)
+{
+ return ((struct apk_atom_hashnode *) item)->blob;
+}
+
+static struct apk_hash_ops atom_ops = {
+ .node_offset = offsetof(struct apk_atom_hashnode, hash_node),
+ .get_key = atom_hash_get_key,
+ .hash_key = apk_blob_hash,
+ .compare = apk_blob_compare,
+ .delete_item = (apk_hash_delete_f) free,
+};
+
+void apk_atom_init(struct apk_atom_pool *atoms)
+{
+ apk_hash_init(&atoms->hash, &atom_ops, 10000);
+}
+
+void apk_atom_free(struct apk_atom_pool *atoms)
+{
+ apk_hash_free(&atoms->hash);
+}
+
+apk_blob_t *apk_atom_get(struct apk_atom_pool *atoms, apk_blob_t blob, int duplicate)
+{
+ struct apk_atom_hashnode *atom;
+ unsigned long hash = apk_hash_from_key(&atoms->hash, blob);
+
+ if (blob.len < 0 || !blob.ptr) return &apk_atom_null;
+
+ atom = (struct apk_atom_hashnode *) apk_hash_get_hashed(&atoms->hash, blob, hash);
+ if (atom) return &atom->blob;
+
+ if (duplicate) {
+ char *ptr;
+ atom = malloc(sizeof(*atom) + blob.len);
+ ptr = (char*) (atom + 1);
+ memcpy(ptr, blob.ptr, blob.len);
+ atom->blob = APK_BLOB_PTR_LEN(ptr, blob.len);
+ } else {
+ atom = malloc(sizeof(*atom));
+ atom->blob = blob;
+ }
+ apk_hash_insert_hashed(&atoms->hash, atom, hash);
+ return &atom->blob;
+}
diff --git a/src/blob.c b/src/blob.c
index 72b9fd6..1a63686 100644
--- a/src/blob.c
+++ b/src/blob.c
@@ -15,11 +15,6 @@
#include "apk_blob.h"
#include "apk_hash.h"
-struct apk_blob_atom {
- struct hlist_node hash_node;
- apk_blob_t blob;
-};
-
char *apk_blob_cstr(apk_blob_t blob)
{
char *cstr;
@@ -640,77 +635,6 @@ err:
*b = APK_BLOB_NULL;
}
-static apk_blob_t atom_hash_get_key(apk_hash_item item)
-{
- return ((struct apk_blob_atom *) item)->blob;
-}
-
-struct apk_hash atom_hash;
-static struct apk_hash_ops atom_ops = {
- .node_offset = offsetof(struct apk_blob_atom, hash_node),
- .get_key = atom_hash_get_key,
- .hash_key = apk_blob_hash,
- .compare = apk_blob_compare,
- .delete_item = (apk_hash_delete_f) free,
-};
-
-apk_blob_t apk_null_blob = {0,0};
-
-#ifdef VALGRIND
-static void apk_atom_fini(void)
-{
- apk_hash_free(&atom_hash);
-}
-#endif
-
-void apk_atom_init(void)
-{
-#ifdef VALGRIND
- atexit(apk_atom_fini);
-#endif
- apk_hash_init(&atom_hash, &atom_ops, 10000);
-}
-
-apk_blob_t *apk_blob_atomize(apk_blob_t blob)
-{
- struct apk_blob_atom *atom;
- unsigned long hash = apk_hash_from_key(&atom_hash, blob);
-
- if (blob.len < 0 || blob.ptr == NULL)
- return &apk_null_blob;
-
- atom = (struct apk_blob_atom *) apk_hash_get_hashed(&atom_hash, blob, hash);
- if (atom != NULL)
- return &atom->blob;
-
- atom = malloc(sizeof(*atom));
- atom->blob = blob;
- apk_hash_insert_hashed(&atom_hash, atom, hash);
-
- return &atom->blob;
-}
-
-apk_blob_t *apk_blob_atomize_dup(apk_blob_t blob)
-{
- struct apk_blob_atom *atom;
- unsigned long hash = apk_hash_from_key(&atom_hash, blob);
- char *ptr;
-
- if (blob.len < 0 || blob.ptr == NULL)
- return &apk_null_blob;
- atom = (struct apk_blob_atom *) apk_hash_get_hashed(&atom_hash, blob, hash);
- if (atom != NULL)
- return &atom->blob;
-
- atom = malloc(sizeof(*atom) + blob.len);
- ptr = (char*) (atom + 1);
- memcpy(ptr, blob.ptr, blob.len);
- atom->blob = APK_BLOB_PTR_LEN(ptr, blob.len);
- apk_hash_insert_hashed(&atom_hash, atom, hash);
-
- return &atom->blob;
-}
-
#if defined(__GLIBC__) && !defined(__UCLIBC__)
size_t strlcpy(char *dst, const char *src, size_t size)
{
diff --git a/src/commit.c b/src/commit.c
index 8c337e3..b82607c 100644
--- a/src/commit.c
+++ b/src/commit.c
@@ -453,8 +453,8 @@ static void print_conflicts(struct print_state *ps, struct apk_package *pkg)
foreach_array_item(p, d->name->providers) {
if (!p->pkg->marked)
continue;
- if (d->version == &apk_null_blob &&
- p->version == &apk_null_blob)
+ if (d->version == &apk_atom_null &&
+ p->version == &apk_atom_null)
continue;
if (once && p->pkg == pkg &&
p->version == d->version) {
diff --git a/src/database.c b/src/database.c
index 65d07e2..d113d6a 100644
--- a/src/database.c
+++ b/src/database.c
@@ -225,7 +225,7 @@ struct apk_name *apk_db_get_name(struct apk_database *db, apk_blob_t name)
return pn;
}
-static struct apk_db_acl *apk_db_acl_atomize(mode_t mode, uid_t uid, gid_t gid, const struct apk_checksum *xattr_csum)
+static struct apk_db_acl *apk_db_acl_atomize(struct apk_database *db, mode_t mode, uid_t uid, gid_t gid, const struct apk_checksum *xattr_csum)
{
struct apk_db_acl acl = { .mode = mode & 07777, .uid = uid, .gid = gid };
apk_blob_t *b;
@@ -233,7 +233,7 @@ static struct apk_db_acl *apk_db_acl_atomize(mode_t mode, uid_t uid, gid_t gid,
if (xattr_csum && xattr_csum->type != APK_CHECKSUM_NONE)
acl.xattr_csum = *xattr_csum;
- b = apk_blob_atomize_dup(APK_BLOB_STRUCT(acl));
+ b = apk_atomize_dup(&db->atoms, APK_BLOB_STRUCT(acl));
return (struct apk_db_acl *) b->ptr;
}
@@ -518,8 +518,7 @@ struct apk_package *apk_db_pkg_add(struct apk_database *db, struct apk_package *
struct apk_package *idb;
struct apk_dependency *dep;
- if (pkg->license == NULL)
- pkg->license = apk_blob_atomize(APK_BLOB_NULL);
+ if (!pkg->license) pkg->license = &apk_atom_null;
/* Set as "cached" if installing from specified file, and
* for virtual packages */
@@ -848,7 +847,7 @@ int apk_db_index_read(struct apk_database *db, struct apk_istream *is, int repo)
else
xattr_csum.type = APK_CHECKSUM_NONE;
- acl = apk_db_acl_atomize(mode, uid, gid, &xattr_csum);
+ acl = apk_db_acl_atomize(db, mode, uid, gid, &xattr_csum);
if (field == 'M')
diri->acl = acl;
else
@@ -1501,6 +1500,7 @@ void apk_db_init(struct apk_database *db)
apk_hash_init(&db->available.packages, &pkg_info_hash_ops, 10000);
apk_hash_init(&db->installed.dirs, &dir_hash_ops, 20000);
apk_hash_init(&db->installed.files, &file_hash_ops, 200000);
+ apk_atom_init(&db->atoms);
list_init(&db->installed.packages);
list_init(&db->installed.triggers);
apk_dependency_array_init(&db->world);
@@ -1517,8 +1517,8 @@ int apk_db_open(struct apk_database *db, struct apk_db_options *dbopts)
apk_blob_t blob;
int r, fd, write_arch = FALSE;
- apk_default_acl_dir = apk_db_acl_atomize(0755, 0, 0, NULL);
- apk_default_acl_file = apk_db_acl_atomize(0644, 0, 0, NULL);
+ apk_default_acl_dir = apk_db_acl_atomize(db, 0755, 0, 0, NULL);
+ apk_default_acl_file = apk_db_acl_atomize(db, 0644, 0, 0, NULL);
if (apk_flags & APK_SIMULATE) {
dbopts->open_flags &= ~(APK_OPENF_CREATE | APK_OPENF_WRITE);
@@ -1553,16 +1553,16 @@ int apk_db_open(struct apk_database *db, struct apk_db_options *dbopts)
db->permanent = 0;
if (dbopts->root && dbopts->arch) {
- db->arch = apk_blob_atomize(APK_BLOB_STR(dbopts->arch));
+ db->arch = apk_atomize(&db->atoms, APK_BLOB_STR(dbopts->arch));
write_arch = TRUE;
} else {
apk_blob_t arch;
arch = apk_blob_from_file(db->root_fd, apk_arch_file);
if (!APK_BLOB_IS_NULL(arch)) {
- db->arch = apk_blob_atomize_dup(apk_blob_trim(arch));
+ db->arch = apk_atomize_dup(&db->atoms, apk_blob_trim(arch));
free(arch.ptr);
} else {
- db->arch = apk_blob_atomize(APK_BLOB_STR(APK_DEFAULT_ARCH));
+ db->arch = apk_atomize(&db->atoms, APK_BLOB_STR(APK_DEFAULT_ARCH));
write_arch = TRUE;
}
}
@@ -1820,6 +1820,7 @@ void apk_db_close(struct apk_database *db)
apk_hash_free(&db->available.names);
apk_hash_free(&db->installed.files);
apk_hash_free(&db->installed.dirs);
+ apk_atom_free(&db->atoms);
if (db->root_proc_dir) {
umount2(db->root_proc_dir, MNT_DETACH|UMOUNT_NOFOLLOW);
@@ -1867,12 +1868,12 @@ int apk_db_get_tag_id(struct apk_database *db, apk_blob_t tag)
db->num_repo_tags++;
if (tag.ptr[0] == '@') {
- db->repo_tags[i].tag = *apk_blob_atomize_dup(tag);
+ db->repo_tags[i].tag = *apk_atomize_dup(&db->atoms, tag);
} else {
char *tmp = alloca(tag.len + 1);
tmp[0] = '@';
memcpy(&tmp[1], tag.ptr, tag.len);
- db->repo_tags[i].tag = *apk_blob_atomize_dup(APK_BLOB_PTR_LEN(tmp, tag.len+1));
+ db->repo_tags[i].tag = *apk_atomize_dup(&db->atoms, APK_BLOB_PTR_LEN(tmp, tag.len+1));
}
db->repo_tags[i].plain_name = db->repo_tags[i].tag;
@@ -2551,7 +2552,7 @@ static int apk_db_install_archive_entry(void *_ctx,
apk_message("%s", ae->name);
/* Extract the file with temporary name */
- file->acl = apk_db_acl_atomize(ae->mode, ae->uid, ae->gid, &ae->xattr_csum);
+ file->acl = apk_db_acl_atomize(db, ae->mode, ae->uid, ae->gid, &ae->xattr_csum);
r = apk_archive_entry_extract(
db->root_fd, ae,
format_tmpname(pkg, file, tmpname_file),
@@ -2592,7 +2593,7 @@ static int apk_db_install_archive_entry(void *_ctx,
diri = apk_db_install_directory_entry(ctx, name);
apk_db_dir_prepare(db, diri->dir, ae->mode);
}
- apk_db_diri_set(diri, apk_db_acl_atomize(ae->mode, ae->uid, ae->gid, &ae->xattr_csum));
+ apk_db_diri_set(diri, apk_db_acl_atomize(db, ae->mode, ae->uid, ae->gid, &ae->xattr_csum));
}
ctx->installed_size += ctx->current_file_size;
@@ -2628,7 +2629,7 @@ static void apk_db_purge_pkg(struct apk_database *db,
if ((diri->dir->protect_mode == APK_PROTECT_NONE) ||
(apk_flags & APK_PURGE) ||
(file->csum.type != APK_CHECKSUM_NONE &&
- apk_fileinfo_get(db->root_fd, name, APK_FI_NOFOLLOW | file->csum.type, &fi) == 0 &&
+ apk_fileinfo_get(db->root_fd, name, APK_FI_NOFOLLOW | file->csum.type, &fi, &db->atoms) == 0 &&
apk_checksum_compare(&file->csum, &fi.csum) == 0))
unlinkat(db->root_fd, name, 0);
if (apk_verbosity >= 3)
@@ -2684,7 +2685,7 @@ static void apk_db_migrate_files(struct apk_database *db,
cstype = ofile->csum.type;
cstype |= APK_FI_NOFOLLOW;
- r = apk_fileinfo_get(db->root_fd, name, cstype, &fi);
+ r = apk_fileinfo_get(db->root_fd, name, cstype, &fi, &db->atoms);
if (ofile && ofile->diri->pkg->name == NULL) {
/* File was from overlay, delete the
* packages version */
@@ -2702,7 +2703,8 @@ static void apk_db_migrate_files(struct apk_database *db,
if (ofile == NULL ||
ofile->csum.type != file->csum.type)
apk_fileinfo_get(db->root_fd, name,
- APK_FI_NOFOLLOW | file->csum.type, &fi);
+ APK_FI_NOFOLLOW | file->csum.type,
+ &fi, &db->atoms);
if ((apk_flags & APK_CLEAN_PROTECTED) ||
(file->csum.type != APK_CHECKSUM_NONE &&
apk_checksum_compare(&file->csum, &fi.csum) == 0)) {
diff --git a/src/hash.c b/src/hash.c
index 28301d4..6835ddf 100644
--- a/src/hash.c
+++ b/src/hash.c
@@ -93,6 +93,7 @@ void apk_hash_delete_hashed(struct apk_hash *h, apk_blob_t key, unsigned long ha
if (h->ops->compare_item(item, key) == 0) {
hlist_del(pos, &h->buckets->item[hash]);
h->ops->delete_item(item);
+ h->num_items--;
break;
}
}
@@ -103,9 +104,9 @@ void apk_hash_delete_hashed(struct apk_hash *h, apk_blob_t key, unsigned long ha
if (h->ops->compare(key, itemkey) == 0) {
hlist_del(pos, &h->buckets->item[hash]);
h->ops->delete_item(item);
+ h->num_items--;
break;
}
}
}
}
-
diff --git a/src/io.c b/src/io.c
index 92f1a32..9643218 100644
--- a/src/io.c
+++ b/src/io.c
@@ -692,7 +692,7 @@ void apk_fileinfo_hash_xattr(struct apk_file_info *fi)
}
int apk_fileinfo_get(int atfd, const char *filename, unsigned int flags,
- struct apk_file_info *fi)
+ struct apk_file_info *fi, struct apk_atom_pool *atoms)
{
struct stat64 st;
unsigned int checksum = flags & 0xff;
@@ -735,7 +735,7 @@ int apk_fileinfo_get(int atfd, const char *filename, unsigned int flags,
}
*apk_xattr_array_add(&xattrs) = (struct apk_xattr) {
.name = &buf[i],
- .value = *apk_blob_atomize_dup(APK_BLOB_PTR_LEN(val, vlen)),
+ .value = *apk_atomize_dup(atoms, APK_BLOB_PTR_LEN(val, vlen)),
};
}
apk_fileinfo_hash_xattr_array(xattrs, apk_checksum_evp(xattr_checksum), &fi->xattr_csum);
@@ -747,11 +747,8 @@ int apk_fileinfo_get(int atfd, const char *filename, unsigned int flags,
if (r && r != ENOTSUP) return -r;
}
- if (checksum == APK_CHECKSUM_NONE)
- return 0;
-
- if (S_ISDIR(st.st_mode))
- return 0;
+ if (checksum == APK_CHECKSUM_NONE) return 0;
+ if (S_ISDIR(st.st_mode)) return 0;
/* Checksum file content */
if ((flags & APK_FI_NOFOLLOW) && S_ISLNK(st.st_mode)) {
diff --git a/src/lua-apk.c b/src/lua-apk.c
index fa153e1..f653163 100644
--- a/src/lua-apk.c
+++ b/src/lua-apk.c
@@ -171,7 +171,6 @@ static int Papk_db_open(lua_State *L)
memset(&opts, 0, sizeof(opts));
list_init(&opts.repository_list);
- apk_atom_init();
if (lua_istable(L, 1))
get_dbopts(L, 1, &opts);
else
diff --git a/src/package.c b/src/package.c
index 4514ad7..5db77ec 100644
--- a/src/package.c
+++ b/src/package.c
@@ -259,7 +259,7 @@ void apk_blob_pull_dep(apk_blob_t *b, struct apk_database *db, struct apk_depend
*dep = (struct apk_dependency){
.name = name,
- .version = apk_blob_atomize_dup(bver),
+ .version = apk_atomize_dup(&db->atoms, bver),
.repository_tag = tag,
.result_mask = mask,
.conflict = conflict,
@@ -295,7 +295,7 @@ void apk_dep_from_pkg(struct apk_dependency *dep, struct apk_database *db,
*dep = (struct apk_dependency) {
.name = pkg->name,
- .version = apk_blob_atomize_dup(b),
+ .version = apk_atomize_dup(&db->atoms, b),
.result_mask = APK_DEPMASK_CHECKSUM,
};
}
@@ -323,7 +323,7 @@ int apk_dep_is_provided(struct apk_dependency *dep, struct apk_provider *p)
case APK_DEPMASK_ANY:
return !dep->conflict;
default:
- if (p->version == &apk_null_blob)
+ if (p->version == &apk_atom_null)
return dep->conflict;
if (apk_version_compare_blob_fuzzy(*p->version, *dep->version, dep->fuzzy)
& dep->result_mask)
@@ -779,7 +779,7 @@ int apk_pkg_add_info(struct apk_database *db, struct apk_package *pkg,
pkg->name = apk_db_get_name(db, value);
break;
case 'V':
- pkg->version = apk_blob_atomize_dup(value);
+ pkg->version = apk_atomize_dup(&db->atoms, value);
break;
case 'T':
pkg->description = apk_blob_cstr(value);
@@ -788,10 +788,10 @@ int apk_pkg_add_info(struct apk_database *db, struct apk_package *pkg,
pkg->url = apk_blob_cstr(value);
break;
case 'L':
- pkg->license = apk_blob_atomize_dup(value);
+ pkg->license = apk_atomize_dup(&db->atoms, value);
break;
case 'A':
- pkg->arch = apk_blob_atomize_dup(value);
+ pkg->arch = apk_atomize_dup(&db->atoms, value);
break;
case 'D':
apk_blob_pull_deps(&value, db, &pkg->depends);
@@ -812,10 +812,10 @@ int apk_pkg_add_info(struct apk_database *db, struct apk_package *pkg,
apk_blob_pull_deps(&value, db, &pkg->install_if);
break;
case 'o':
- pkg->origin = apk_blob_atomize_dup(value);
+ pkg->origin = apk_atomize_dup(&db->atoms, value);
break;
case 'm':
- pkg->maintainer = apk_blob_atomize_dup(value);
+ pkg->maintainer = apk_atomize_dup(&db->atoms, value);
break;
case 't':
pkg->build_time = apk_blob_pull_uint(&value, 10);
@@ -921,7 +921,7 @@ int apk_pkg_read(struct apk_database *db, const char *file,
struct apk_file_info fi;
int r;
- r = apk_fileinfo_get(AT_FDCWD, file, APK_CHECKSUM_NONE, &fi);
+ r = apk_fileinfo_get(AT_FDCWD, file, APK_CHECKSUM_NONE, &fi, &db->atoms);
if (r != 0)
return r;
diff --git a/src/solver.c b/src/solver.c
index 0881196..febf52d 100644
--- a/src/solver.c
+++ b/src/solver.c
@@ -42,7 +42,7 @@ struct apk_solver_state {
static struct apk_provider provider_none = {
.pkg = NULL,
- .version = &apk_null_blob
+ .version = &apk_atom_null
};
void apk_solver_set_name_flags(struct apk_name *name,
@@ -321,10 +321,10 @@ static void exclude_non_providers(struct apk_solver_state *ss, struct apk_name *
foreach_array_item(p, name->providers) {
if (p->pkg->name == must_provide || !p->pkg->ss.pkg_selectable ||
- (skip_virtuals && p->version == &apk_null_blob))
+ (skip_virtuals && p->version == &apk_atom_null))
goto next;
foreach_array_item(d, p->pkg->provides)
- if (d->name == must_provide || (skip_virtuals && d->version == &apk_null_blob))
+ if (d->name == must_provide || (skip_virtuals && d->version == &apk_atom_null))
goto next;
disqualify_package(ss, p->pkg, "provides transitivity");
next: ;
@@ -425,10 +425,10 @@ static void reconsider_name(struct apk_solver_state *ss, struct apk_name *name)
merge_index(&dep->name->ss.merge_depends, num_options);
if (merge_index(&pkg->name->ss.merge_provides, num_options))
- pkg->name->ss.has_virtual_provides |= (p->version == &apk_null_blob);
+ pkg->name->ss.has_virtual_provides |= (p->version == &apk_atom_null);
foreach_array_item(dep, pkg->provides)
if (merge_index(&dep->name->ss.merge_provides, num_options))
- dep->name->ss.has_virtual_provides |= (dep->version == &apk_null_blob);
+ dep->name->ss.has_virtual_provides |= (dep->version == &apk_atom_null);
num_tag_not_ok += !pkg->ss.tag_ok;
num_options++;
@@ -630,8 +630,8 @@ static void assign_name(struct apk_solver_state *ss, struct apk_name *name, stru
if (name->ss.locked) {
/* If both are providing this name without version, it's ok */
- if (p.version == &apk_null_blob &&
- name->ss.chosen.version == &apk_null_blob)
+ if (p.version == &apk_atom_null &&
+ name->ss.chosen.version == &apk_atom_null)
return;
if (ss->ignore_conflict)
return;
@@ -656,8 +656,8 @@ static void assign_name(struct apk_solver_state *ss, struct apk_name *name, stru
foreach_array_item(p0, name->providers) {
if (p0->pkg == p.pkg)
continue;
- if (p.version == &apk_null_blob &&
- p0->version == &apk_null_blob)
+ if (p.version == &apk_atom_null &&
+ p0->version == &apk_atom_null)
continue;
disqualify_package(ss, p0->pkg, "conflicting provides");
}
@@ -668,7 +668,7 @@ static void assign_name(struct apk_solver_state *ss, struct apk_name *name, stru
static void select_package(struct apk_solver_state *ss, struct apk_name *name)
{
- struct apk_provider chosen = { NULL, &apk_null_blob }, *p;
+ struct apk_provider chosen = { NULL, &apk_atom_null }, *p;
struct apk_package *pkg = NULL;
struct apk_dependency *d;
@@ -689,7 +689,7 @@ static void select_package(struct apk_solver_state *ss, struct apk_name *name)
continue;
/* Virtual packages without provider_priority cannot be autoselected,
* unless there is only one provider */
- if (p->version == &apk_null_blob &&
+ if (p->version == &apk_atom_null &&
p->pkg->name->auto_select_virtual == 0 &&
p->pkg->name->ss.requirers == 0 &&
(p->pkg->provider_priority == 0 && name->providers->num > 1))
@@ -934,7 +934,7 @@ static void generate_changeset(struct apk_solver_state *ss, struct apk_dependenc
pkg->name->ss.installed_pkg = pkg;
pkg->name->ss.installed_name = pkg->name;
foreach_array_item(d, pkg->provides)
- if (d->version != &apk_null_blob)
+ if (d->version != &apk_atom_null)
d->name->ss.installed_name = pkg->name;
}
list_for_each_entry(ipkg, &ss->db->installed.packages, installed_pkgs_list)