]> git.saurik.com Git - apt.git/commitdiff
implement a public pkgSystem::ArchitecturesSupported
authorDavid Kalnischkies <david@kalnischkies.de>
Tue, 15 Sep 2015 12:12:19 +0000 (14:12 +0200)
committerDavid Kalnischkies <david@kalnischkies.de>
Wed, 4 Nov 2015 17:04:00 +0000 (18:04 +0100)
apt-pkg/aptconfiguration.cc
apt-pkg/deb/debsystem.cc
apt-pkg/deb/debsystem.h
apt-pkg/pkgsystem.cc
apt-pkg/pkgsystem.h

index c15332c7a95ac8bcf3ad7e9d1d47a16c7f286add..74f88640cc54ee2a967e3044df7b9a6a17ccd602 100644 (file)
@@ -16,6 +16,7 @@
 #include <apt-pkg/fileutl.h>
 #include <apt-pkg/macros.h>
 #include <apt-pkg/strutl.h>
+#include <apt-pkg/pkgsystem.h>
 
 #include <dirent.h>
 #include <stdio.h>
@@ -320,88 +321,8 @@ std::vector<std::string> const Configuration::getArchitectures(bool const &Cache
        string const arch = _config->Find("APT::Architecture");
        archs = _config->FindVector("APT::Architectures");
 
-       if (unlikely(arch.empty() == true))
-               return archs;
-
-       // FIXME: It is a bit unclean to have debian specific code hereā€¦
-       if (archs.empty() == true) {
-               archs.push_back(arch);
-
-               // Generate the base argument list for dpkg
-               std::vector<const char *> Args;
-               string Tmp = _config->Find("Dir::Bin::dpkg","dpkg");
-               {
-                       string const dpkgChrootDir = _config->FindDir("DPkg::Chroot-Directory", "/");
-                       size_t dpkgChrootLen = dpkgChrootDir.length();
-                       if (dpkgChrootDir != "/" && Tmp.find(dpkgChrootDir) == 0) {
-                               if (dpkgChrootDir[dpkgChrootLen - 1] == '/')
-                                       --dpkgChrootLen;
-                               Tmp = Tmp.substr(dpkgChrootLen);
-                       }
-               }
-               Args.push_back(Tmp.c_str());
-
-               // Stick in any custom dpkg options
-               ::Configuration::Item const *Opts = _config->Tree("DPkg::Options");
-               if (Opts != 0) {
-                       Opts = Opts->Child;
-                       for (; Opts != 0; Opts = Opts->Next)
-                       {
-                               if (Opts->Value.empty() == true)
-                                       continue;
-                               Args.push_back(Opts->Value.c_str());
-                       }
-               }
-
-               Args.push_back("--print-foreign-architectures");
-               Args.push_back(NULL);
-
-               int external[2] = {-1, -1};
-               if (pipe(external) != 0)
-               {
-                       _error->WarningE("getArchitecture", "Can't create IPC pipe for dpkg --print-foreign-architectures");
-                       return archs;
-               }
-
-               pid_t dpkgMultiArch = ExecFork();
-               if (dpkgMultiArch == 0) {
-                       close(external[0]);
-                       std::string const chrootDir = _config->FindDir("DPkg::Chroot-Directory");
-                       int const nullfd = open("/dev/null", O_RDONLY);
-                       dup2(nullfd, STDIN_FILENO);
-                       dup2(external[1], STDOUT_FILENO);
-                       dup2(nullfd, STDERR_FILENO);
-                       if (chrootDir != "/" && chroot(chrootDir.c_str()) != 0 && chdir("/") != 0)
-                               _error->WarningE("getArchitecture", "Couldn't chroot into %s for dpkg --print-foreign-architectures", chrootDir.c_str());
-                       execvp(Args[0], (char**) &Args[0]);
-                       _error->WarningE("getArchitecture", "Can't detect foreign architectures supported by dpkg!");
-                       _exit(100);
-               }
-               close(external[1]);
-
-               FILE *dpkg = fdopen(external[0], "r");
-               if(dpkg != NULL) {
-                       char buf[1024];
-                       char *tok_buf;
-                       while (fgets(buf, sizeof(buf), dpkg) != NULL) {
-                               char* arch = strtok_r(buf, " ", &tok_buf);
-                               while (arch != NULL) {
-                                       for (; isspace(*arch) != 0; ++arch);
-                                       if (arch[0] != '\0') {
-                                               char const* archend = arch;
-                                               for (; isspace(*archend) == 0 && *archend != '\0'; ++archend);
-                                               string a(arch, (archend - arch));
-                                               if (std::find(archs.begin(), archs.end(), a) == archs.end())
-                                                       archs.push_back(a);
-                                       }
-                                       arch = strtok_r(NULL, " ", &tok_buf);
-                               }
-                       }
-                       fclose(dpkg);
-               }
-               ExecWait(dpkgMultiArch, "dpkg --print-foreign-architectures", true);
-               return archs;
-       }
+       if (archs.empty() == true)
+          archs = _system->ArchitecturesSupported();
 
        if (archs.empty() == true ||
            std::find(archs.begin(), archs.end(), arch) == archs.end())
index 5353761fcbf92421d82c80900182201e4d4deb67..724312bc5f887d42bd7ab9c4ac8036c66058c0ad 100644 (file)
@@ -304,7 +304,6 @@ void debSystem::DpkgChrootDirectory()                                       /*{{{*/
                                                                        /*}}}*/
 bool debSystem::SupportsMultiArch()                                    /*{{{*/
 {
-   // Generate the base argument list for dpkg
    std::vector<std::string> const Args = GetDpkgBaseCommand();
    std::vector<const char *> cArgs(Args.size(), NULL);
    std::transform(Args.begin(), Args.end(), cArgs.begin(), [](std::string const &s) { return s.c_str(); });
@@ -343,3 +342,64 @@ bool debSystem::SupportsMultiArch()                                        /*{{{*/
    return false;
 }
                                                                        /*}}}*/
+std::vector<std::string> debSystem::SupportedArchitectures()           /*{{{*/
+{
+   std::vector<std::string> const sArgs = GetDpkgBaseCommand();
+   std::vector<const char *> Args(sArgs.size(), NULL);
+   std::transform(sArgs.begin(), sArgs.end(), Args.begin(), [](std::string const &s) { return s.c_str(); });
+   Args.push_back("--print-foreign-architectures");
+   Args.push_back(NULL);
+
+   std::vector<std::string> archs;
+   string const arch = _config->Find("APT::Architecture");
+   if (arch.empty() == false)
+      archs.push_back(arch);
+
+   int external[2] = {-1, -1};
+   if (pipe(external) != 0)
+   {
+      _error->WarningE("getArchitecture", "Can't create IPC pipe for dpkg --print-foreign-architectures");
+      return archs;
+   }
+
+   pid_t dpkgMultiArch = ExecFork();
+   if (dpkgMultiArch == 0) {
+      close(external[0]);
+      int const nullfd = open("/dev/null", O_RDONLY);
+      dup2(nullfd, STDIN_FILENO);
+      dup2(external[1], STDOUT_FILENO);
+      dup2(nullfd, STDERR_FILENO);
+      DpkgChrootDirectory();
+      execvp(Args[0], (char**) &Args[0]);
+      _error->WarningE("getArchitecture", "Can't detect foreign architectures supported by dpkg!");
+      _exit(100);
+   }
+   close(external[1]);
+
+   FILE *dpkg = fdopen(external[0], "r");
+   if(dpkg != NULL) {
+      char* buf = NULL;
+      size_t bufsize = 0;
+      while (getline(&buf, &bufsize, dpkg) != -1)
+      {
+        char* tok_saveptr;
+        char* arch = strtok_r(buf, " ", &tok_saveptr);
+        while (arch != NULL) {
+           for (; isspace(*arch) != 0; ++arch);
+           if (arch[0] != '\0') {
+              char const* archend = arch;
+              for (; isspace(*archend) == 0 && *archend != '\0'; ++archend);
+              string a(arch, (archend - arch));
+              if (std::find(archs.begin(), archs.end(), a) == archs.end())
+                 archs.push_back(a);
+           }
+           arch = strtok_r(NULL, " ", &tok_saveptr);
+        }
+      }
+      free(buf);
+      fclose(dpkg);
+   }
+   ExecWait(dpkgMultiArch, "dpkg --print-foreign-architectures", true);
+   return archs;
+}
+                                                                       /*}}}*/
index 521552ef481555befcb7127ad7ca2e9e07a65b7a..efb33a3ed9dcb779d261f6a66e153ce63b6682d6 100644 (file)
@@ -50,6 +50,7 @@ class debSystem : public pkgSystem
    APT_HIDDEN static std::vector<std::string> GetDpkgBaseCommand();
    APT_HIDDEN static void DpkgChrootDirectory();
    APT_HIDDEN static bool SupportsMultiArch();
+   APT_HIDDEN static std::vector<std::string> SupportedArchitectures();
 };
 
 extern debSystem debSys;
