From 8336ae355b8a22877cd233063c715688155aa617 Mon Sep 17 00:00:00 2001 From: Michael Vogt Date: Tue, 22 Oct 2013 18:44:14 +0200 Subject: move install-progress.{cc,h} to apt-pkg --- apt-pkg/install-progress.h | 137 +++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 137 insertions(+) create mode 100644 apt-pkg/install-progress.h (limited to 'apt-pkg/install-progress.h') diff --git a/apt-pkg/install-progress.h b/apt-pkg/install-progress.h new file mode 100644 index 000000000..9c31eac92 --- /dev/null +++ b/apt-pkg/install-progress.h @@ -0,0 +1,137 @@ +#ifndef PKGLIB_IPROGRESS_H +#define PKGLIB_IPROGRESS_H + +#include +#include + + +namespace APT { +namespace Progress { + + class PackageManager + { + private: + /** \brief dpointer placeholder */ + void *d; + + protected: + std::string progress_str; + float percentage; + int last_reported_progress; + + public: + PackageManager() + : percentage(0.0), last_reported_progress(-1) {}; + virtual ~PackageManager() {}; + + virtual void Start() {}; + virtual void Stop() {}; + + virtual pid_t fork() {return fork(); }; + + virtual void Pulse() {}; + virtual long GetPulseInterval() { + return 500000; + }; + + virtual bool StatusChanged(std::string PackageName, + unsigned int StepsDone, + unsigned int TotalSteps, + std::string HumanReadableAction) ; + virtual void Error(std::string PackageName, + unsigned int StepsDone, + unsigned int TotalSteps, + std::string ErrorMessage) {}; + virtual void ConffilePrompt(std::string PackageName, + unsigned int StepsDone, + unsigned int TotalSteps, + std::string ConfMessage) {}; + }; + + class PackageManagerProgressFd : public PackageManager + { + protected: + int OutStatusFd; + int StepsDone; + int StepsTotal; + void WriteToStatusFd(std::string msg); + + public: + PackageManagerProgressFd(int progress_fd); + + virtual void Start(); + virtual void Stop(); + + virtual bool StatusChanged(std::string PackageName, + unsigned int StepsDone, + unsigned int TotalSteps, + std::string HumanReadableAction); + virtual void Error(std::string PackageName, + unsigned int StepsDone, + unsigned int TotalSteps, + std::string ErrorMessage); + virtual void ConffilePrompt(std::string PackageName, + unsigned int StepsDone, + unsigned int TotalSteps, + std::string ConfMessage); + + }; + + class PackageManagerProgressDeb822Fd : public PackageManager + { + protected: + int OutStatusFd; + int StepsDone; + int StepsTotal; + void WriteToStatusFd(std::string msg); + + public: + PackageManagerProgressDeb822Fd(int progress_fd); + + virtual void Start(); + virtual void Stop(); + + virtual bool StatusChanged(std::string PackageName, + unsigned int StepsDone, + unsigned int TotalSteps, + std::string HumanReadableAction); + virtual void Error(std::string PackageName, + unsigned int StepsDone, + unsigned int TotalSteps, + std::string ErrorMessage); + virtual void ConffilePrompt(std::string PackageName, + unsigned int StepsDone, + unsigned int TotalSteps, + std::string ConfMessage); + }; + + class PackageManagerFancy : public PackageManager + { + protected: + int nr_terminal_rows; + void SetupTerminalScrollArea(int nr_rows); + + public: + PackageManagerFancy(); + virtual void Start(); + virtual void Stop(); + virtual bool StatusChanged(std::string PackageName, + unsigned int StepsDone, + unsigned int TotalSteps, + std::string HumanReadableAction); + }; + + class PackageManagerText : public PackageManager + { + public: + virtual bool StatusChanged(std::string PackageName, + unsigned int StepsDone, + unsigned int TotalSteps, + std::string HumanReadableAction); + }; + + +}; // namespace Progress +}; // namespace APT + +#endif -- cgit v1.2.3-70-g09d2 From bd5f39b34cc0e8cebbe9103f569d4d903e75bd2b Mon Sep 17 00:00:00 2001 From: Michael Vogt Date: Thu, 31 Oct 2013 08:23:12 +0100 Subject: restore ABI and prepare next ABI via #if (APT_PKG_MAJOR >= 4 && APT_PKG_MINOR >= 13) --- apt-pkg/deb/dpkgpm.cc | 17 +++++++++++++++++ apt-pkg/deb/dpkgpm.h | 7 +++++++ apt-pkg/install-progress.cc | 22 ++++++++++++++++++++++ apt-pkg/install-progress.h | 3 +++ apt-pkg/packagemanager.cc | 36 ++++++++++++++++++++++++++++++------ apt-pkg/packagemanager.h | 15 ++++++++++++++- apt-private/private-install.cc | 35 +++++++++++++---------------------- 7 files changed, 106 insertions(+), 29 deletions(-) (limited to 'apt-pkg/install-progress.h') diff --git a/apt-pkg/deb/dpkgpm.cc b/apt-pkg/deb/dpkgpm.cc index 98fb7581a..b252c02eb 100644 --- a/apt-pkg/deb/dpkgpm.cc +++ b/apt-pkg/deb/dpkgpm.cc @@ -1000,6 +1000,19 @@ void pkgDPkgPM::BuildPackagesProgressMap() } } /*}}}*/ +#if (APT_PKG_MAJOR >= 4 && APT_PKG_MINOR < 13) +bool pkgDPkgPM::Go(int StatusFd) +{ + APT::Progress::PackageManager *progress = NULL; + if (StatusFd == -1) + progress = APT::Progress::PackageManagerProgressFactory(); + else + progress = new APT::Progress::PackageManagerProgressFd(StatusFd); + + return GoNoABIBreak(progress); +} +#endif + // DPkgPM::Go - Run the sequence /*{{{*/ // --------------------------------------------------------------------- /* This globs the operations and calls dpkg @@ -1009,7 +1022,11 @@ void pkgDPkgPM::BuildPackagesProgressMap() * through to human readable (and i10n-able) * names and calculates a percentage for each step. */ +#if (APT_PKG_MAJOR >= 4 && APT_PKG_MINOR >= 13) bool pkgDPkgPM::Go(APT::Progress::PackageManager *progress) +#else +bool pkgDPkgPM::GoNoABIBreak(APT::Progress::PackageManager *progress) +#endif { pkgPackageManager::SigINTStop = false; d->progress = progress; diff --git a/apt-pkg/deb/dpkgpm.h b/apt-pkg/deb/dpkgpm.h index 5f00eee5d..4494bbae3 100644 --- a/apt-pkg/deb/dpkgpm.h +++ b/apt-pkg/deb/dpkgpm.h @@ -15,6 +15,7 @@ #include #include #include +#include #ifndef APT_8_CLEANER_HEADERS using std::vector; @@ -112,7 +113,13 @@ class pkgDPkgPM : public pkgPackageManager virtual bool Configure(PkgIterator Pkg); virtual bool Remove(PkgIterator Pkg,bool Purge = false); +#if (APT_PKG_MAJOR >= 4 && APT_PKG_MINOR >= 13) virtual bool Go(APT::Progress::PackageManager *progress); +#else + virtual bool Go(int StatusFd=-1); + bool GoNoABIBreak(APT::Progress::PackageManager *progress); +#endif + virtual void Reset(); public: diff --git a/apt-pkg/install-progress.cc b/apt-pkg/install-progress.cc index 9d0d4e3f1..a9146f27d 100644 --- a/apt-pkg/install-progress.cc +++ b/apt-pkg/install-progress.cc @@ -13,6 +13,28 @@ namespace APT { namespace Progress { +PackageManager* PackageManagerProgressFactory() +{ + // select the right progress + int status_fd = _config->FindI("APT::Status-Fd", -1); + int status_deb822_fd = _config->FindI("APT::Status-deb822-Fd", -1); + + APT::Progress::PackageManager *progress = NULL; + if (status_deb822_fd > 0) + progress = new APT::Progress::PackageManagerProgressDeb822Fd( + status_deb822_fd); + else if (status_fd > 0) + progress = new APT::Progress::PackageManagerProgressFd(status_fd); + else if(_config->FindB("Dpkg::Progress-Fancy", false) == true) + progress = new APT::Progress::PackageManagerFancy(); + else if (_config->FindB("Dpkg::Progress", + _config->FindB("DpkgPM::Progress", false)) == true) + progress = new APT::Progress::PackageManagerText(); + else + progress = new APT::Progress::PackageManager(); + return progress; +} + bool PackageManager::StatusChanged(std::string PackageName, unsigned int StepsDone, unsigned int TotalSteps, diff --git a/apt-pkg/install-progress.h b/apt-pkg/install-progress.h index 9c31eac92..050954bb5 100644 --- a/apt-pkg/install-progress.h +++ b/apt-pkg/install-progress.h @@ -8,6 +8,9 @@ namespace APT { namespace Progress { + class PackageManager; + PackageManager* PackageManagerProgressFactory(); + class PackageManager { private: diff --git a/apt-pkg/packagemanager.cc b/apt-pkg/packagemanager.cc index a2079a2e4..3fdd9b637 100644 --- a/apt-pkg/packagemanager.cc +++ b/apt-pkg/packagemanager.cc @@ -1030,15 +1030,16 @@ pkgPackageManager::OrderResult pkgPackageManager::OrderInstall() // PM::DoInstallPostFork - compat /*{{{*/ // --------------------------------------------------------------------- /*}}}*/ +#if (APT_PKG_MAJOR >= 4 && APT_PKG_MINOR >= 13) pkgPackageManager::OrderResult pkgPackageManager::DoInstallPostFork(int statusFd) { - APT::Progress::PackageManager *progress = new - APT::Progress::PackageManagerProgressFd(statusFd); - pkgPackageManager::OrderResult res = DoInstallPostFork(progress); - delete progress; - return res; - } + APT::Progress::PackageManager *progress = new + APT::Progress::PackageManagerProgressFd(statusFd); + pkgPackageManager::OrderResult res = DoInstallPostFork(progress); + delete progress; + return res; +} /*}}}*/ // PM::DoInstallPostFork - Does install part that happens after the fork /*{{{*/ // --------------------------------------------------------------------- @@ -1051,10 +1052,22 @@ pkgPackageManager::DoInstallPostFork(APT::Progress::PackageManager *progress) return Res; }; +#else +pkgPackageManager::OrderResult +pkgPackageManager::DoInstallPostFork(int statusFd) +{ + bool goResult = Go(statusFd); + if(goResult == false) + return Failed; + + return Res; +} +#endif /*}}}*/ // PM::DoInstall - Does the installation /*{{{*/ // --------------------------------------------------------------------- /* compat */ +#if (APT_PKG_MAJOR >= 4 && APT_PKG_MINOR >= 13) pkgPackageManager::OrderResult pkgPackageManager::DoInstall(int statusFd) { @@ -1064,11 +1077,21 @@ pkgPackageManager::DoInstall(int statusFd) delete progress; return res; } +#else +pkgPackageManager::OrderResult pkgPackageManager::DoInstall(int statusFd) +{ + if(DoInstallPreFork() == Failed) + return Failed; + + return DoInstallPostFork(statusFd); +} +#endif /*}}}*/ // PM::DoInstall - Does the installation /*{{{*/ // --------------------------------------------------------------------- /* This uses the filenames in FileNames and the information in the DepCache to perform the installation of packages.*/ +#if (APT_PKG_MAJOR >= 4 && APT_PKG_MINOR >= 13) pkgPackageManager::OrderResult pkgPackageManager::DoInstall(APT::Progress::PackageManager *progress) { @@ -1077,4 +1100,5 @@ pkgPackageManager::DoInstall(APT::Progress::PackageManager *progress) return DoInstallPostFork(progress); } +#endif /*}}}*/ diff --git a/apt-pkg/packagemanager.h b/apt-pkg/packagemanager.h index 8ffac2f13..a5c58e4a7 100644 --- a/apt-pkg/packagemanager.h +++ b/apt-pkg/packagemanager.h @@ -26,6 +26,7 @@ #include #include #include +#include #include #include @@ -87,7 +88,12 @@ class pkgPackageManager : protected pkgCache::Namespace virtual bool Install(PkgIterator /*Pkg*/,std::string /*File*/) {return false;}; virtual bool Configure(PkgIterator /*Pkg*/) {return false;}; virtual bool Remove(PkgIterator /*Pkg*/,bool /*Purge*/=false) {return false;}; +#if (APT_PKG_MAJOR >= 4 && APT_PKG_MINOR >= 13) virtual bool Go(APT::Progress::PackageManager *progress) {return true;}; +#else + virtual bool Go(int StatusFd=-1) {return true;}; +#endif + virtual void Reset() {}; // the result of the operation @@ -100,9 +106,13 @@ class pkgPackageManager : protected pkgCache::Namespace pkgRecords *Recs); // Do the installation +#if (APT_PKG_MAJOR >= 4 && APT_PKG_MINOR >= 13) OrderResult DoInstall(APT::Progress::PackageManager *progress); // compat __deprecated OrderResult DoInstall(int statusFd=-1); +#else + OrderResult DoInstall(int statusFd=-1); +#endif // stuff that needs to be done before the fork() of a library that // uses apt @@ -110,11 +120,14 @@ class pkgPackageManager : protected pkgCache::Namespace Res = OrderInstall(); return Res; }; - +#if (APT_PKG_MAJOR >= 4 && APT_PKG_MINOR >= 13) // stuff that needs to be done after the fork OrderResult DoInstallPostFork(APT::Progress::PackageManager *progress); // compat __deprecated OrderResult DoInstallPostFork(int statusFd=-1); +#else + OrderResult DoInstallPostFork(int statusFd=-1); +#endif // ? bool FixMissing(); diff --git a/apt-private/private-install.cc b/apt-private/private-install.cc index d9d46dba0..3adb00b23 100644 --- a/apt-private/private-install.cc +++ b/apt-private/private-install.cc @@ -24,6 +24,7 @@ #include #include #include +#include #include #include @@ -105,12 +106,14 @@ bool InstallPackages(CacheFile &Cache,bool ShwKept,bool Ask, bool Safety) { pkgSimulate PM(Cache); - int status_fd = _config->FindI("APT::Status-Fd",-1); - APT::Progress::PackageManager *progress = NULL; - if (status_fd > 0) - progress = new APT::Progress::PackageManagerProgressFd(status_fd); +#if (APT_PKG_MAJOR >= 4 && APT_PKG_MINOR >= 13) + APT::Progress::PackageManager *progress = APT::Progress::PackageManagerProgressFactory(); pkgPackageManager::OrderResult Res = PM.DoInstall(progress); delete progress; +#else + int status_fd = _config->FindI("APT::Status-Fd",-1); + pkgPackageManager::OrderResult Res = PM.DoInstall(status_fd); +#endif if (Res == pkgPackageManager::Failed) return false; @@ -340,26 +343,14 @@ bool InstallPackages(CacheFile &Cache,bool ShwKept,bool Ask, bool Safety) _system->UnLock(); - // FIXME: make this a factory - // select the right progress - int status_fd = _config->FindI("APT::Status-Fd", -1); - int status_deb822_fd = _config->FindI("APT::Status-deb822-Fd", -1); - - APT::Progress::PackageManager *progress = NULL; - if (status_deb822_fd > 0) - progress = new APT::Progress::PackageManagerProgressDeb822Fd( - status_deb822_fd); - else if (status_fd > 0) - progress = new APT::Progress::PackageManagerProgressFd(status_fd); - else if(_config->FindB("Dpkg::Progress-Fancy", false) == true) - progress = new APT::Progress::PackageManagerFancy(); - else if (_config->FindB("Dpkg::Progress", - _config->FindB("DpkgPM::Progress", false)) == true) - progress = new APT::Progress::PackageManagerText(); - else - progress = new APT::Progress::PackageManager(); +#if (APT_PKG_MAJOR >= 4 && APT_PKG_MINOR >= 13) + APT::Progress::PackageManager *progress = APT::Progress::PackageManagerProgressFactory(); pkgPackageManager::OrderResult Res = PM->DoInstall(progress); delete progress; +#else + int status_fd = _config->FindI("APT::Status-Fd", -1); + pkgPackageManager::OrderResult Res = PM->DoInstall(status_fd); +#endif if (Res == pkgPackageManager::Failed || _error->PendingError() == true) return false; -- cgit v1.2.3-70-g09d2 From e45c4617e496b49f8d7225546a751022f246a2f3 Mon Sep 17 00:00:00 2001 From: Michael Vogt Date: Thu, 31 Oct 2013 22:55:38 +0100 Subject: add new pid_t ExecFork(std::set KeepFDs) to get rid of the super ugly APT::Keep-Fds hack and also add a new PackageManagerProgressFd::StartDpkg() progress state --- apt-pkg/contrib/fileutl.cc | 33 +++++++++++++++++++-------------- apt-pkg/contrib/fileutl.h | 2 ++ apt-pkg/deb/dpkgpm.cc | 26 ++++++++++++++------------ apt-pkg/install-progress.cc | 6 +----- apt-pkg/install-progress.h | 8 +++++++- 5 files changed, 43 insertions(+), 32 deletions(-) (limited to 'apt-pkg/install-progress.h') diff --git a/apt-pkg/contrib/fileutl.cc b/apt-pkg/contrib/fileutl.cc index 0261119ba..2347ef140 100644 --- a/apt-pkg/contrib/fileutl.cc +++ b/apt-pkg/contrib/fileutl.cc @@ -766,6 +766,25 @@ bool WaitFd(int Fd,bool write,unsigned long timeout) child, it fixes up the important signals and nukes all of the fds, otherwise acts like normal fork. */ pid_t ExecFork() +{ + set KeepFDs; + + Configuration::Item const *Opts = _config->Tree("APT::Keep-Fds"); + if (Opts != 0 && Opts->Child != 0) + { + Opts = Opts->Child; + for (; Opts != 0; Opts = Opts->Next) + { + if (Opts->Value.empty() == true) + continue; + int fd = atoi(Opts->Value.c_str()); + KeepFDs.insert(fd); + } + } + return ExecFork(KeepFDs); +} + +pid_t ExecFork(std::set KeepFDs) { // Fork off the process pid_t Process = fork(); @@ -786,20 +805,6 @@ pid_t ExecFork() signal(SIGCONT,SIG_DFL); signal(SIGTSTP,SIG_DFL); - set KeepFDs; - Configuration::Item const *Opts = _config->Tree("APT::Keep-Fds"); - if (Opts != 0 && Opts->Child != 0) - { - Opts = Opts->Child; - for (; Opts != 0; Opts = Opts->Next) - { - if (Opts->Value.empty() == true) - continue; - int fd = atoi(Opts->Value.c_str()); - KeepFDs.insert(fd); - } - } - // Close all of our FDs - just in case for (int K = 3; K != 40; K++) { diff --git a/apt-pkg/contrib/fileutl.h b/apt-pkg/contrib/fileutl.h index decd64d9d..63a999c30 100644 --- a/apt-pkg/contrib/fileutl.h +++ b/apt-pkg/contrib/fileutl.h @@ -26,6 +26,7 @@ #include #include +#include #include @@ -182,6 +183,7 @@ void SetCloseExec(int Fd,bool Close); void SetNonBlock(int Fd,bool Block); bool WaitFd(int Fd,bool write = false,unsigned long timeout = 0); pid_t ExecFork(); +pid_t ExecFork(std::set keep_fds); bool ExecWait(pid_t Pid,const char *Name,bool Reap = false); // File string manipulators diff --git a/apt-pkg/deb/dpkgpm.cc b/apt-pkg/deb/dpkgpm.cc index d1b11098c..26d79dbb1 100644 --- a/apt-pkg/deb/dpkgpm.cc +++ b/apt-pkg/deb/dpkgpm.cc @@ -416,17 +416,20 @@ bool pkgDPkgPM::RunScriptsWithPkgs(const char *Cnf) unsigned int InfoFD = _config->FindI(OptSec + "::InfoFD", STDIN_FILENO); // Create the pipes + std::set 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 +451,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 +1376,14 @@ 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]); + pid_t Child = ExecFork(KeepFDs); if (Child == 0) { - + // This is the child if(d->slave >= 0 && d->master >= 0) { setsid(); @@ -1425,9 +1429,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 +1472,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) diff --git a/apt-pkg/install-progress.cc b/apt-pkg/install-progress.cc index a9146f27d..79660b29e 100644 --- a/apt-pkg/install-progress.cc +++ b/apt-pkg/install-progress.cc @@ -63,7 +63,7 @@ void PackageManagerProgressFd::WriteToStatusFd(std::string s) FileFd::Write(OutStatusFd, s.c_str(), s.size()); } -void PackageManagerProgressFd::Start() +void PackageManagerProgressFd::StartDpkg() { if(OutStatusFd <= 0) return; @@ -83,8 +83,6 @@ void PackageManagerProgressFd::Start() void PackageManagerProgressFd::Stop() { - // clear the Keep-Fd again - _config->Clear("APT::Keep-Fds", OutStatusFd); } void PackageManagerProgressFd::Error(std::string PackageName, @@ -168,8 +166,6 @@ void PackageManagerProgressDeb822Fd::Start() void PackageManagerProgressDeb822Fd::Stop() { - // clear the Keep-Fd again - _config->Clear("APT::Keep-Fds", OutStatusFd); } void PackageManagerProgressDeb822Fd::Error(std::string PackageName, diff --git a/apt-pkg/install-progress.h b/apt-pkg/install-progress.h index 050954bb5..5291039d8 100644 --- a/apt-pkg/install-progress.h +++ b/apt-pkg/install-progress.h @@ -27,9 +27,15 @@ namespace Progress { : percentage(0.0), last_reported_progress(-1) {}; virtual ~PackageManager() {}; + /* Global Start/Stop */ virtual void Start() {}; virtual void Stop() {}; + /* When dpkg is invoked (may happen multiple times for each + * install/remove block + */ + virtual void StartDpkg() {}; + virtual pid_t fork() {return fork(); }; virtual void Pulse() {}; @@ -62,7 +68,7 @@ namespace Progress { public: PackageManagerProgressFd(int progress_fd); - virtual void Start(); + virtual void StartDpkg(); virtual void Stop(); virtual bool StatusChanged(std::string PackageName, -- cgit v1.2.3-70-g09d2 From 790d41f6372871e527f3fc9da66d049937b4c780 Mon Sep 17 00:00:00 2001 From: Michael Vogt Date: Thu, 31 Oct 2013 23:00:11 +0100 Subject: use StartDpkg() in PackageManagerProgressDeb822Fd as well --- apt-pkg/install-progress.cc | 2 +- apt-pkg/install-progress.h | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) (limited to 'apt-pkg/install-progress.h') diff --git a/apt-pkg/install-progress.cc b/apt-pkg/install-progress.cc index 79660b29e..f76fc88c2 100644 --- a/apt-pkg/install-progress.cc +++ b/apt-pkg/install-progress.cc @@ -149,7 +149,7 @@ void PackageManagerProgressDeb822Fd::WriteToStatusFd(std::string s) FileFd::Write(OutStatusFd, s.c_str(), s.size()); } -void PackageManagerProgressDeb822Fd::Start() +void PackageManagerProgressDeb822Fd::StartDpkg() { // FIXME: use SetCloseExec here once it taught about throwing // exceptions instead of doing _exit(100) on failure diff --git a/apt-pkg/install-progress.h b/apt-pkg/install-progress.h index 5291039d8..d721c6373 100644 --- a/apt-pkg/install-progress.h +++ b/apt-pkg/install-progress.h @@ -97,7 +97,7 @@ namespace Progress { public: PackageManagerProgressDeb822Fd(int progress_fd); - virtual void Start(); + virtual void StartDpkg(); virtual void Stop(); virtual bool StatusChanged(std::string PackageName, -- cgit v1.2.3-70-g09d2 From e96e4e9cef3a0137b789117f72a93a8e9106562e Mon Sep 17 00:00:00 2001 From: Michael Vogt Date: Fri, 6 Dec 2013 15:54:12 +0100 Subject: Handle SIGWINCH in APT::Progress-Fancy=1 --- apt-pkg/deb/dpkgpm.h | 1 - apt-pkg/install-progress.cc | 32 +++++++++++++++++++++++++------- apt-pkg/install-progress.h | 9 ++++++--- 3 files changed, 31 insertions(+), 11 deletions(-) (limited to 'apt-pkg/install-progress.h') diff --git a/apt-pkg/deb/dpkgpm.h b/apt-pkg/deb/dpkgpm.h index 06318d94f..02e12a6d9 100644 --- a/apt-pkg/deb/dpkgpm.h +++ b/apt-pkg/deb/dpkgpm.h @@ -89,7 +89,6 @@ class pkgDPkgPM : public pkgPackageManager const std::string &short_pkgname); // Terminal progress - void SetupTerminalScrollArea(int nr_scrolled_rows); void SendTerminalProgress(float percentage); // apport integration diff --git a/apt-pkg/install-progress.cc b/apt-pkg/install-progress.cc index 09b1bef9e..b82b7efde 100644 --- a/apt-pkg/install-progress.cc +++ b/apt-pkg/install-progress.cc @@ -10,6 +10,7 @@ #include #include + namespace APT { namespace Progress { @@ -221,6 +222,14 @@ bool PackageManagerProgressDeb822Fd::StatusChanged(std::string PackageName, return true; } +int PackageManagerFancy::GetNumberTerminalRows() +{ + struct winsize win; + if(ioctl(STDOUT_FILENO, TIOCGWINSZ, (char *)&win) != 0) + return -1; + + return win.ws_row; +} void PackageManagerFancy::SetupTerminalScrollArea(int nr_rows) { @@ -248,23 +257,32 @@ void PackageManagerFancy::SetupTerminalScrollArea(int nr_rows) } PackageManagerFancy::PackageManagerFancy() - : nr_terminal_rows(-1) { - struct winsize win; - if(ioctl(STDOUT_FILENO, TIOCGWINSZ, (char *)&win) == 0) - { - nr_terminal_rows = win.ws_row; - } + // setup terminal size + old_SIGWINCH = signal(SIGWINCH, HandleSIGWINCH); +} + +PackageManagerFancy::~PackageManagerFancy() +{ + signal(SIGWINCH, old_SIGWINCH); +} + +void PackageManagerFancy::HandleSIGWINCH(int) +{ + int nr_terminal_rows = GetNumberTerminalRows(); + SetupTerminalScrollArea(nr_terminal_rows); } void PackageManagerFancy::Start() { + int nr_terminal_rows = GetNumberTerminalRows(); if (nr_terminal_rows > 0) SetupTerminalScrollArea(nr_terminal_rows); } void PackageManagerFancy::Stop() { + int nr_terminal_rows = GetNumberTerminalRows(); if (nr_terminal_rows > 0) { SetupTerminalScrollArea(nr_terminal_rows + 1); @@ -284,7 +302,7 @@ bool PackageManagerFancy::StatusChanged(std::string PackageName, HumanReadableAction)) return false; - int row = nr_terminal_rows; + int row = GetNumberTerminalRows(); static string save_cursor = "\033[s"; static string restore_cursor = "\033[u"; diff --git a/apt-pkg/install-progress.h b/apt-pkg/install-progress.h index d721c6373..4b7590983 100644 --- a/apt-pkg/install-progress.h +++ b/apt-pkg/install-progress.h @@ -3,7 +3,7 @@ #include #include - +#include namespace APT { namespace Progress { @@ -117,11 +117,14 @@ namespace Progress { class PackageManagerFancy : public PackageManager { protected: - int nr_terminal_rows; - void SetupTerminalScrollArea(int nr_rows); + static void SetupTerminalScrollArea(int nr_rows); + static int GetNumberTerminalRows(); + static void HandleSIGWINCH(int); + sighandler_t old_SIGWINCH; public: PackageManagerFancy(); + ~PackageManagerFancy(); virtual void Start(); virtual void Stop(); virtual bool StatusChanged(std::string PackageName, -- cgit v1.2.3-70-g09d2 From 4754718a4461ebff89f5b49c385a007b4197bcff Mon Sep 17 00:00:00 2001 From: Michael Vogt Date: Sun, 22 Dec 2013 14:38:39 +0100 Subject: first proof-of-concept for a fix for #731738 --- apt-pkg/deb/dpkgpm.cc | 2 +- apt-pkg/install-progress.cc | 9 ++++++++- apt-pkg/install-progress.h | 4 ++-- 3 files changed, 11 insertions(+), 4 deletions(-) (limited to 'apt-pkg/install-progress.h') diff --git a/apt-pkg/deb/dpkgpm.cc b/apt-pkg/deb/dpkgpm.cc index b4bfd1400..b9f839e82 100644 --- a/apt-pkg/deb/dpkgpm.cc +++ b/apt-pkg/deb/dpkgpm.cc @@ -1182,7 +1182,7 @@ bool pkgDPkgPM::GoNoABIBreak(APT::Progress::PackageManager *progress) StartPtyMagic(); // Tell the progress that its starting and fork dpkg - d->progress->Start(); + d->progress->Start(d->master); // this loop is runs once per dpkg operation vector::const_iterator I = List.begin(); diff --git a/apt-pkg/install-progress.cc b/apt-pkg/install-progress.cc index b82b7efde..2215fb1f5 100644 --- a/apt-pkg/install-progress.cc +++ b/apt-pkg/install-progress.cc @@ -273,11 +273,18 @@ void PackageManagerFancy::HandleSIGWINCH(int) SetupTerminalScrollArea(nr_terminal_rows); } -void PackageManagerFancy::Start() +void PackageManagerFancy::Start(int child_pty) { int nr_terminal_rows = GetNumberTerminalRows(); if (nr_terminal_rows > 0) + { SetupTerminalScrollArea(nr_terminal_rows); + // *cough* + struct winsize win; + ioctl(child_pty, TIOCGWINSZ, (char *)&win); + win.ws_row = nr_terminal_rows - 1; + ioctl(child_pty, TIOCSWINSZ, (char *)&win); + } } void PackageManagerFancy::Stop() diff --git a/apt-pkg/install-progress.h b/apt-pkg/install-progress.h index 4b7590983..010be82fd 100644 --- a/apt-pkg/install-progress.h +++ b/apt-pkg/install-progress.h @@ -28,7 +28,7 @@ namespace Progress { virtual ~PackageManager() {}; /* Global Start/Stop */ - virtual void Start() {}; + virtual void Start(int child_pty=-1) {}; virtual void Stop() {}; /* When dpkg is invoked (may happen multiple times for each @@ -125,7 +125,7 @@ namespace Progress { public: PackageManagerFancy(); ~PackageManagerFancy(); - virtual void Start(); + virtual void Start(int child_pty=-1); virtual void Stop(); virtual bool StatusChanged(std::string PackageName, unsigned int StepsDone, -- cgit v1.2.3-70-g09d2 From 5ed887855df9c39dcd22971073ed05b28a9ee95f Mon Sep 17 00:00:00 2001 From: Michael Vogt Date: Sat, 28 Dec 2013 00:26:17 +0100 Subject: properly handle SIGWINCH in PackageManagerFancy again --- apt-pkg/install-progress.cc | 65 +++++++++++++++++++++++++++++---------------- apt-pkg/install-progress.h | 12 ++++++--- 2 files changed, 51 insertions(+), 26 deletions(-) (limited to 'apt-pkg/install-progress.h') diff --git a/apt-pkg/install-progress.cc b/apt-pkg/install-progress.cc index 2215fb1f5..bfc00bd06 100644 --- a/apt-pkg/install-progress.cc +++ b/apt-pkg/install-progress.cc @@ -9,7 +9,7 @@ #include #include #include - +#include namespace APT { namespace Progress { @@ -222,17 +222,47 @@ bool PackageManagerProgressDeb822Fd::StatusChanged(std::string PackageName, return true; } + +PackageManagerFancy::PackageManagerFancy() + : child_pty(-1) +{ + // setup terminal size + old_SIGWINCH = signal(SIGWINCH, PackageManagerFancy::staticSIGWINCH); + instances.push_back(this); +} +std::vector PackageManagerFancy::instances; + +PackageManagerFancy::~PackageManagerFancy() +{ + instances.erase(find(instances.begin(), instances.end(), this)); + signal(SIGWINCH, old_SIGWINCH); +} + +void PackageManagerFancy::staticSIGWINCH(int signum) +{ + std::vector::const_iterator I; + for(I = instances.begin(); I != instances.end(); I++) + (*I)->HandleSIGWINCH(signum); +} + int PackageManagerFancy::GetNumberTerminalRows() { struct winsize win; + // FIXME: get from "child_pty" instead? if(ioctl(STDOUT_FILENO, TIOCGWINSZ, (char *)&win) != 0) return -1; + + if(_config->FindB("Debug::InstallProgress::Fancy", false) == true) + std::cerr << "GetNumberTerminalRows: " << win.ws_row << std::endl; return win.ws_row; } void PackageManagerFancy::SetupTerminalScrollArea(int nr_rows) { + if(_config->FindB("Debug::InstallProgress::Fancy", false) == true) + std::cerr << "SetupTerminalScrollArea: " << nr_rows << std::endl; + // scroll down a bit to avoid visual glitch when the screen // area shrinks by one row std::cout << "\n"; @@ -241,30 +271,22 @@ void PackageManagerFancy::SetupTerminalScrollArea(int nr_rows) std::cout << "\033[s"; // set scroll region (this will place the cursor in the top left) - std::cout << "\033[1;" << nr_rows - 1 << "r"; + std::cout << "\033[0;" << nr_rows - 1 << "r"; // restore cursor but ensure its inside the scrolling area std::cout << "\033[u"; static const char *move_cursor_up = "\033[1A"; std::cout << move_cursor_up; - // setup env for (hopefully!) ncurses - string s; - strprintf(s, "%i", nr_rows); - setenv("LINES", s.c_str(), 1); - + // ensure its flushed std::flush(std::cout); -} -PackageManagerFancy::PackageManagerFancy() -{ - // setup terminal size - old_SIGWINCH = signal(SIGWINCH, HandleSIGWINCH); -} - -PackageManagerFancy::~PackageManagerFancy() -{ - signal(SIGWINCH, old_SIGWINCH); + // setup tty size to ensure xterm/linux console are working properly too + // see bug #731738 + struct winsize win; + ioctl(child_pty, TIOCGWINSZ, (char *)&win); + win.ws_row = nr_rows - 1; + ioctl(child_pty, TIOCSWINSZ, (char *)&win); } void PackageManagerFancy::HandleSIGWINCH(int) @@ -273,17 +295,13 @@ void PackageManagerFancy::HandleSIGWINCH(int) SetupTerminalScrollArea(nr_terminal_rows); } -void PackageManagerFancy::Start(int child_pty) +void PackageManagerFancy::Start(int a_child_pty) { + child_pty = a_child_pty; int nr_terminal_rows = GetNumberTerminalRows(); if (nr_terminal_rows > 0) { SetupTerminalScrollArea(nr_terminal_rows); - // *cough* - struct winsize win; - ioctl(child_pty, TIOCGWINSZ, (char *)&win); - win.ws_row = nr_terminal_rows - 1; - ioctl(child_pty, TIOCSWINSZ, (char *)&win); } } @@ -298,6 +316,7 @@ void PackageManagerFancy::Stop() static const char* clear_screen_below_cursor = "\033[J"; std::cout << clear_screen_below_cursor; } + child_pty = -1; } bool PackageManagerFancy::StatusChanged(std::string PackageName, diff --git a/apt-pkg/install-progress.h b/apt-pkg/install-progress.h index 010be82fd..513de1c08 100644 --- a/apt-pkg/install-progress.h +++ b/apt-pkg/install-progress.h @@ -116,11 +116,17 @@ namespace Progress { class PackageManagerFancy : public PackageManager { + private: + static void staticSIGWINCH(int); + static std::vector instances; + protected: - static void SetupTerminalScrollArea(int nr_rows); - static int GetNumberTerminalRows(); - static void HandleSIGWINCH(int); + void SetupTerminalScrollArea(int nr_rows); + void HandleSIGWINCH(int); + + int GetNumberTerminalRows(); sighandler_t old_SIGWINCH; + int child_pty; public: PackageManagerFancy(); -- cgit v1.2.3-70-g09d2 From 23bd09778261c945b460b46d855b1a6ef998cfd8 Mon Sep 17 00:00:00 2001 From: Michael Vogt Date: Sat, 28 Dec 2013 09:50:06 +0100 Subject: add missing vector include --- apt-pkg/install-progress.h | 1 + 1 file changed, 1 insertion(+) (limited to 'apt-pkg/install-progress.h') diff --git a/apt-pkg/install-progress.h b/apt-pkg/install-progress.h index 513de1c08..8a5b68a8f 100644 --- a/apt-pkg/install-progress.h +++ b/apt-pkg/install-progress.h @@ -4,6 +4,7 @@ #include #include #include +#include namespace APT { namespace Progress { -- cgit v1.2.3-70-g09d2