From ac5fbff8c55db2bd1cde194600115a874d9d0c73 Mon Sep 17 00:00:00 2001 From: David Kalnischkies Date: Mon, 2 May 2011 13:55:51 +0200 Subject: [PATCH] refactor: move solver execution into his own EDSP method --- apt-pkg/algorithms.cc | 42 +++++------------------------------------- apt-pkg/edsp.cc | 42 ++++++++++++++++++++++++++++++++++++++++++ apt-pkg/edsp.h | 1 + 3 files changed, 48 insertions(+), 37 deletions(-) diff --git a/apt-pkg/algorithms.cc b/apt-pkg/algorithms.cc index e40f7412..82b1d608 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 const solverDirs = _config->FindVector("Dir::Bin::Solvers"); - std::string file; - for (std::vector::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 170e2a4c..c3e608d1 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 const solverDirs = _config->FindVector("Dir::Bin::Solvers"); + std::string file; + for (std::vector::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 a05de944..df6e1d21 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 -- 2.20.1