summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDavid Kalnischkies <kalnischkies@gmail.com>2011-05-02 13:55:51 +0200
committerDavid Kalnischkies <kalnischkies@gmail.com>2011-05-02 13:55:51 +0200
commitac5fbff8c55db2bd1cde194600115a874d9d0c73 (patch)
treedccf97231360fd3665e8ab1d2133e9d80123e9f2
parent98d6aaa8fd2e5c3e9671560781ab23c99f66d7a4 (diff)
refactor: move solver execution into his own EDSP method
-rw-r--r--apt-pkg/algorithms.cc42
-rw-r--r--apt-pkg/edsp.cc42
-rw-r--r--apt-pkg/edsp.h1
3 files changed, 48 insertions, 37 deletions
diff --git a/apt-pkg/algorithms.cc b/apt-pkg/algorithms.cc
index e40f74122..82b1d608d 100644
--- a/apt-pkg/algorithms.cc
+++ b/apt-pkg/algorithms.cc
@@ -743,51 +743,19 @@ bool pkgProblemResolver::Resolve(bool BrokenFix)
if (solver != "internal")
{
- std::vector<std::string> const solverDirs = _config->FindVector("Dir::Bin::Solvers");
- std::string file;
- for (std::vector<std::string>::const_iterator dir = solverDirs.begin();
- dir != solverDirs.end(); ++dir) {
- file = flCombine(*dir, solver);
- if (RealFileExists(file.c_str()) == true)
- break;
- file.clear();
- }
-
- if (file.empty() == true)
- return _error->Error("Can't call external solver '%s' as it is not in a configured directory!", solver.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");
+ int solver_in, solver_out;
+ if (EDSP::ExecuteSolver(solver.c_str(), &solver_in, &solver_out) == false)
+ return false;
- FILE* output = fdopen(external[1], "w");
+ FILE* output = fdopen(solver_in, "w");
if (output == NULL)
return _error->Errno("Resolve", "fdopen on solver stdin failed");
EDSP::WriteRequest(Cache, output);
EDSP::WriteScenario(Cache, output);
fclose(output);
- if (EDSP::ReadResponse(external[2], Cache) == false)
+ if (EDSP::ReadResponse(solver_out, Cache) == false)
return _error->Error("Reading solver response failed");
-
- return ExecWait(Solver, solver.c_str(), false);
}
return ResolveInternal(BrokenFix);
}
diff --git a/apt-pkg/edsp.cc b/apt-pkg/edsp.cc
index 170e2a4c6..c3e608d17 100644
--- a/apt-pkg/edsp.cc
+++ b/apt-pkg/edsp.cc
@@ -441,3 +441,45 @@ bool EDSP::WriteProgress(unsigned short const percent, const char* const message
}
/*}}}*/
bool EDSP::WriteError(std::string const &message, FILE* output) { return false; }
+
+// EDSP::ExecuteSolver - fork requested solver and setup ipc pipes {{{*/
+bool EDSP::ExecuteSolver(const char* const solver, int *solver_in, int *solver_out) {
+ std::vector<std::string> const solverDirs = _config->FindVector("Dir::Bin::Solvers");
+ std::string file;
+ for (std::vector<std::string>::const_iterator dir = solverDirs.begin();
+ dir != solverDirs.end(); ++dir) {
+ file = flCombine(*dir, solver);
+ if (RealFileExists(file.c_str()) == true)
+ break;
+ file.clear();
+ }
+
+ if (file.empty() == true)
+ return _error->Error("Can't call external solver '%s' as it is not in a configured directory!", solver);
+ 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", "Timed out while Waiting on availability of solver stdin");
+
+ *solver_in = external[1];
+ *solver_out = external[2];
+ return true;
+}
+ /*}}}*/
diff --git a/apt-pkg/edsp.h b/apt-pkg/edsp.h
index a05de9448..df6e1d21c 100644
--- a/apt-pkg/edsp.h
+++ b/apt-pkg/edsp.h
@@ -52,6 +52,7 @@ public:
bool static WriteProgress(unsigned short const percent, const char* const message, FILE* output);
bool static WriteError(std::string const &message, FILE* output);
+ bool static ExecuteSolver(const char* const solver, int *solver_in, int *solver_out);
};
/*}}}*/
#endif