index 2a0fc9d3b78ce842f913ca561e01576f3fa0f1bb..53015022150f51f89231e7a0607607501944d6a0 100644 (file)
@@ -55,5 +55,13 @@ bool pkgSystem::MultiArchSupported() const                           /*{{{*/
    return true;
 }
                                                                        /*}}}*/
+std::vector<std::string> pkgSystem::ArchitecturesSupported() const     /*{{{*/
+{
+   debSystem const * const deb = dynamic_cast<debSystem const *>(this);
+   if (deb != NULL)
+      return deb->SupportedArchitectures();
+   return {};
+}
+                                                                       /*}}}*/
 
 pkgSystem::~pkgSystem() {}
index c7de63c8739ea93c84dd773f67545cc83aac0099..55bdeec708c02c53f4b07268314cc5568a45cdd8 100644 (file)
@@ -104,6 +104,15 @@ class pkgSystem
     * @return \b true if the system supports MultiArch, \b false if not.
     */
    bool MultiArchSupported() const;
+   /** architectures supported by this system
+    *
+    * A MultiArch capable system might be configured to use
+    * this capability.
+    *
+    * @return a list of all architectures (native + foreign) configured
+    * for on this system (aka: which can be installed without force)
+    */
+   std::vector<std::string> ArchitecturesSupported() const;
 
    pkgSystem(char const * const Label, pkgVersioningSystem * const VS);
    virtual ~pkgSystem();