-
[PATCH] Factor out common code for reloading database files (2/2)
From
Simon Richter@1:229/2 to
All on Fri May 5 21:10:02 2023
[continued from previous message]
+ file = dpkg_db_reopen(&info, statoverridename, &unchanged);
- file = fopen(statoverridename, "r");
- if (!file) {
- if (errno != ENOENT)
- ohshite(_("failed to open statoverride file"));
- } else {
- setcloexec(fileno(file), statoverridename);
-
- if (fstat(fileno(file), &sb_next))
- ohshite(_("failed to fstat statoverride file"));
-
- /*
- * We need to keep the database file open so that the
- * filesystem cannot reuse the inode number (f.ex. during
- * multiple dpkg-statoverride invocations in a maintainer
- * script), otherwise the following check might turn true,
- * and we would skip reloading a modified database.
- */
- if (file_prev &&
- sb_prev.st_dev == sb_next.st_dev &&
- sb_prev.st_ino == sb_next.st_ino) {
- fclose(file);
- onerr_abort--;
- debug(dbg_general, "%s: same, skipping", __func__);
- return;
- }
- sb_prev = sb_next;
- }
- if (file_prev)
- fclose(file_prev);
- file_prev = file;
+ if (unchanged)
+ return;
+
+ onerr_abort++;
/* Reset statoverride information. */
iter = fsys_hash_iter_new();
@@ -171,15 +143,15 @@ ensure_statoverrides(enum statdb_parse_flags flags)
/* If the statoverride list is empty we don't need to bother
* reading it. */
- if (!sb_next.st_size) {
+ if (!info.sb.st_size) {
onerr_abort--;
return;
}
- loaded_list = m_malloc(sb_next.st_size);
- loaded_list_end = loaded_list + sb_next.st_size;
+ loaded_list = m_malloc(info.sb.st_size);
+ loaded_list_end = loaded_list + info.sb.st_size;
- if (fd_read(fileno(file), loaded_list, sb_next.st_size) < 0)
+ if (fd_read(fileno(file), loaded_list, info.sb.st_size) < 0)
ohshite(_("reading statoverride file '%.250s'"), statoverridename);
thisline = loaded_list;
diff --git a/lib/dpkg/dpkg-db.h b/lib/dpkg/dpkg-db.h
index 61f220506..4d602cb00 100644
--- a/lib/dpkg/dpkg-db.h
+++ b/lib/dpkg/dpkg-db.h
@@ -24,6 +24,7 @@
#define LIBDPKG_DPKG_DB_H
#include <sys/types.h>
+#include <sys/stat.h>
#include <stdbool.h>
#include <stdio.h>
@@ -259,6 +260,18 @@ const char *dpkg_db_set_dir(const char *dir);
const char *dpkg_db_get_dir(void);
char *dpkg_db_get_path(const char *pathpart);
+/*** from db-fsys-common.c ***/
+
+struct dbinfo {
+ FILE *file;
+ struct stat sb;
+};
+
+FILE *dpkg_db_reopen(
+ struct dbinfo *info,
+ char const *filename,
+ bool *unchanged);
+
#include <dpkg/atomic-file.h>
/*** from dbmodify.c ***/
--
2.39.2
--- SoupGate-Win32 v1.05
* Origin: you cannot sedate... all the things you hate (1:229/2)
-
From
Simon Richter@1:229/2 to
All on Sun Mar 17 00:40:02 2024
[continued from previous message]
statoverridename = dpkg_db_get_path(STATOVERRIDEFILE);
- onerr_abort++;
+ file = dpkg_db_reopen(&dbi, statoverridename, &unchanged);
- file = fopen(statoverridename, "r");
- if (!file) {
- if (errno != ENOENT)
- ohshite(_("failed to open statoverride file"));
- } else {
- setcloexec(fileno(file), statoverridename);
-
- if (fstat(fileno(file), &sb_next))
- ohshite(_("failed to fstat statoverride file"));
-
- /*
- * We need to keep the database file open so that the
- * filesystem cannot reuse the inode number (f.ex. during
- * multiple dpkg-statoverride invocations in a maintainer
- * script), otherwise the following check might turn true,
- * and we would skip reloading a modified database.
- */
- if (file_prev &&
- sb_prev.st_dev == sb_next.st_dev &&
- sb_prev.st_ino == sb_next.st_ino) {
- fclose(file);
- onerr_abort--;
- debug(dbg_general, "%s: same, skipping", __func__);
- return;
- }
- sb_prev = sb_next;
- }
- if (file_prev)
- fclose(file_prev);
- file_prev = file;
+ if (unchanged)
+ return;
+
+ onerr_abort++;
/* Reset statoverride information. */
iter = fsys_hash_iter_new();
@@ -171,15 +143,15 @@ ensure_statoverrides(enum statdb_parse_flags flags)
/* If the statoverride list is empty we don't need to bother
* reading it. */
- if (!sb_next.st_size) {
+ if (!dbi.sb.st_size) {
onerr_abort--;
return;
}
- loaded_list = m_malloc(sb_next.st_size);
- loaded_list_end = loaded_list + sb_next.st_size;
+ loaded_list = m_malloc(dbi.sb.st_size);
+ loaded_list_end = loaded_list + dbi.sb.st_size;
- if (fd_read(fileno(file), loaded_list, sb_next.st_size) < 0)
+ if (fd_read(fileno(file), loaded_list, dbi.sb.st_size) < 0)
ohshite(_("reading statoverride file '%.250s'"), statoverridename);
thisline = loaded_list;
diff --git a/lib/dpkg/dpkg-db.h b/lib/dpkg/dpkg-db.h
index 61f220506..4d602cb00 100644
--- a/lib/dpkg/dpkg-db.h
+++ b/lib/dpkg/dpkg-db.h
@@ -24,6 +24,7 @@
#define LIBDPKG_DPKG_DB_H
#include <sys/types.h>
+#include <sys/stat.h>
#include <stdbool.h>
#include <stdio.h>
@@ -259,6 +260,18 @@ const char *dpkg_db_set_dir(const char *dir);
const char *dpkg_db_get_dir(void);
char *dpkg_db_get_path(const char *pathpart);
+/*** from db-fsys-common.c ***/
+
+struct dbinfo {
+ FILE *file;
+ struct stat sb;
+};
+
+FILE *dpkg_db_reopen(
+ struct dbinfo *info,
+ char const *filename,
+ bool *unchanged);
+
#include <dpkg/atomic-file.h>
/*** from dbmodify.c ***/
--
2.39.2
--- SoupGate-Win32 v1.05
* Origin: you cannot sedate... all the things you hate (1:229/2)
-
From
Guillem Jover@1:229/2 to
All on Sun Mar 17 17:30:01 2024
[continued from previous message]
+#include <sys/types.h>
+#include <sys/stat.h>
+
+#include <errno.h>
+
+#include <dpkg/dpkg.h>
+#include <dpkg/dpkg-db.h>
+#include <dpkg/db-fsys.h>
+#include <dpkg/i18n.h>
+#include <dpkg/debug.h>
+
+enum dpkg_db_error
+dpkg_db_reopen(struct dpkg_db *db)
+{
+ struct stat st_next;
+ FILE *file_next;
+
+ if (db->pathname == NULL)
+ db->pathname = dpkg_db_get_path(db->name);
+
+ onerr_abort++;
+
+ file_next = fopen(db->pathname, "r");
+ if (!file_next) {
+ if (errno != ENOENT)
+ ohshite(_("cannot open %s file"), db->pathname);
+ } else {
+ setcloexec(fileno(file_next), db->pathname);
+
+ if (fstat(fileno(file_next), &st_next))
+ ohshite(_("cannot get %s file metadata"), db->pathname);
+
+ /*
+ * We need to keep the database file open so that the
+ * filesystem cannot reuse the inode number (f.ex. during
+ * multiple dpkg-divert invocations in a maintainer script),
+ * otherwise the following check might turn true, and we
+ * would skip reloading a modified database.
+ */
+ if (db->file &&
+ db->st.st_dev == st_next.st_dev &&
+ db->st.st_ino == st_next.st_ino) {
+ fclose(file_next);
+ onerr_abort--;
+
+ debug(dbg_general, "%s: unchanged %s, skipping",
+ __func__, db->pathname);
+ return DPKG_DB_SAME;
+ }
+ db->st = st_next;
+ }
+ if (db->file)
+ fclose(db->file);
+ db->file = file_next;
+
+ onerr_abort--;
+
+ if (db->file) {
+ debug(dbg_general, "%s: new %s, (re)loading",
+ __func__, db->pathname);
+ return DPKG_DB_LOAD;
+ } else {
+ debug(dbg_general, "%s: missing %s, resetting",
+ __func__, db->pathname);
+ return DPKG_DB_NONE;
+ }
+}
diff --git a/lib/dpkg/db-fsys-override.c b/lib/dpkg/db-fsys-override.c
index b74f6cbc2..120bc3dd8 100644
--- a/lib/dpkg/db-fsys-override.c
+++ b/lib/dpkg/db-fsys-override.c
@@ -24,7 +24,6 @@
#include <compat.h>
#include <sys/types.h>
-#include <sys/stat.h>
#include <errno.h>
#include <string.h>
@@ -41,8 +40,6 @@
#include <dpkg/debug.h>
#include <dpkg/db-fsys.h>
-static char *statoverridename;
-
uid_t
statdb_parse_uid(const char *str)
{
@@ -111,76 +108,44 @@ statdb_parse_mode(const char *str)
void
ensure_statoverrides(enum statdb_parse_flags flags)
{
- static struct stat sb_prev;
- struct stat sb_next;
- static FILE *file_prev;
- FILE *file;
+ static struct dpkg_db db = {
+ .name = STATOVERRIDEFILE,
+ };
+ enum dpkg_db_error rc;
char *loaded_list, *loaded_list_end, *thisline, *nextline, *ptr;
struct file_stat *fso;
struct fsys_namenode *fnn;
struct fsys_hash_iter *iter;
- if (statoverridename == NULL)
- statoverridename = dpkg_db_get_path(STATOVERRIDEFILE);
+ rc = dpkg_db_reopen(&db);
+ if (rc == DPKG_DB_SAME)
+ return;
onerr_abort++;