Pārlūkot izejas kodu

libdpkg: Change pkg_db_get_pkg() to create new arch instances

This allows the code to load several architecture package instances
per package set.

Based-on-patch-by: Raphaël Hertzog <hertzog@debian.org>
Patch-sponsored-by: Linaro Limited

Signed-off-by: Guillem Jover <guillem@debian.org>
Guillem Jover 14 gadi atpakaļ
vecāks
revīzija
ffa1ec0502
1 mainītis faili ar 35 papildinājumiem un 1 dzēšanām
  1. 35 1
      lib/dpkg/pkg-db.c

+ 35 - 1
lib/dpkg/pkg-db.c

@@ -24,6 +24,7 @@
 #include <config.h>
 #include <compat.h>
 
+#include <assert.h>
 #include <ctype.h>
 #include <string.h>
 #include <stdlib.h>
@@ -168,6 +169,11 @@ pkg_db_find_singleton(const char *name)
 /**
  * Return the package instance in a set with the given architecture.
  *
+ * It traverse the various instances to find out whether there's one
+ * matching the given architecture. If found, it returns it. Otherwise it
+ * allocates a new instance and registers it in the package set before
+ * returning it.
+ *
  * @param set  The package set to use.
  * @param arch The requested architecture.
  *
@@ -176,10 +182,38 @@ pkg_db_find_singleton(const char *name)
 struct pkginfo *
 pkg_db_get_pkg(struct pkgset *set, const struct dpkg_arch *arch)
 {
-  struct pkginfo *pkg;
+  struct pkginfo *pkg, **pkgp;
+
+  assert(arch);
+  assert(arch->type != arch_none);
 
   pkg = &set->pkg;
 
+  /* If there's a single unused slot, let's use that. */
+  if (pkg->installed.arch->type == arch_none && pkg->arch_next == NULL) {
+    pkg->installed.arch = arch;
+    pkg->available.arch = arch;
+    return pkg;
+  }
+
+  /* Match the slot with the most appropriate architecture. The installed
+   * architecture always has preference over the available one, as there's
+   * a small time window on cross-grades, where they might differ. */
+  for (pkgp = &pkg; *pkgp; pkgp = &(*pkgp)->arch_next) {
+    if ((*pkgp)->installed.arch == arch)
+      return *pkgp;
+  }
+
+  /* Need to create a new instance for the wanted architecture. */
+  pkg = nfmalloc(sizeof(struct pkginfo));
+  pkg_blank(pkg);
+  pkg->set = set;
+  pkg->arch_next = NULL;
+  pkg->installed.arch = arch;
+  pkg->available.arch = arch;
+  *pkgp = pkg;
+  npkg++;
+
   return pkg;
 }