Browse Source

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

The solution is NOT interpreted so far.
David Kalnischkies 15 years ago
parent
commit
2029276f03
3 changed files with 62 additions and 10 deletions
  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)
 {
    std::string const solver = _config->Find("APT::Solver::Name", "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::WriteScenario(Cache, 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);
 }

+ 26 - 2
apt-pkg/edsp.cc

@@ -10,6 +10,7 @@
 #include <apt-pkg/configuration.h>
 #include <apt-pkg/version.h>
 #include <apt-pkg/policy.h>
+#include <apt-pkg/tagfile.h>
 
 #include <apti18n.h>
 #include <limits>
@@ -139,14 +140,37 @@ bool EDSP::WriteRequest(pkgDepCache &Cache, FILE* output, bool const Upgrade,
    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		/*{{{*/
 // ---------------------------------------------------------------------
 /* 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
    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) {
 	char one;
 	ssize_t data = 0;

+ 1 - 1
apt-pkg/edsp.h

@@ -22,7 +22,7 @@ public:
 				 bool const distUpgrade = false,
 				 bool const autoRemove = false);
 	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
 	bool static ReadRequest(int const input, std::list<std::string> &install,