summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorTimo Teräs <timo.teras@iki.fi>2021-07-23 14:39:38 +0300
committerTimo Teräs <timo.teras@iki.fi>2021-07-23 15:08:40 +0300
commitc13969849d6d072c22ae4a2eddb40c0974b70a31 (patch)
tree49b62b736c4e045f80ddf1d8556c04b999029b64
parent6854da9271bf30dc8273ca446dd5f18b4036c7a9 (diff)
downloadapk-tools-c13969849d6d072c22ae4a2eddb40c0974b70a31.tar.gz
apk-tools-c13969849d6d072c22ae4a2eddb40c0974b70a31.tar.bz2
apk-tools-c13969849d6d072c22ae4a2eddb40c0974b70a31.tar.xz
apk-tools-c13969849d6d072c22ae4a2eddb40c0974b70a31.zip
db: allow read-only operations without cache
fixes #10748
-rw-r--r--src/apk_defines.h1
-rw-r--r--src/database.c20
-rw-r--r--src/io.c17
-rw-r--r--src/print.c2
4 files changed, 29 insertions, 11 deletions
diff --git a/src/apk_defines.h b/src/apk_defines.h
index e4f247a..fc975bd 100644
--- a/src/apk_defines.h
+++ b/src/apk_defines.h
@@ -37,6 +37,7 @@
#define EAPKFORMAT 1026
#define EAPKDEPFORMAT 1027
#define EAPKDBFORMAT 1028
+#define EAPKCACHE 1029
static inline void *ERR_PTR(long error) { return (void*) error; }
static inline void *ERR_CAST(const void *ptr) { return (void*) ptr; }
diff --git a/src/database.c b/src/database.c
index 80f393d..f4169ff 100644
--- a/src/database.c
+++ b/src/database.c
@@ -1670,7 +1670,10 @@ int apk_db_open(struct apk_database *db, struct apk_db_options *dbopts)
mkdirat(db->root_fd, "var/cache", 0755);
mkdirat(db->root_fd, "var/cache/apk", 0755);
db->cache_fd = openat(db->root_fd, db->cache_dir, O_RDONLY | O_CLOEXEC);
- if (db->cache_fd < 0) goto ret_errno;
+ if (db->cache_fd < 0) {
+ if (dbopts->open_flags & APK_OPENF_WRITE) goto ret_errno;
+ db->cache_fd = -EAPKCACHE;
+ }
}
}
@@ -1854,16 +1857,11 @@ void apk_db_close(struct apk_database *db)
db->cache_remount_dir = NULL;
}
- if (db->keys_fd)
- close(db->keys_fd);
- if (db->cache_fd)
- close(db->cache_fd);
- if (db->root_fd)
- close(db->root_fd);
- if (db->lock_fd)
- close(db->lock_fd);
- if (db->root != NULL)
- free(db->root);
+ if (db->keys_fd > 0) close(db->keys_fd);
+ if (db->cache_fd > 0) close(db->cache_fd);
+ if (db->root_fd > 0) close(db->root_fd);
+ if (db->lock_fd > 0) close(db->lock_fd);
+ free(db->root);
}
int apk_db_get_tag_id(struct apk_database *db, apk_blob_t tag)
diff --git a/src/io.c b/src/io.c
index b693ac4..22ef386 100644
--- a/src/io.c
+++ b/src/io.c
@@ -34,6 +34,11 @@
size_t apk_io_bufsize = 128*1024;
+static inline int atfd_error(int atfd)
+{
+ return atfd < -1 && atfd != AT_FDCWD;
+}
+
static void apk_file_meta_from_fd(int fd, struct apk_file_meta *meta)
{
struct stat st;
@@ -314,6 +319,7 @@ struct apk_istream *apk_istream_tee(struct apk_istream *from, int atfd, const ch
int fd, r;
if (IS_ERR_OR_NULL(from)) return ERR_CAST(from);
+ if (atfd_error(atfd)) return ERR_PTR(atfd);
fd = openat(atfd, to, O_CREAT | O_RDWR | O_TRUNC | O_CLOEXEC,
S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH);
@@ -482,6 +488,8 @@ struct apk_istream *apk_istream_from_file(int atfd, const char *file)
{
int fd;
+ if (atfd_error(atfd)) return ERR_PTR(atfd);
+
fd = openat(atfd, file, O_RDONLY | O_CLOEXEC);
if (fd < 0) return ERR_PTR(-errno);
@@ -604,6 +612,8 @@ apk_blob_t apk_blob_from_file(int atfd, const char *file)
struct stat st;
char *buf;
+ if (atfd_error(atfd)) return APK_BLOB_NULL;
+
fd = openat(atfd, file, O_RDONLY | O_CLOEXEC);
if (fd < 0)
return APK_BLOB_NULL;
@@ -631,6 +641,8 @@ int apk_blob_to_file(int atfd, const char *file, apk_blob_t b, unsigned int flag
{
int fd, r, len;
+ if (atfd_error(atfd)) return atfd;
+
fd = openat(atfd, file, O_CREAT | O_WRONLY | O_CLOEXEC, 0644);
if (fd < 0)
return -errno;
@@ -707,6 +719,9 @@ int apk_fileinfo_get(int atfd, const char *filename, unsigned int flags,
unsigned int xattr_checksum = (flags >> 8) & 0xff;
int atflags = 0;
+ if (atfd_error(atfd)) return atfd;
+
+ memset(fi, 0, sizeof *fi);
if (flags & APK_FI_NOFOLLOW)
atflags |= AT_SYMLINK_NOFOLLOW;
@@ -959,6 +974,8 @@ struct apk_ostream *apk_ostream_to_file(int atfd,
struct apk_ostream *os;
int fd;
+ if (atfd_error(atfd)) return ERR_PTR(atfd);
+
fd = openat(atfd, tmpfile ?: file, O_CREAT | O_RDWR | O_TRUNC | O_CLOEXEC, mode);
if (fd < 0) return ERR_PTR(-errno);
diff --git a/src/print.c b/src/print.c
index 81a4faf..5be5460 100644
--- a/src/print.c
+++ b/src/print.c
@@ -185,6 +185,8 @@ const char *apk_error_str(int error)
return "package dependency format error";
case EAPKDBFORMAT:
return "database file format error";
+ case EAPKCACHE:
+ return "cache not available";
default:
return strerror(error);
}