X-Git-Url: https://git.saurik.com/apt.git/blobdiff_plain/177296dffd8bf7d9ce5870b135c412958aab3756..75ab11ae3880530c5354cc90c8d1ff0998f8146b:/apt-pkg/deb/dpkgpm.cc diff --git a/apt-pkg/deb/dpkgpm.cc b/apt-pkg/deb/dpkgpm.cc index d1b11098c..b4bfd1400 100644 --- a/apt-pkg/deb/dpkgpm.cc +++ b/apt-pkg/deb/dpkgpm.cc @@ -201,7 +201,7 @@ pkgCache::VerIterator FindNowVersion(const pkgCache::PkgIterator &Pkg) // --------------------------------------------------------------------- /* */ pkgDPkgPM::pkgDPkgPM(pkgDepCache *Cache) - : pkgPackageManager(Cache), PackagesDone(0), PackagesTotal(0) + : pkgPackageManager(Cache), pkgFailures(0), PackagesDone(0), PackagesTotal(0) { d = new pkgDPkgPMPrivate(); } @@ -416,17 +416,21 @@ bool pkgDPkgPM::RunScriptsWithPkgs(const char *Cnf) unsigned int InfoFD = _config->FindI(OptSec + "::InfoFD", STDIN_FILENO); // Create the pipes + std::set KeepFDs; + MergeKeepFdsFromConfiguration(KeepFDs); int Pipes[2]; if (pipe(Pipes) != 0) return _error->Errno("pipe","Failed to create IPC pipe to subprocess"); if (InfoFD != (unsigned)Pipes[0]) SetCloseExec(Pipes[0],true); else - _config->Set("APT::Keep-Fds::", Pipes[0]); + KeepFDs.insert(Pipes[0]); + + SetCloseExec(Pipes[1],true); // Purified Fork for running the script - pid_t Process = ExecFork(); + pid_t Process = ExecFork(KeepFDs); if (Process == 0) { // Setup the FDs @@ -448,8 +452,6 @@ bool pkgDPkgPM::RunScriptsWithPkgs(const char *Cnf) execv(Args[0],(char **)Args); _exit(100); } - if (InfoFD == (unsigned)Pipes[0]) - _config->Clear("APT::Keep-Fds", Pipes[0]); close(Pipes[0]); FILE *F = fdopen(Pipes[1],"w"); if (F == 0) @@ -1375,11 +1377,15 @@ bool pkgDPkgPM::GoNoABIBreak(APT::Progress::PackageManager *progress) // ignore SIGHUP as well (debian #463030) sighandler_t old_SIGHUP = signal(SIGHUP,SIG_IGN); - pid_t Child = ExecFork(); - // This is the child + // now run dpkg + d->progress->StartDpkg(); + std::set KeepFDs; + KeepFDs.insert(fd[1]); + MergeKeepFdsFromConfiguration(KeepFDs); + pid_t Child = ExecFork(KeepFDs); if (Child == 0) { - + // This is the child if(d->slave >= 0 && d->master >= 0) { setsid(); @@ -1425,9 +1431,6 @@ bool pkgDPkgPM::GoNoABIBreak(APT::Progress::PackageManager *progress) if (_config->FindB("DPkg::UseIoNice", false) == true) ionice(Child); - // clear the Keep-Fd again - _config->Clear("APT::Keep-Fds",fd[1]); - // Wait for dpkg int Status = 0; @@ -1471,13 +1474,14 @@ bool pkgDPkgPM::GoNoABIBreak(APT::Progress::PackageManager *progress) FD_SET(_dpkgin, &rfds); if(d->master >= 0) FD_SET(d->master, &rfds); - tv.tv_sec = 1; - tv.tv_nsec = 0; + tv.tv_sec = 0; + tv.tv_nsec = d->progress->GetPulseInterval(); select_ret = pselect(max(d->master, _dpkgin)+1, &rfds, NULL, NULL, &tv, &d->original_sigmask); if (select_ret < 0 && (errno == EINVAL || errno == ENOSYS)) select_ret = racy_pselect(max(d->master, _dpkgin)+1, &rfds, NULL, NULL, &tv, &d->original_sigmask); + d->progress->Pulse(); if (select_ret == 0) continue; else if (select_ret < 0 && errno == EINTR) @@ -1526,6 +1530,7 @@ bool pkgDPkgPM::GoNoABIBreak(APT::Progress::PackageManager *progress) if(stopOnError) { CloseLog(); + StopPtyMagic(); d->progress->Stop(); return false; } @@ -1617,18 +1622,49 @@ void pkgDPkgPM::WriteApportReport(const char *pkgpath, const char *errormsg) } // do not report out-of-memory failures - if(strstr(errormsg, strerror(ENOMEM)) != NULL) { + if(strstr(errormsg, strerror(ENOMEM)) != NULL || + strstr(errormsg, "failed to allocate memory") != NULL) { std::clog << _("No apport report written because the error message indicates a out of memory error") << std::endl; return; } - // do not report dpkg I/O errors - // XXX - this message is localized, but this only matches the English version. This is better than nothing. - if(strstr(errormsg, "short read in buffer_copy (")) { - std::clog << _("No apport report written because the error message indicates a dpkg I/O error") << std::endl; + // do not report bugs regarding inaccessible local files + if(strstr(errormsg, strerror(ENOENT)) != NULL || + strstr(errormsg, "cannot access archive") != NULL) { + std::clog << _("No apport report written because the error message indicates an issue on the local system") << std::endl; + return; + } + + // do not report errors encountered when decompressing packages + if(strstr(errormsg, "--fsys-tarfile returned error exit status 2") != NULL) { + std::clog << _("No apport report written because the error message indicates an issue on the local system") << std::endl; return; } + // do not report dpkg I/O errors, this is a format string, so we compare + // the prefix and the suffix of the error with the dpkg error message + vector io_errors; + io_errors.push_back(string("failed to read on buffer copy for %s")); + io_errors.push_back(string("failed in write on buffer copy for %s")); + io_errors.push_back(string("short read on buffer copy for %s")); + + for (vector::iterator I = io_errors.begin(); I != io_errors.end(); I++) + { + vector list = VectorizeString(dgettext("dpkg", (*I).c_str()), '%'); + if (list.size() > 1) { + // we need to split %s, VectorizeString only allows char so we need + // to kill the "s" manually + if (list[1].size() > 1) { + list[1].erase(0, 1); + if(strstr(errormsg, list[0].c_str()) && + strstr(errormsg, list[1].c_str())) { + std::clog << _("No apport report written because the error message indicates a dpkg I/O error") << std::endl; + return; + } + } + } + } + // get the pkgname and reportfile pkgname = flNotDir(pkgpath); pos = pkgname.find('_'); @@ -1716,6 +1752,24 @@ void pkgDPkgPM::WriteApportReport(const char *pkgpath, const char *errormsg) if(log != NULL) { char buf[1024]; + while( fgets(buf, sizeof(buf), log) != NULL) + fprintf(report, " %s", buf); + fprintf(report, " \n"); + fclose(log); + } + } + + // attach history log it if we have it + string histfile_name = _config->FindFile("Dir::Log::History"); + if (!histfile_name.empty()) + { + FILE *log = NULL; + char buf[1024]; + + fprintf(report, "DpkgHistoryLog:\n"); + log = fopen(histfile_name.c_str(),"r"); + if(log != NULL) + { while( fgets(buf, sizeof(buf), log) != NULL) fprintf(report, " %s", buf); fclose(log);