]> git.saurik.com Git - apt.git/commitdiff
send the scenario through a pipe to the solver and get the solution back
authorDavid Kalnischkies <kalnischkies@gmail.com>
Sat, 2 Apr 2011 13:47:14 +0000 (15:47 +0200)
committerDavid Kalnischkies <kalnischkies@gmail.com>
Sat, 2 Apr 2011 13:47:14 +0000 (15:47 +0200)
The solution is NOT interpreted so far.

apt-pkg/algorithms.cc
apt-pkg/edsp.cc
apt-pkg/edsp.h

index aabb511a29a64e5c12433ca1f3b6e9c641885131..bbe315ef79fb62692fc2325731d0e6d93be483e8 100644 (file)
@@ -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);
 }
index d93b054118eee94d59da3c7ec5d8d94e6a647182..e6dc16536b8d26f7d649b4607bb718db1409402e 100644 (file)
@@ -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;
index 75733c2d2155ef1e6c4f6cb5ea0d21f3d96a0e8e..31f8891f3681bb416c0723c691c8864e9ee57214 100644 (file)
@@ -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,