Sfoglia il codice sorgente

send the scenario through a pipe to the solver and get the solution back

The solution is NOT interpreted so far.
David Kalnischkies 15 anni fa
parent
commit
2029276f03
3 ha cambiato i file con 62 aggiunte e 10 eliminazioni
  1. 35 7
      apt-pkg/algorithms.cc
  2. 26 2
      apt-pkg/edsp.cc
  3. 1 1
      apt-pkg/edsp.h

+ 35 - 7
apt-pkg/algorithms.cc

@@ -740,18 +740,46 @@ bool pkgProblemResolver::DoUpgrade(pkgCache::PkgIterator Pkg)
 bool pkgProblemResolver::Resolve(bool BrokenFix)
 bool pkgProblemResolver::Resolve(bool BrokenFix)
 {
 {
    std::string const solver = _config->Find("APT::Solver::Name", "internal");
    std::string const solver = _config->Find("APT::Solver::Name", "internal");
+
    if (solver != "internal")
    if (solver != "internal")
    {
    {
-      FILE* output = fopen("/tmp/scenario.log", "w");
+//       std::string const file = _config->FindDir("Dir::Bin::Solvers") + solver;
+      std::string const file = solver;
+      if (RealFileExists(file.c_str()) == false)
+	 return _error->Error("Can't call external solver '%s' as it is not available: %s", solver.c_str(), file.c_str());
+      int external[4] = {-1, -1, -1, -1};
+      if (pipe(external) != 0 || pipe(external + 2) != 0)
+	 return _error->Errno("Resolve", "Can't create needed IPC pipes for EDSP");
+      for (int i = 0; i < 4; ++i)
+	 SetCloseExec(external[i], true);
+
+      pid_t Solver = ExecFork();
+      if (Solver == 0)
+      {
+	 dup2(external[0], STDIN_FILENO);
+	 dup2(external[3], STDOUT_FILENO);
+	 const char* calling[2] = { file.c_str(), 0 };
+	 execv(calling[0], (char**) calling);
+	 std::cerr << "Failed to execute solver '" << solver << "'!" << std::endl;
+	 _exit(100);
+      }
+      close(external[0]);
+      close(external[3]);
+
+      if (WaitFd(external[1], true, 5) == false)
+         return _error->Errno("Resolve", "Waiting on availability of solver stdin timed out");
+
+      FILE* output = fdopen(external[1], "w");
+      if (output == NULL)
+         return _error->Errno("Resolve", "fdopen on solver stdin failed");
       EDSP::WriteRequest(Cache, output);
       EDSP::WriteRequest(Cache, output);
       EDSP::WriteScenario(Cache, output);
       EDSP::WriteScenario(Cache, output);
       fclose(output);
       fclose(output);
-      if (ResolveInternal(BrokenFix) == false)
-	 return false;
-      output = fopen("/tmp/solution.log", "w");
-      EDSP::WriteSolution(Cache, output);
-      fclose(output);
-      return true;
+
+      if (EDSP::ReadResponse(external[2], Cache) == false)
+	 return _error->Error("Reading solver response failed");
+
+      return ExecWait(Solver, solver.c_str(), false);
    }
    }
    return ResolveInternal(BrokenFix);
    return ResolveInternal(BrokenFix);
 }
 }

+ 26 - 2
apt-pkg/edsp.cc

@@ -10,6 +10,7 @@
 #include <apt-pkg/configuration.h>
 #include <apt-pkg/configuration.h>
 #include <apt-pkg/version.h>
 #include <apt-pkg/version.h>
 #include <apt-pkg/policy.h>
 #include <apt-pkg/policy.h>
+#include <apt-pkg/tagfile.h>
 
 
 #include <apti18n.h>
 #include <apti18n.h>
 #include <limits>
 #include <limits>
@@ -139,14 +140,37 @@ bool EDSP::WriteRequest(pkgDepCache &Cache, FILE* output, bool const Upgrade,
    return true;
    return true;
 }
 }
 									/*}}}*/
 									/*}}}*/
-bool EDSP::ReadResponse(FILE* input, pkgDepCache &Cache) { return false; }
+// EDSP::ReadResponse - from the given file descriptor			/*{{{*/
+bool EDSP::ReadResponse(int const input, pkgDepCache &Cache) {
+	FileFd in;
+	in.OpenDescriptor(input, FileFd::ReadOnly);
+	pkgTagFile response(&in);
+	pkgTagSection section;
+	while (response.Step(section) == true) {
+		std::string type;
+		if (section.Exists("Install") == true)
+			type = "Install";
+		else if (section.Exists("Remove") == true)
+			type = "Remove";
+		//FIXME: handle progress
+		else
+			continue;
+
+		int const id = section.FindI(type.c_str(), -1);
+		if (id == -1)
+			return _error->Error("Unable to parse %s request!", type.c_str());
 
 
+		//FIXME: find version by id and mark it correctly
+	}
+	return true;
+}
+									/*}}}*/
 // EDSP::ReadLine - first line from the given file descriptor		/*{{{*/
 // EDSP::ReadLine - first line from the given file descriptor		/*{{{*/
 // ---------------------------------------------------------------------
 // ---------------------------------------------------------------------
 /* Little helper method to read a complete line into a string. Similar to
 /* Little helper method to read a complete line into a string. Similar to
    fgets but we need to use the low-level read() here as otherwise the
    fgets but we need to use the low-level read() here as otherwise the
    listparser will be confused later on as mixing of fgets and read isn't
    listparser will be confused later on as mixing of fgets and read isn't
-   a supported action according to the manpages and result are undefined */
+   a supported action according to the manpages and results are undefined */
 bool EDSP::ReadLine(int const input, std::string &line) {
 bool EDSP::ReadLine(int const input, std::string &line) {
 	char one;
 	char one;
 	ssize_t data = 0;
 	ssize_t data = 0;

+ 1 - 1
apt-pkg/edsp.h

@@ -22,7 +22,7 @@ public:
 				 bool const distUpgrade = false,
 				 bool const distUpgrade = false,
 				 bool const autoRemove = false);
 				 bool const autoRemove = false);
 	bool static WriteScenario(pkgDepCache &Cache, FILE* output);
 	bool static WriteScenario(pkgDepCache &Cache, FILE* output);
-	bool static ReadResponse(FILE* input, pkgDepCache &Cache);
+	bool static ReadResponse(int const input, pkgDepCache &Cache);
 
 
 	// ReadScenario is provided by the listparser infrastructure
 	// ReadScenario is provided by the listparser infrastructure
 	bool static ReadRequest(int const input, std::list<std::string> &install,
 	bool static ReadRequest(int const input, std::list<std::string> &install,