Просмотр исходного кода

* apt-pkg/aptconfiguration.cc:
- chroot if needed before calling dpkg --print-foreign-architectures

David Kalnischkies лет назад: 14
Родитель
Сommit
b9ed63d39e
2 измененных файлов с 60 добавлено и 9 удалено
  1. 57 8
      apt-pkg/aptconfiguration.cc
  2. 3 1
      debian/changelog

+ 57 - 8
apt-pkg/aptconfiguration.cc

@@ -20,6 +20,7 @@
 #include <sys/types.h>
 #include <dirent.h>
 #include <stdio.h>
+#include <fcntl.h>
 
 #include <algorithm>
 #include <string>
@@ -328,13 +329,60 @@ std::vector<std::string> const Configuration::getArchitectures(bool const &Cache
 	// FIXME: It is a bit unclean to have debian specific code here…
 	if (archs.empty() == true) {
 		archs.push_back(arch);
-		string dpkgcall = _config->Find("Dir::Bin::dpkg", "dpkg");
-		std::vector<string> const dpkgoptions = _config->FindVector("DPkg::options");
-		for (std::vector<string>::const_iterator o = dpkgoptions.begin();
-		     o != dpkgoptions.end(); ++o)
-			dpkgcall.append(" ").append(*o);
-		dpkgcall.append(" --print-foreign-architectures 2> /dev/null");
-		FILE *dpkg = popen(dpkgcall.c_str(), "r");
+
+		// 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");
+			if (chrootDir != "/" && chroot(chrootDir.c_str()) != 0)
+				_error->WarningE("getArchitecture", "Couldn't chroot into %s for dpkg --print-foreign-architectures", chrootDir.c_str());
+			int const nullfd = open("/dev/null", O_RDONLY);
+			dup2(nullfd, STDIN_FILENO);
+			dup2(external[1], STDOUT_FILENO);
+			dup2(nullfd, STDERR_FILENO);
+			execv(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");
 		char buf[1024];
 		if(dpkg != NULL) {
 			while (fgets(buf, sizeof(buf), dpkg) != NULL) {
@@ -349,8 +397,9 @@ std::vector<std::string> const Configuration::getArchitectures(bool const &Cache
 					arch = strtok(NULL, " ");
 				}
 			}
-			pclose(dpkg);
+			fclose(dpkg);
 		}
+		ExecWait(dpkgMultiArch, "dpkg --print-foreign-architectures", true);
 		return archs;
 	}
 

+ 3 - 1
debian/changelog

@@ -13,6 +13,8 @@ apt (0.8.16~exp13) UNRELEASED; urgency=low
     - if a file without an extension is requested send an 'Accept: text/*'
       header to avoid that the server chooses unsupported compressed files
       in a content-negotation attempt (Closes: #657560)
+  * apt-pkg/aptconfiguration.cc:
+    - chroot if needed before calling dpkg --print-foreign-architectures
 
   [ Steve Langasek ]
   * cmdline/apt-get.cc:
@@ -26,7 +28,7 @@ apt (0.8.16~exp13) UNRELEASED; urgency=low
     - use a signed int instead of short for score calculation as upgrades
       become so big now that it can overflow (Closes: #657732, LP: #917173)
 
- -- David Kalnischkies <kalnischkies@gmail.com>  Mon, 30 Jan 2012 16:06:11 +0100
+ -- David Kalnischkies <kalnischkies@gmail.com>  Mon, 30 Jan 2012 19:17:09 +0100
 
 apt (0.8.16~exp12) experimental; urgency=low