-// DPkgPM::Go - Run the sequence /*{{{*/
-// ---------------------------------------------------------------------
-/* This globs the operations and calls dpkg
- *
- * If it is called with a progress object apt will report the install
- * progress to this object. It maps the dpkg states a package goes
- * through to human readable (and i10n-able)
- * names and calculates a percentage for each step.
- */
-bool pkgDPkgPM::Go(APT::Progress::PackageManager *progress)
-{
- pkgPackageManager::SigINTStop = false;
- d->progress = progress;
-
- // Generate the base argument list for dpkg
- std::vector<const char *> Args;
- unsigned long StartSize = 0;
- string Tmp = _config->Find("Dir::Bin::dpkg","dpkg");
- {
- string const dpkgChrootDir = _config->FindDir("DPkg::Chroot-Directory", "/");
- size_t dpkgChrootLen = dpkgChrootDir.length();
- if (dpkgChrootDir != "/" && Tmp.find(dpkgChrootDir) == 0)
- {
- if (dpkgChrootDir[dpkgChrootLen - 1] == '/')
- --dpkgChrootLen;
- Tmp = Tmp.substr(dpkgChrootLen);
- }
- }
- Args.push_back(Tmp.c_str());
- StartSize += Tmp.length();
-
- // Stick in any custom dpkg options
- Configuration::Item const *Opts = _config->Tree("DPkg::Options");
- if (Opts != 0)
- {
- Opts = Opts->Child;
- for (; Opts != 0; Opts = Opts->Next)
- {
- if (Opts->Value.empty() == true)
- continue;
- Args.push_back(Opts->Value.c_str());
- StartSize += Opts->Value.length();
- }
- }
-
- size_t const BaseArgs = Args.size();
- // we need to detect if we can qualify packages with the architecture or not
- Args.push_back("--assert-multi-arch");
- Args.push_back(NULL);
-
- pid_t dpkgAssertMultiArch = ExecFork();
- if (dpkgAssertMultiArch == 0)
- {
- dpkgChrootDirectory();
- // redirect everything to the ultimate sink as we only need the exit-status
- int const nullfd = open("/dev/null", O_RDONLY);
- dup2(nullfd, STDIN_FILENO);
- dup2(nullfd, STDOUT_FILENO);
- dup2(nullfd, STDERR_FILENO);
- execvp(Args[0], (char**) &Args[0]);
- _error->WarningE("dpkgGo", "Can't detect if dpkg supports multi-arch!");
- _exit(2);
- }
-
- fd_set rfds;
- struct timespec tv;
- sigset_t sigmask;
- sigset_t original_sigmask;
-
- unsigned int const MaxArgs = _config->FindI("Dpkg::MaxArgs",8*1024);
- unsigned int const MaxArgBytes = _config->FindI("Dpkg::MaxArgBytes",32*1024);
- bool const NoTriggers = _config->FindB("DPkg::NoTriggers", false);
-
- if (RunScripts("DPkg::Pre-Invoke") == false)
- return false;
-
- if (RunScriptsWithPkgs("DPkg::Pre-Install-Pkgs") == false)
- return false;
-
- // support subpressing of triggers processing for special
- // cases like d-i that runs the triggers handling manually
- bool const SmartConf = (_config->Find("PackageManager::Configure", "all") != "all");
- bool const TriggersPending = _config->FindB("DPkg::TriggersPending", false);
- if (_config->FindB("DPkg::ConfigurePending", SmartConf) == true)
- List.push_back(Item(Item::ConfigurePending, PkgIterator()));