From 697a1d8ab6744181355cda92b4de01b996c1bc1d Mon Sep 17 00:00:00 2001 From: Michael Vogt Date: Thu, 27 Jan 2011 21:59:23 +0100 Subject: apt-pkg/deb/dpkgpm.{cc,h}: convert to use dpointers --- apt-pkg/deb/dpkgpm.cc | 108 +++++++++++++++++++++++++++++--------------------- 1 file changed, 62 insertions(+), 46 deletions(-) (limited to 'apt-pkg/deb/dpkgpm.cc') diff --git a/apt-pkg/deb/dpkgpm.cc b/apt-pkg/deb/dpkgpm.cc index 9f0da3be6..55525db85 100644 --- a/apt-pkg/deb/dpkgpm.cc +++ b/apt-pkg/deb/dpkgpm.cc @@ -44,6 +44,21 @@ using namespace std; +class pkgDPkgPMPrivate +{ +public: + pkgDPkgPMPrivate() : dpkgbuf_pos(0), term_out(NULL), history_out(NULL) + { + } + bool stdin_is_dev_null; + // the buffer we use for the dpkg status-fd reading + char dpkgbuf[1024]; + int dpkgbuf_pos; + FILE *term_out; + FILE *history_out; + string dpkg_error; +}; + namespace { // Maps the dpkg "processing" info to human readable names. Entry 0 @@ -108,9 +123,9 @@ ionice(int PID) // --------------------------------------------------------------------- /* */ pkgDPkgPM::pkgDPkgPM(pkgDepCache *Cache) - : pkgPackageManager(Cache), dpkgbuf_pos(0), - term_out(NULL), history_out(NULL), PackagesDone(0), PackagesTotal(0) + : pkgPackageManager(Cache), PackagesDone(0), PackagesTotal(0) { + d = new pkgDPkgPMPrivate(); } /*}}}*/ // DPkgPM::pkgDPkgPM - Destructor /*{{{*/ @@ -118,6 +133,7 @@ pkgDPkgPM::pkgDPkgPM(pkgDepCache *Cache) /* */ pkgDPkgPM::~pkgDPkgPM() { + delete d; } /*}}}*/ // DPkgPM::Install - Install a package /*{{{*/ @@ -369,7 +385,7 @@ void pkgDPkgPM::DoStdin(int master) if (len) write(master, input_buf, len); else - stdin_is_dev_null = true; + d->stdin_is_dev_null = true; } /*}}}*/ // DPkgPM::DoTerminalPty - Read the terminal pty and write log /*{{{*/ @@ -393,8 +409,8 @@ void pkgDPkgPM::DoTerminalPty(int master) if(len <= 0) return; write(1, term_buf, len); - if(term_out) - fwrite(term_buf, len, sizeof(char), term_out); + if(d->term_out) + fwrite(term_buf, len, sizeof(char), d->term_out); } /*}}}*/ // DPkgPM::ProcessDpkgStatusBuf /*{{{*/ @@ -598,14 +614,14 @@ void pkgDPkgPM::DoDpkgStatusFd(int statusfd, int OutStatusFd) char *p, *q; int len; - len=read(statusfd, &dpkgbuf[dpkgbuf_pos], sizeof(dpkgbuf)-dpkgbuf_pos); - dpkgbuf_pos += len; + len=read(statusfd, &d->dpkgbuf[d->dpkgbuf_pos], sizeof(d->dpkgbuf)-d->dpkgbuf_pos); + d->dpkgbuf_pos += len; if(len <= 0) return; // process line by line if we have a buffer - p = q = dpkgbuf; - while((q=(char*)memchr(p, '\n', dpkgbuf+dpkgbuf_pos-p)) != NULL) + p = q = d->dpkgbuf; + while((q=(char*)memchr(p, '\n', d->dpkgbuf+d->dpkgbuf_pos-p)) != NULL) { *q = 0; ProcessDpkgStatusLine(OutStatusFd, p); @@ -613,8 +629,8 @@ void pkgDPkgPM::DoDpkgStatusFd(int statusfd, int OutStatusFd) } // now move the unprocessed bits (after the final \n that is now a 0x0) - // to the start and update dpkgbuf_pos - p = (char*)memrchr(dpkgbuf, 0, dpkgbuf_pos); + // to the start and update d->dpkgbuf_pos + p = (char*)memrchr(d->dpkgbuf, 0, d->dpkgbuf_pos); if(p == NULL) return; @@ -622,8 +638,8 @@ void pkgDPkgPM::DoDpkgStatusFd(int statusfd, int OutStatusFd) p++; // move the unprocessed tail to the start and update pos - memmove(dpkgbuf, p, p-dpkgbuf); - dpkgbuf_pos = dpkgbuf+dpkgbuf_pos-p; + memmove(d->dpkgbuf, p, p-d->dpkgbuf); + d->dpkgbuf_pos = d->dpkgbuf+d->dpkgbuf_pos-p; } /*}}}*/ // DPkgPM::WriteHistoryTag /*{{{*/ @@ -635,7 +651,7 @@ void pkgDPkgPM::WriteHistoryTag(string const &tag, string value) // poor mans rstrip(", ") if (value[length-2] == ',' && value[length-1] == ' ') value.erase(length - 2, 2); - fprintf(history_out, "%s: %s\n", tag.c_str(), value.c_str()); + fprintf(d->history_out, "%s: %s\n", tag.c_str(), value.c_str()); } /*}}}*/ // DPkgPM::OpenLog /*{{{*/ bool pkgDPkgPM::OpenLog() @@ -656,13 +672,13 @@ bool pkgDPkgPM::OpenLog() _config->Find("Dir::Log::Terminal")); if (!logfile_name.empty()) { - term_out = fopen(logfile_name.c_str(),"a"); - if (term_out == NULL) + d->term_out = fopen(logfile_name.c_str(),"a"); + if (d->term_out == NULL) return _error->WarningE("OpenLog", _("Could not open file '%s'"), logfile_name.c_str()); - setvbuf(term_out, NULL, _IONBF, 0); - SetCloseExec(fileno(term_out), true); + setvbuf(d->term_out, NULL, _IONBF, 0); + SetCloseExec(fileno(d->term_out), true); chmod(logfile_name.c_str(), 0600); - fprintf(term_out, "\nLog started: %s\n", timestr); + fprintf(d->term_out, "\nLog started: %s\n", timestr); } // write your history @@ -670,11 +686,11 @@ bool pkgDPkgPM::OpenLog() _config->Find("Dir::Log::History")); if (!history_name.empty()) { - history_out = fopen(history_name.c_str(),"a"); - if (history_out == NULL) + d->history_out = fopen(history_name.c_str(),"a"); + if (d->history_out == NULL) return _error->WarningE("OpenLog", _("Could not open file '%s'"), history_name.c_str()); chmod(history_name.c_str(), 0644); - fprintf(history_out, "\nStart-Date: %s\n", timestr); + fprintf(d->history_out, "\nStart-Date: %s\n", timestr); string remove, purge, install, upgrade, downgrade; for (pkgCache::PkgIterator I = Cache.PkgBegin(); I.end() == false; I++) { @@ -704,7 +720,7 @@ bool pkgDPkgPM::OpenLog() WriteHistoryTag("Downgrade",downgrade); WriteHistoryTag("Remove",remove); WriteHistoryTag("Purge",purge); - fflush(history_out); + fflush(d->history_out); } return true; @@ -718,16 +734,16 @@ bool pkgDPkgPM::CloseLog() struct tm *tmp = localtime(&t); strftime(timestr, sizeof(timestr), "%F %T", tmp); - if(term_out) + if(d->term_out) { - fprintf(term_out, "Log ended: "); - fprintf(term_out, "%s", timestr); - fprintf(term_out, "\n"); - fclose(term_out); + fprintf(d->term_out, "Log ended: "); + fprintf(d->term_out, "%s", timestr); + fprintf(d->term_out, "\n"); + fclose(d->term_out); } - term_out = NULL; + d->term_out = NULL; - if(history_out) + if(d->history_out) { if (disappearedPkgs.empty() == false) { @@ -744,12 +760,12 @@ bool pkgDPkgPM::CloseLog() } WriteHistoryTag("Disappeared", disappear); } - if (dpkg_error.empty() == false) - fprintf(history_out, "Error: %s\n", dpkg_error.c_str()); - fprintf(history_out, "End-Date: %s\n", timestr); - fclose(history_out); + if (d->dpkg_error.empty() == false) + fprintf(d->history_out, "Error: %s\n", d->dpkg_error.c_str()); + fprintf(d->history_out, "End-Date: %s\n", timestr); + fclose(d->history_out); } - history_out = NULL; + d->history_out = NULL; return true; } @@ -857,7 +873,7 @@ bool pkgDPkgPM::Go(int OutStatusFd) } } - stdin_is_dev_null = false; + d->stdin_is_dev_null = false; // create log OpenLog(); @@ -1043,8 +1059,8 @@ bool pkgDPkgPM::Go(int OutStatusFd) const char *s = _("Can not write log, openpty() " "failed (/dev/pts not mounted?)\n"); fprintf(stderr, "%s",s); - if(term_out) - fprintf(term_out, "%s",s); + if(d->term_out) + fprintf(d->term_out, "%s",s); master = slave = -1; } else { struct termios rtt; @@ -1169,7 +1185,7 @@ bool pkgDPkgPM::Go(int OutStatusFd) // wait for input or output here FD_ZERO(&rfds); - if (master >= 0 && !stdin_is_dev_null) + if (master >= 0 && !d->stdin_is_dev_null) FD_SET(0, &rfds); FD_SET(_dpkgin, &rfds); if(master >= 0) @@ -1223,14 +1239,14 @@ bool pkgDPkgPM::Go(int OutStatusFd) RunScripts("DPkg::Post-Invoke"); if (WIFSIGNALED(Status) != 0 && WTERMSIG(Status) == SIGSEGV) - strprintf(dpkg_error, "Sub-process %s received a segmentation fault.",Args[0]); + strprintf(d->dpkg_error, "Sub-process %s received a segmentation fault.",Args[0]); else if (WIFEXITED(Status) != 0) - strprintf(dpkg_error, "Sub-process %s returned an error code (%u)",Args[0],WEXITSTATUS(Status)); + strprintf(d->dpkg_error, "Sub-process %s returned an error code (%u)",Args[0],WEXITSTATUS(Status)); else - strprintf(dpkg_error, "Sub-process %s exited unexpectedly",Args[0]); + strprintf(d->dpkg_error, "Sub-process %s exited unexpectedly",Args[0]); - if(dpkg_error.size() > 0) - _error->Error(dpkg_error.c_str()); + if(d->dpkg_error.size() > 0) + _error->Error(d->dpkg_error.c_str()); if(stopOnError) { @@ -1377,8 +1393,8 @@ void pkgDPkgPM::WriteApportReport(const char *pkgpath, const char *errormsg) fprintf(report, "ErrorMessage:\n %s\n", errormsg); // ensure that the log is flushed - if(term_out) - fflush(term_out); + if(d->term_out) + fflush(d->term_out); // attach terminal log it if we have it string logfile_name = _config->FindFile("Dir::Log::Terminal"); -- cgit v1.2.3 From 590f1923121815b36ef889033c1c416a23cbe9a2 Mon Sep 17 00:00:00 2001 From: Christopher Baines Date: Wed, 27 Jul 2011 15:20:35 +0100 Subject: SmartConfigure and SmartUnPack have got smarter! The full descriptions of what they now do is in the apt-pkg/packagemanager.cc file. The short version is that they will both put the system in a state where there operation can be achived, this involves calling themselves and each other recursively. Because SmartConfigure can now configure a package and all its dependancies itself, there is no current need for DepAdd (at least in packagemanager.cc), SmartConfigure also performs the function of the short lived VerifyConfigure as it checks through all the dependancies before performing configuration. Another change is to use the ConfigureAll method in OrderInstall to clean up any packages left unconfigured during ImmConfigureAll. This is necessary to inprove the safety of ImmConfiguration and because of the new SIGINT functionality of dpkgpm.cc relies on no packages being left unconfigured between pairs of dpkg calls. While writing this commit log, I have realised that the SIGINT stuff is a prototype and not ready to be used yet as I have only tested it twice. --- apt-pkg/deb/dpkgpm.cc | 15 ++++++++++++--- 1 file changed, 12 insertions(+), 3 deletions(-) (limited to 'apt-pkg/deb/dpkgpm.cc') diff --git a/apt-pkg/deb/dpkgpm.cc b/apt-pkg/deb/dpkgpm.cc index 5fbd1801a..3dbbd7c97 100644 --- a/apt-pkg/deb/dpkgpm.cc +++ b/apt-pkg/deb/dpkgpm.cc @@ -16,6 +16,7 @@ #include #include #include +#include #include #include @@ -888,7 +889,7 @@ bool pkgDPkgPM::Go(int OutStatusFd) OpenLog(); // this loop is runs once per operation - for (vector::const_iterator I = List.begin(); I != List.end();) + for (vector::const_iterator I = List.begin(); I != List.end() && !pkgPackageManager::SigINTStop;) { // Do all actions with the same Op in one run vector::const_iterator J = I; @@ -920,7 +921,7 @@ bool pkgDPkgPM::Go(int OutStatusFd) // the argument list is split in a way that A depends on B // and they are in the same "--configure A B" run // - with the split they may now be configured in different - // runs + // runs if (J - I > (signed)MaxArgs) J = I + MaxArgs; @@ -1062,7 +1063,7 @@ bool pkgDPkgPM::Go(int OutStatusFd) it to all processes in the group. Since dpkg ignores the signal it doesn't die but we do! So we must also ignore it */ sighandler_t old_SIGQUIT = signal(SIGQUIT,SIG_IGN); - sighandler_t old_SIGINT = signal(SIGINT,SIG_IGN); + sighandler_t old_SIGINT = signal(SIGINT,SigINT); // ignore SIGHUP as well (debian #463030) sighandler_t old_SIGHUP = signal(SIGHUP,SIG_IGN); @@ -1207,6 +1208,7 @@ bool pkgDPkgPM::Go(int OutStatusFd) // Restore sig int/quit signal(SIGQUIT,old_SIGQUIT); signal(SIGINT,old_SIGINT); + signal(SIGHUP,old_SIGHUP); return _error->Errno("waitpid","Couldn't wait for subprocess"); } @@ -1247,6 +1249,7 @@ bool pkgDPkgPM::Go(int OutStatusFd) // Restore sig int/quit signal(SIGQUIT,old_SIGQUIT); signal(SIGINT,old_SIGINT); + signal(SIGHUP,old_SIGHUP); if(master >= 0) @@ -1308,6 +1311,12 @@ bool pkgDPkgPM::Go(int OutStatusFd) Cache.writeStateFile(NULL); return true; } + +void SigINT(int sig) { + cout << " -- SIGINT -- " << endl; + if (_config->FindB("APT::Immediate-Configure-All",false)) + pkgPackageManager::SigINTStop = true; +} /*}}}*/ // pkgDpkgPM::Reset - Dump the contents of the command list /*{{{*/ // --------------------------------------------------------------------- -- cgit v1.2.3 From 1cecd4376cebdd0225ee91707b7630bc35959474 Mon Sep 17 00:00:00 2001 From: Christopher Baines Date: Sun, 31 Jul 2011 16:26:39 +0100 Subject: Only allow interupts when using, Immediate-Configure-All. TODO for dpkgpm: Useful messages about the interupt, what was done to what packages and what was not done to what packages. Only fail when the system is in a clean state, at the moment it will fail either a configure or install run. --- apt-pkg/deb/dpkgpm.cc | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) (limited to 'apt-pkg/deb/dpkgpm.cc') diff --git a/apt-pkg/deb/dpkgpm.cc b/apt-pkg/deb/dpkgpm.cc index 3dbbd7c97..479126658 100644 --- a/apt-pkg/deb/dpkgpm.cc +++ b/apt-pkg/deb/dpkgpm.cc @@ -889,7 +889,7 @@ bool pkgDPkgPM::Go(int OutStatusFd) OpenLog(); // this loop is runs once per operation - for (vector::const_iterator I = List.begin(); I != List.end() && !pkgPackageManager::SigINTStop;) + for (vector::const_iterator I = List.begin(); I != List.end();) { // Do all actions with the same Op in one run vector::const_iterator J = I; @@ -921,7 +921,7 @@ bool pkgDPkgPM::Go(int OutStatusFd) // the argument list is split in a way that A depends on B // and they are in the same "--configure A B" run // - with the split they may now be configured in different - // runs + // runs, using Immediate-Configure-All can help prevent this. if (J - I > (signed)MaxArgs) J = I + MaxArgs; @@ -1064,6 +1064,9 @@ bool pkgDPkgPM::Go(int OutStatusFd) it doesn't die but we do! So we must also ignore it */ sighandler_t old_SIGQUIT = signal(SIGQUIT,SIG_IGN); sighandler_t old_SIGINT = signal(SIGINT,SigINT); + + // Check here for any SIGINT + if (pkgPackageManager::SigINTStop) break; // ignore SIGHUP as well (debian #463030) sighandler_t old_SIGHUP = signal(SIGHUP,SIG_IGN); @@ -1102,7 +1105,6 @@ bool pkgDPkgPM::Go(int OutStatusFd) sigprocmask(SIG_SETMASK, &original_sigmask, 0); } } - // Fork dpkg pid_t Child; _config->Set("APT::Keep-Fds::",fd[1]); -- cgit v1.2.3 From 17182c0c66630c2fcba938edb5b27668f7495854 Mon Sep 17 00:00:00 2001 From: Christopher Baines Date: Mon, 1 Aug 2011 12:27:10 +0100 Subject: Only stop on SigInt if the system state is right (still needs more testing). More inprovements to the package manager to prevent packages from being configured twice. --- apt-pkg/deb/dpkgpm.cc | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'apt-pkg/deb/dpkgpm.cc') diff --git a/apt-pkg/deb/dpkgpm.cc b/apt-pkg/deb/dpkgpm.cc index 479126658..68d9ca1de 100644 --- a/apt-pkg/deb/dpkgpm.cc +++ b/apt-pkg/deb/dpkgpm.cc @@ -1066,7 +1066,8 @@ bool pkgDPkgPM::Go(int OutStatusFd) sighandler_t old_SIGINT = signal(SIGINT,SigINT); // Check here for any SIGINT - if (pkgPackageManager::SigINTStop) break; + if (pkgPackageManager::SigINTStop && + (I->Op == Item::Install || I->Op == Item::Remove || I->Op == Item::Purge)) break; // ignore SIGHUP as well (debian #463030) sighandler_t old_SIGHUP = signal(SIGHUP,SIG_IGN); @@ -1315,7 +1316,6 @@ bool pkgDPkgPM::Go(int OutStatusFd) } void SigINT(int sig) { - cout << " -- SIGINT -- " << endl; if (_config->FindB("APT::Immediate-Configure-All",false)) pkgPackageManager::SigINTStop = true; } -- cgit v1.2.3 From 11b87a08ee6952c5b66b14842283df3ea26b90ac Mon Sep 17 00:00:00 2001 From: Christopher Baines Date: Tue, 2 Aug 2011 10:29:11 +0100 Subject: Inproved the SIGINT stop in the dpkgpm, not perfect yet but it should work when using Immediate-Configure-All. --- apt-pkg/deb/dpkgpm.cc | 12 +++++++++--- 1 file changed, 9 insertions(+), 3 deletions(-) (limited to 'apt-pkg/deb/dpkgpm.cc') diff --git a/apt-pkg/deb/dpkgpm.cc b/apt-pkg/deb/dpkgpm.cc index 68d9ca1de..57361ccdc 100644 --- a/apt-pkg/deb/dpkgpm.cc +++ b/apt-pkg/deb/dpkgpm.cc @@ -954,6 +954,8 @@ bool pkgDPkgPM::Go(int OutStatusFd) snprintf(status_fd_buf,sizeof(status_fd_buf),"%i", fd[1]); Args[n++] = status_fd_buf; Size += strlen(Args[n-1]); + + unsigned long const Op = I->Op; switch (I->Op) { @@ -1066,9 +1068,10 @@ bool pkgDPkgPM::Go(int OutStatusFd) sighandler_t old_SIGINT = signal(SIGINT,SigINT); // Check here for any SIGINT - if (pkgPackageManager::SigINTStop && - (I->Op == Item::Install || I->Op == Item::Remove || I->Op == Item::Purge)) break; - + if (pkgPackageManager::SigINTStop && (Op == Item::Remove || Op == Item::Purge || Op == Item::Install)) + break; + + // ignore SIGHUP as well (debian #463030) sighandler_t old_SIGHUP = signal(SIGHUP,SIG_IGN); @@ -1290,6 +1293,9 @@ bool pkgDPkgPM::Go(int OutStatusFd) } } CloseLog(); + + if (pkgPackageManager::SigINTStop) + _error->Warning(_("Operation was interrupted before it could finish")); if (RunScripts("DPkg::Post-Invoke") == false) return false; -- cgit v1.2.3 From ea54214002c09eeb4dd498d97a564471ec9993c5 Mon Sep 17 00:00:00 2001 From: David Kalnischkies Date: Tue, 13 Sep 2011 10:09:00 +0200 Subject: reorder includes: add if needed and include it at first --- apt-pkg/deb/dpkgpm.cc | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'apt-pkg/deb/dpkgpm.cc') diff --git a/apt-pkg/deb/dpkgpm.cc b/apt-pkg/deb/dpkgpm.cc index 019b72bb8..7733390c0 100644 --- a/apt-pkg/deb/dpkgpm.cc +++ b/apt-pkg/deb/dpkgpm.cc @@ -8,6 +8,8 @@ ##################################################################### */ /*}}}*/ // Includes /*{{{*/ +#include + #include #include #include @@ -40,7 +42,6 @@ #include #include -#include #include /*}}}*/ -- cgit v1.2.3 From edca7af056e5f4e09dd0df235743c512ddfe83e7 Mon Sep 17 00:00:00 2001 From: David Kalnischkies Date: Tue, 20 Sep 2011 11:34:37 +0200 Subject: * apt-pkg/deb/dpkgpm.cc: - use std::vector instead of fixed size arrays to store args and multiarch-packagename strings --- apt-pkg/deb/dpkgpm.cc | 122 +++++++++++++++++++++++++------------------------- 1 file changed, 61 insertions(+), 61 deletions(-) (limited to 'apt-pkg/deb/dpkgpm.cc') diff --git a/apt-pkg/deb/dpkgpm.cc b/apt-pkg/deb/dpkgpm.cc index 0cc21f322..c17419819 100644 --- a/apt-pkg/deb/dpkgpm.cc +++ b/apt-pkg/deb/dpkgpm.cc @@ -927,10 +927,9 @@ bool pkgDPkgPM::Go(int OutStatusFd) /* nothing */; // Generate the argument list - const char *Args[MaxArgs + 50]; + std::vector Args; // keep track of allocated strings for multiarch package names - char *Packages[MaxArgs + 50]; - unsigned int pkgcount = 0; + std::vector Packages; // Now check if we are within the MaxArgs limit // @@ -940,13 +939,19 @@ bool pkgDPkgPM::Go(int OutStatusFd) // - with the split they may now be configured in different // runs, using Immediate-Configure-All can help prevent this. if (J - I > (signed)MaxArgs) + { J = I + MaxArgs; - - unsigned int n = 0; + Args.reserve(MaxArgs + 10); + } + else + { + Args.reserve((J - I) + 10); + } + unsigned long Size = 0; string const Tmp = _config->Find("Dir::Bin::dpkg","dpkg"); - Args[n++] = Tmp.c_str(); - Size += strlen(Args[n-1]); + Args.push_back(Tmp.c_str()); + Size += Tmp.length(); // Stick in any custom dpkg options Configuration::Item const *Opts = _config->Tree("DPkg::Options"); @@ -957,76 +962,64 @@ bool pkgDPkgPM::Go(int OutStatusFd) { if (Opts->Value.empty() == true) continue; - Args[n++] = Opts->Value.c_str(); + Args.push_back(Opts->Value.c_str()); Size += Opts->Value.length(); } } - char status_fd_buf[20]; int fd[2]; pipe(fd); - - Args[n++] = "--status-fd"; - Size += strlen(Args[n-1]); + +#define ADDARG(X) Args.push_back(X); Size += strlen(X) +#define ADDARGC(X) Args.push_back(X); Size += sizeof(X) - 1 + + ADDARGC("--status-fd"); + char status_fd_buf[20]; snprintf(status_fd_buf,sizeof(status_fd_buf),"%i", fd[1]); - Args[n++] = status_fd_buf; - Size += strlen(Args[n-1]); - + ADDARG(status_fd_buf); + unsigned long const Op = I->Op; switch (I->Op) { case Item::Remove: - Args[n++] = "--force-depends"; - Size += strlen(Args[n-1]); - Args[n++] = "--force-remove-essential"; - Size += strlen(Args[n-1]); - Args[n++] = "--remove"; - Size += strlen(Args[n-1]); + ADDARGC("--force-depends"); + ADDARGC("--force-remove-essential"); + ADDARGC("--remove"); break; case Item::Purge: - Args[n++] = "--force-depends"; - Size += strlen(Args[n-1]); - Args[n++] = "--force-remove-essential"; - Size += strlen(Args[n-1]); - Args[n++] = "--purge"; - Size += strlen(Args[n-1]); + ADDARGC("--force-depends"); + ADDARGC("--force-remove-essential"); + ADDARGC("--purge"); break; case Item::Configure: - Args[n++] = "--configure"; - Size += strlen(Args[n-1]); + ADDARGC("--configure"); break; case Item::ConfigurePending: - Args[n++] = "--configure"; - Size += strlen(Args[n-1]); - Args[n++] = "--pending"; - Size += strlen(Args[n-1]); + ADDARGC("--configure"); + ADDARGC("--pending"); break; case Item::TriggersPending: - Args[n++] = "--triggers-only"; - Size += strlen(Args[n-1]); - Args[n++] = "--pending"; - Size += strlen(Args[n-1]); + ADDARGC("--triggers-only"); + ADDARGC("--pending"); break; case Item::Install: - Args[n++] = "--unpack"; - Size += strlen(Args[n-1]); - Args[n++] = "--auto-deconfigure"; - Size += strlen(Args[n-1]); + ADDARGC("--unpack"); + ADDARGC("--auto-deconfigure"); break; } if (NoTriggers == true && I->Op != Item::TriggersPending && I->Op != Item::ConfigurePending) { - Args[n++] = "--no-triggers"; - Size += strlen(Args[n-1]); + ADDARGC("--no-triggers"); } +#undef ADDARGC // Write in the file or package names if (I->Op == Item::Install) @@ -1035,10 +1028,10 @@ bool pkgDPkgPM::Go(int OutStatusFd) { if (I->File[0] != '/') return _error->Error("Internal Error, Pathname to install is not absolute '%s'",I->File.c_str()); - Args[n++] = I->File.c_str(); - Size += strlen(Args[n-1]); + Args.push_back(I->File.c_str()); + Size += I->File.length(); } - } + } else { string const nativeArch = _config->Find("APT::Architecture"); @@ -1049,30 +1042,36 @@ bool pkgDPkgPM::Go(int OutStatusFd) continue; if (I->Op == Item::Configure && disappearedPkgs.find(I->Pkg.Name()) != disappearedPkgs.end()) continue; - if (I->Pkg.Arch() == nativeArch || !strcmp(I->Pkg.Arch(), "all")) - Args[n++] = I->Pkg.Name(); + if (false && (I->Pkg.Arch() == nativeArch || !strcmp(I->Pkg.Arch(), "all"))) + { + char const * const name = I->Pkg.Name(); + ADDARG(name); + } else { - Packages[pkgcount] = strdup(I->Pkg.FullName(false).c_str()); - Args[n++] = Packages[pkgcount++]; + char * const fullname = strdup(I->Pkg.FullName(false).c_str()); + Packages.push_back(fullname); + ADDARG(fullname); } - Size += strlen(Args[n-1]); } // skip configure action if all sheduled packages disappeared if (oldSize == Size) continue; } - Args[n] = 0; +#undef ADDARG + J = I; if (_config->FindB("Debug::pkgDPkgPM",false) == true) { - for (unsigned int k = 0; k != n; k++) - clog << Args[k] << ' '; - clog << endl; + for (std::vector::const_iterator a = Args.begin(); + a != Args.end(); ++a) + clog << *a << ' '; + clog << "size=" << Size << endl; continue; } - + Args.push_back(NULL); + cout << flush; clog << flush; cerr << flush; @@ -1186,7 +1185,7 @@ bool pkgDPkgPM::Go(int OutStatusFd) /* No Job Control Stop Env is a magic dpkg var that prevents it from using sigstop */ putenv((char *)"DPKG_NO_TSTP=yes"); - execvp(Args[0],(char **)Args); + execvp(Args[0], (char**) &Args[0]); cerr << "Could not exec dpkg!" << endl; _exit(100); } @@ -1212,10 +1211,11 @@ bool pkgDPkgPM::Go(int OutStatusFd) sigemptyset(&sigmask); sigprocmask(SIG_BLOCK,&sigmask,&original_sigmask); - /* clean up the temporary allocation for multiarch package names in - the parent, so we don't leak memory when we return. */ - for (unsigned int i = 0; i < pkgcount; i++) - free(Packages[i]); + /* free vectors (and therefore memory) as we don't need the included data anymore */ + for (std::vector::const_iterator p = Packages.begin(); + p != Packages.end(); ++p) + free(*p); + Packages.clear(); // the result of the waitpid call int res; -- cgit v1.2.3 From 11bcbdb93e13e0b2c1625fc0f926378bce43fead Mon Sep 17 00:00:00 2001 From: David Kalnischkies Date: Tue, 20 Sep 2011 11:54:15 +0200 Subject: load the dpkg base arguments only one time and reuse them later --- apt-pkg/deb/dpkgpm.cc | 50 ++++++++++++++++++++++++++++---------------------- 1 file changed, 28 insertions(+), 22 deletions(-) (limited to 'apt-pkg/deb/dpkgpm.cc') diff --git a/apt-pkg/deb/dpkgpm.cc b/apt-pkg/deb/dpkgpm.cc index c17419819..5eb6406c6 100644 --- a/apt-pkg/deb/dpkgpm.cc +++ b/apt-pkg/deb/dpkgpm.cc @@ -905,6 +905,28 @@ bool pkgDPkgPM::Go(int OutStatusFd) // create log OpenLog(); + // Generate the base argument list for dpkg + std::vector Args; + unsigned long StartSize = 0; + string const Tmp = _config->Find("Dir::Bin::dpkg","dpkg"); + 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(); + // this loop is runs once per operation for (vector::const_iterator I = List.begin(); I != List.end();) { @@ -926,11 +948,13 @@ bool pkgDPkgPM::Go(int OutStatusFd) for (; J != List.end() && J->Op == I->Op; ++J) /* nothing */; - // Generate the argument list - std::vector Args; // keep track of allocated strings for multiarch package names std::vector Packages; + // start with the baseset of arguments + unsigned long Size = StartSize; + Args.erase(Args.begin() + BaseArgs, Args.end()); + // Now check if we are within the MaxArgs limit // // this code below is problematic, because it may happen that @@ -948,24 +972,6 @@ bool pkgDPkgPM::Go(int OutStatusFd) Args.reserve((J - I) + 10); } - unsigned long Size = 0; - string const Tmp = _config->Find("Dir::Bin::dpkg","dpkg"); - Args.push_back(Tmp.c_str()); - Size += 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()); - Size += Opts->Value.length(); - } - } int fd[2]; pipe(fd); @@ -1042,7 +1048,7 @@ bool pkgDPkgPM::Go(int OutStatusFd) continue; if (I->Op == Item::Configure && disappearedPkgs.find(I->Pkg.Name()) != disappearedPkgs.end()) continue; - if (false && (I->Pkg.Arch() == nativeArch || !strcmp(I->Pkg.Arch(), "all"))) + if (I->Pkg.Arch() == nativeArch || !strcmp(I->Pkg.Arch(), "all")) { char const * const name = I->Pkg.Name(); ADDARG(name); @@ -1067,7 +1073,7 @@ bool pkgDPkgPM::Go(int OutStatusFd) for (std::vector::const_iterator a = Args.begin(); a != Args.end(); ++a) clog << *a << ' '; - clog << "size=" << Size << endl; + clog << endl; continue; } Args.push_back(NULL); -- cgit v1.2.3 From 86fc2ca8909eb686e2ad751acb0f0eaf706d9d5e Mon Sep 17 00:00:00 2001 From: David Kalnischkies Date: Fri, 13 Jan 2012 17:30:17 +0100 Subject: * apt-pkg/deb/dpkgpm.cc: - check if dpkg supports multiarch with --assert-multi-arch and if it does be always explicit about the architecture --- apt-pkg/deb/dpkgpm.cc | 73 ++++++++++++++++++++++++++++++++++++--------------- 1 file changed, 52 insertions(+), 21 deletions(-) (limited to 'apt-pkg/deb/dpkgpm.cc') diff --git a/apt-pkg/deb/dpkgpm.cc b/apt-pkg/deb/dpkgpm.cc index 7c0ed5639..4dc0baa50 100644 --- a/apt-pkg/deb/dpkgpm.cc +++ b/apt-pkg/deb/dpkgpm.cc @@ -108,7 +108,7 @@ ionice(int PID) { if (!FileExists("/usr/bin/ionice")) return false; - pid_t Process = ExecFork(); + pid_t Process = ExecFork(); if (Process == 0) { char buf[32]; @@ -829,6 +829,40 @@ static int racy_pselect(int nfds, fd_set *readfds, fd_set *writefds, */ bool pkgDPkgPM::Go(int OutStatusFd) { + // Generate the base argument list for dpkg + std::vector Args; + unsigned long StartSize = 0; + string const Tmp = _config->Find("Dir::Bin::dpkg","dpkg"); + 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) + { + execv(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; @@ -905,27 +939,20 @@ bool pkgDPkgPM::Go(int OutStatusFd) // create log OpenLog(); - // Generate the base argument list for dpkg - std::vector Args; - unsigned long StartSize = 0; - string const Tmp = _config->Find("Dir::Bin::dpkg","dpkg"); - 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) + bool dpkgMultiArch = false; + if (dpkgAssertMultiArch > 0) { - Opts = Opts->Child; - for (; Opts != 0; Opts = Opts->Next) + int Status = 0; + while (waitpid(dpkgAssertMultiArch, &Status, 0) != dpkgAssertMultiArch) { - if (Opts->Value.empty() == true) + if (errno == EINTR) continue; - Args.push_back(Opts->Value.c_str()); - StartSize += Opts->Value.length(); + _error->WarningE("dpkgGo", _("Waited for %s but it wasn't there"), "dpkg --assert-multi-arch"); + break; } + if (WIFEXITED(Status) == true && WEXITSTATUS(Status) == 0) + dpkgMultiArch = true; } - size_t const BaseArgs = Args.size(); // this loop is runs once per operation for (vector::const_iterator I = List.begin(); I != List.end();) @@ -965,14 +992,17 @@ bool pkgDPkgPM::Go(int OutStatusFd) if (J - I > (signed)MaxArgs) { J = I + MaxArgs; - Args.reserve(MaxArgs + 10); + unsigned long const size = MaxArgs + 10; + Args.reserve(size); + Packages.reserve(size); } else { - Args.reserve((J - I) + 10); + unsigned long const size = (J - I) + 10; + Args.reserve(size); + Packages.reserve(size); } - int fd[2]; pipe(fd); @@ -1047,7 +1077,8 @@ bool pkgDPkgPM::Go(int OutStatusFd) continue; if (I->Op == Item::Configure && disappearedPkgs.find(I->Pkg.Name()) != disappearedPkgs.end()) continue; - if (I->Pkg.Arch() == nativeArch || !strcmp(I->Pkg.Arch(), "all")) + // We keep this here to allow "smooth" transitions from e.g. multiarch dpkg/ubuntu to dpkg/debian + if (dpkgMultiArch == false && (I->Pkg.Arch() == nativeArch || !strcmp(I->Pkg.Arch(), "all"))) { char const * const name = I->Pkg.Name(); ADDARG(name); -- cgit v1.2.3 From 67b5d3dc34e88e092c8e5f05efc82370a873c80f Mon Sep 17 00:00:00 2001 From: David Kalnischkies Date: Thu, 19 Jan 2012 12:40:38 +0100 Subject: * apt-pkg/deb/dpkgpm.cc: - redirect out/input of dpkg --assert-multi-arch to /dev/null --- apt-pkg/deb/dpkgpm.cc | 5 +++++ 1 file changed, 5 insertions(+) (limited to 'apt-pkg/deb/dpkgpm.cc') diff --git a/apt-pkg/deb/dpkgpm.cc b/apt-pkg/deb/dpkgpm.cc index 4dc0baa50..0dc00e8ad 100644 --- a/apt-pkg/deb/dpkgpm.cc +++ b/apt-pkg/deb/dpkgpm.cc @@ -858,6 +858,11 @@ bool pkgDPkgPM::Go(int OutStatusFd) pid_t dpkgAssertMultiArch = ExecFork(); if (dpkgAssertMultiArch == 0) { + // 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); execv(Args[0], (char**) &Args[0]); _error->WarningE("dpkgGo", "Can't detect if dpkg supports multi-arch!"); _exit(2); -- cgit v1.2.3 From 3a5ec3053c00ff5db058f1ddd99bf23591b9a181 Mon Sep 17 00:00:00 2001 From: David Kalnischkies Date: Thu, 19 Jan 2012 13:12:14 +0100 Subject: if multi-arch is detected ensure that pkg:all is reported as pkg:all Versions with arch:all are added to the package with the native arch, so we can't rely on Pkg.Arch() for the architecture --- apt-pkg/deb/dpkgpm.cc | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) (limited to 'apt-pkg/deb/dpkgpm.cc') diff --git a/apt-pkg/deb/dpkgpm.cc b/apt-pkg/deb/dpkgpm.cc index 0dc00e8ad..6feada4cc 100644 --- a/apt-pkg/deb/dpkgpm.cc +++ b/apt-pkg/deb/dpkgpm.cc @@ -1090,7 +1090,10 @@ bool pkgDPkgPM::Go(int OutStatusFd) } else { - char * const fullname = strdup(I->Pkg.FullName(false).c_str()); + std::string name = I->Pkg.Name(); + pkgCache::VerIterator PkgVer = Cache[I->Pkg].InstVerIter(Cache); + name.append(":").append(PkgVer.Arch()); + char * const fullname = strdup(name.c_str()); Packages.push_back(fullname); ADDARG(fullname); } -- cgit v1.2.3 From 7720666fba9cd7024009bed964ccfa3f2be97c59 Mon Sep 17 00:00:00 2001 From: Michael Vogt Date: Thu, 19 Jan 2012 16:28:20 +0100 Subject: * apt-pkg/deb/dpkgpm.cc: - fix segfault on pkg removal --- apt-pkg/deb/dpkgpm.cc | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) (limited to 'apt-pkg/deb/dpkgpm.cc') diff --git a/apt-pkg/deb/dpkgpm.cc b/apt-pkg/deb/dpkgpm.cc index 6feada4cc..99c28d201 100644 --- a/apt-pkg/deb/dpkgpm.cc +++ b/apt-pkg/deb/dpkgpm.cc @@ -1090,8 +1090,12 @@ bool pkgDPkgPM::Go(int OutStatusFd) } else { + pkgCache::VerIterator PkgVer; std::string name = I->Pkg.Name(); - pkgCache::VerIterator PkgVer = Cache[I->Pkg].InstVerIter(Cache); + if (Op == Item::Remove || Op == Item::Purge) + PkgVer = I->Pkg.CurrentVer(); + else + PkgVer = Cache[I->Pkg].InstVerIter(Cache); name.append(":").append(PkgVer.Arch()); char * const fullname = strdup(name.c_str()); Packages.push_back(fullname); -- cgit v1.2.3 From 2a2a7ef4dfa9d8fb8118c2e318555438098cdf34 Mon Sep 17 00:00:00 2001 From: David Kalnischkies Date: Thu, 19 Jan 2012 18:42:57 +0100 Subject: * apt-pkg/cacheiterators.h: - return the correct version arch for all+foreign, too The flag is interpreted at a few other places in different styles so this commit ensures that the flag check is consistent everywhere (checking for Same in flag style is a bit too much as it isn't used in combination with others anyway, but who knows and just for consistency) --- apt-pkg/deb/dpkgpm.cc | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'apt-pkg/deb/dpkgpm.cc') diff --git a/apt-pkg/deb/dpkgpm.cc b/apt-pkg/deb/dpkgpm.cc index 99c28d201..2b04f0e71 100644 --- a/apt-pkg/deb/dpkgpm.cc +++ b/apt-pkg/deb/dpkgpm.cc @@ -1093,9 +1093,9 @@ bool pkgDPkgPM::Go(int OutStatusFd) pkgCache::VerIterator PkgVer; std::string name = I->Pkg.Name(); if (Op == Item::Remove || Op == Item::Purge) - PkgVer = I->Pkg.CurrentVer(); + PkgVer = I->Pkg.CurrentVer(); else - PkgVer = Cache[I->Pkg].InstVerIter(Cache); + PkgVer = Cache[I->Pkg].InstVerIter(Cache); name.append(":").append(PkgVer.Arch()); char * const fullname = strdup(name.c_str()); Packages.push_back(fullname); -- cgit v1.2.3 From e6ee75afbd4277df7bb2f5dc9ea03c18aecd3986 Mon Sep 17 00:00:00 2001 From: David Kalnischkies Date: Sun, 29 Jan 2012 12:59:42 +0100 Subject: * apt-pkg/deb/dpkgpm.cc: - chroot if needed before dpkg --assert-multi-arch --- apt-pkg/deb/dpkgpm.cc | 32 +++++++++++++++----------------- 1 file changed, 15 insertions(+), 17 deletions(-) (limited to 'apt-pkg/deb/dpkgpm.cc') diff --git a/apt-pkg/deb/dpkgpm.cc b/apt-pkg/deb/dpkgpm.cc index 2b04f0e71..4c473c1c2 100644 --- a/apt-pkg/deb/dpkgpm.cc +++ b/apt-pkg/deb/dpkgpm.cc @@ -123,6 +123,18 @@ ionice(int PID) return ExecWait(Process, "ionice"); } +// dpkgChrootDirectory - chrooting for dpkg if needed /*{{{*/ +static void dpkgChrootDirectory() +{ + std::string const chrootDir = _config->FindDir("DPkg::Chroot-Directory"); + if (chrootDir == "/") + return; + std::cerr << "Chrooting into " << chrootDir << std::endl; + if (chroot(chrootDir.c_str()) != 0) + _exit(100); +} + /*}}}*/ + // DPkgPM::pkgDPkgPM - Constructor /*{{{*/ // --------------------------------------------------------------------- /* */ @@ -328,15 +340,7 @@ bool pkgDPkgPM::RunScriptsWithPkgs(const char *Cnf) SetCloseExec(STDIN_FILENO,false); SetCloseExec(STDERR_FILENO,false); - if (_config->FindDir("DPkg::Chroot-Directory","/") != "/") - { - std::cerr << "Chrooting into " - << _config->FindDir("DPkg::Chroot-Directory") - << std::endl; - if (chroot(_config->FindDir("DPkg::Chroot-Directory","/").c_str()) != 0) - _exit(100); - } - + dpkgChrootDirectory(); const char *Args[4]; Args[0] = "/bin/sh"; Args[1] = "-c"; @@ -858,6 +862,7 @@ bool pkgDPkgPM::Go(int OutStatusFd) 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); @@ -1202,14 +1207,7 @@ bool pkgDPkgPM::Go(int OutStatusFd) } close(fd[0]); // close the read end of the pipe - if (_config->FindDir("DPkg::Chroot-Directory","/") != "/") - { - std::cerr << "Chrooting into " - << _config->FindDir("DPkg::Chroot-Directory") - << std::endl; - if (chroot(_config->FindDir("DPkg::Chroot-Directory","/").c_str()) != 0) - _exit(100); - } + dpkgChrootDirectory(); if (chdir(_config->FindDir("DPkg::Run-Directory","/").c_str()) != 0) _exit(100); -- cgit v1.2.3 From 734a6727696b42d5351f41b5b33ec767ccbd5db6 Mon Sep 17 00:00:00 2001 From: David Kalnischkies Date: Sun, 29 Jan 2012 13:10:38 +0100 Subject: ensure that dpkg binary doesn't have the chroot-directory prefixed --- apt-pkg/deb/dpkgpm.cc | 12 +++++++++++- 1 file changed, 11 insertions(+), 1 deletion(-) (limited to 'apt-pkg/deb/dpkgpm.cc') diff --git a/apt-pkg/deb/dpkgpm.cc b/apt-pkg/deb/dpkgpm.cc index 4c473c1c2..51e896a4a 100644 --- a/apt-pkg/deb/dpkgpm.cc +++ b/apt-pkg/deb/dpkgpm.cc @@ -836,7 +836,17 @@ bool pkgDPkgPM::Go(int OutStatusFd) // Generate the base argument list for dpkg std::vector Args; unsigned long StartSize = 0; - string const Tmp = _config->Find("Dir::Bin::dpkg","dpkg"); + 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(); -- cgit v1.2.3 From a13554816fac2ab7c5e876355f7b929790722b2c Mon Sep 17 00:00:00 2001 From: Michael Vogt Date: Mon, 30 Jan 2012 20:58:13 +0100 Subject: * apt-pkg/deb/dpkgpm.cc: - fix crash when a package is in removed but residual config state (LP: #923807) --- apt-pkg/deb/dpkgpm.cc | 38 ++++++++++++++++++++++++++++++++++++-- 1 file changed, 36 insertions(+), 2 deletions(-) (limited to 'apt-pkg/deb/dpkgpm.cc') diff --git a/apt-pkg/deb/dpkgpm.cc b/apt-pkg/deb/dpkgpm.cc index 51e896a4a..8c63b0c9b 100644 --- a/apt-pkg/deb/dpkgpm.cc +++ b/apt-pkg/deb/dpkgpm.cc @@ -135,6 +135,33 @@ static void dpkgChrootDirectory() } /*}}}*/ + +// FindNowVersion - Helper to find a Version in "now" state /*{{{*/ +// --------------------------------------------------------------------- +/* This is helpful when a package is no longer installed but has residual + * config files + */ +static +pkgCache::VerIterator FindNowVersion(const pkgCache::PkgIterator &Pkg) +{ + pkgCache::VerIterator Ver; + for (Ver = Pkg.VersionList(); Ver.end() == false; Ver++) + { + pkgCache::VerFileIterator Vf = Ver.FileList(); + pkgCache::PkgFileIterator F = Vf.File(); + for (F = Vf.File(); F.end() == false; F++) + { + if (F && F.Archive()) + { + if (strcmp(F.Archive(), "now")) + return Ver; + } + } + } + return Ver; +} + /*}}}*/ + // DPkgPM::pkgDPkgPM - Constructor /*{{{*/ // --------------------------------------------------------------------- /* */ @@ -1107,11 +1134,18 @@ bool pkgDPkgPM::Go(int OutStatusFd) { pkgCache::VerIterator PkgVer; std::string name = I->Pkg.Name(); - if (Op == Item::Remove || Op == Item::Purge) + if (Op == Item::Remove || Op == Item::Purge) + { PkgVer = I->Pkg.CurrentVer(); + if(PkgVer.end() == true) + PkgVer = FindNowVersion(I->Pkg); + } else PkgVer = Cache[I->Pkg].InstVerIter(Cache); - name.append(":").append(PkgVer.Arch()); + if (PkgVer.end() == false) + name.append(":").append(PkgVer.Arch()); + else + _error->Warning("Can not find PkgVer for '%s'", name.c_str()); char * const fullname = strdup(name.c_str()); Packages.push_back(fullname); ADDARG(fullname); -- cgit v1.2.3 From 17019a09e703452735d5af2538654e0532d27d51 Mon Sep 17 00:00:00 2001 From: David Kalnischkies Date: Thu, 9 Feb 2012 18:06:29 +0100 Subject: call dpkg --assert-multi-arch with execvp instead of execv --- apt-pkg/deb/dpkgpm.cc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'apt-pkg/deb/dpkgpm.cc') diff --git a/apt-pkg/deb/dpkgpm.cc b/apt-pkg/deb/dpkgpm.cc index 8c63b0c9b..3f9e68210 100644 --- a/apt-pkg/deb/dpkgpm.cc +++ b/apt-pkg/deb/dpkgpm.cc @@ -905,7 +905,7 @@ bool pkgDPkgPM::Go(int OutStatusFd) dup2(nullfd, STDIN_FILENO); dup2(nullfd, STDOUT_FILENO); dup2(nullfd, STDERR_FILENO); - execv(Args[0], (char**) &Args[0]); + execvp(Args[0], (char**) &Args[0]); _error->WarningE("dpkgGo", "Can't detect if dpkg supports multi-arch!"); _exit(2); } -- cgit v1.2.3 From dd61e64da1fbae01dc82bab3635c946718cc0eb0 Mon Sep 17 00:00:00 2001 From: David Kalnischkies Date: Sat, 11 Feb 2012 21:01:35 +0100 Subject: save the universe by not printing messages about apport if a package with this name is not installed (Closes: #619646) --- apt-pkg/deb/dpkgpm.cc | 6 ++++++ 1 file changed, 6 insertions(+) (limited to 'apt-pkg/deb/dpkgpm.cc') diff --git a/apt-pkg/deb/dpkgpm.cc b/apt-pkg/deb/dpkgpm.cc index 3f9e68210..499c3db8a 100644 --- a/apt-pkg/deb/dpkgpm.cc +++ b/apt-pkg/deb/dpkgpm.cc @@ -1446,6 +1446,12 @@ void pkgDPkgPM::Reset() /* */ void pkgDPkgPM::WriteApportReport(const char *pkgpath, const char *errormsg) { + // If apport doesn't exist or isn't installed do nothing + // This e.g. prevents messages in 'universes' without apport + pkgCache::PkgIterator apportPkg = Cache.FindPkg("apport"); + if (apportPkg.end() == true || apportPkg->CurrentVer == 0) + return; + string pkgname, reportfile, srcpkgname, pkgver, arch; string::size_type pos; FILE *report; -- cgit v1.2.3 From b1803e01ec18a4946523f3c3d0cbff2f0347ff30 Mon Sep 17 00:00:00 2001 From: David Kalnischkies Date: Sun, 4 Mar 2012 23:01:59 +0100 Subject: handle a SIGINT in all modes as a break after the currently running dpkg transaction instead of ignoring it completely --- apt-pkg/deb/dpkgpm.cc | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) (limited to 'apt-pkg/deb/dpkgpm.cc') diff --git a/apt-pkg/deb/dpkgpm.cc b/apt-pkg/deb/dpkgpm.cc index 499c3db8a..8aea2e1c8 100644 --- a/apt-pkg/deb/dpkgpm.cc +++ b/apt-pkg/deb/dpkgpm.cc @@ -860,6 +860,8 @@ static int racy_pselect(int nfds, fd_set *readfds, fd_set *writefds, */ bool pkgDPkgPM::Go(int OutStatusFd) { + pkgPackageManager::SigINTStop = false; + // Generate the base argument list for dpkg std::vector Args; unsigned long StartSize = 0; @@ -1429,9 +1431,8 @@ bool pkgDPkgPM::Go(int OutStatusFd) } void SigINT(int sig) { - if (_config->FindB("APT::Immediate-Configure-All",false)) - pkgPackageManager::SigINTStop = true; -} + pkgPackageManager::SigINTStop = true; +} /*}}}*/ // pkgDpkgPM::Reset - Dump the contents of the command list /*{{{*/ // --------------------------------------------------------------------- -- cgit v1.2.3 From dcaa1185506986142bccd990a5dca4c6ec1228cf Mon Sep 17 00:00:00 2001 From: David Kalnischkies Date: Sun, 4 Mar 2012 23:47:05 +0100 Subject: fix a bunch of cppcheck "(warning) Member variable '<#>' is not initialized in the constructor." messages (no functional change) --- apt-pkg/deb/dpkgpm.cc | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) (limited to 'apt-pkg/deb/dpkgpm.cc') diff --git a/apt-pkg/deb/dpkgpm.cc b/apt-pkg/deb/dpkgpm.cc index 8aea2e1c8..469132634 100644 --- a/apt-pkg/deb/dpkgpm.cc +++ b/apt-pkg/deb/dpkgpm.cc @@ -51,8 +51,10 @@ using namespace std; class pkgDPkgPMPrivate { public: - pkgDPkgPMPrivate() : dpkgbuf_pos(0), term_out(NULL), history_out(NULL) + pkgDPkgPMPrivate() : stdin_is_dev_null(false), dpkgbuf_pos(0), + term_out(NULL), history_out(NULL) { + dpkgbuf[0] = '\0'; } bool stdin_is_dev_null; // the buffer we use for the dpkg status-fd reading -- cgit v1.2.3 From b3c36c6e2f0c78797d1398e3176aac6a48b36295 Mon Sep 17 00:00:00 2001 From: David Kalnischkies Date: Mon, 5 Mar 2012 00:25:32 +0100 Subject: set char-limits for the scanf parsing previous crash-reports --- apt-pkg/deb/dpkgpm.cc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'apt-pkg/deb/dpkgpm.cc') diff --git a/apt-pkg/deb/dpkgpm.cc b/apt-pkg/deb/dpkgpm.cc index 469132634..c46a81209 100644 --- a/apt-pkg/deb/dpkgpm.cc +++ b/apt-pkg/deb/dpkgpm.cc @@ -1542,7 +1542,7 @@ void pkgDPkgPM::WriteApportReport(const char *pkgpath, const char *errormsg) if(strstr(strbuf,"Package:") == strbuf) { char pkgname[255], version[255]; - if(sscanf(strbuf, "Package: %s %s", pkgname, version) == 2) + if(sscanf(strbuf, "Package: %254s %254s", pkgname, version) == 2) if(strcmp(pkgver.c_str(), version) == 0) { fclose(report); -- cgit v1.2.3 From 319790f4f86f595724fb2bd5aa6274d345469010 Mon Sep 17 00:00:00 2001 From: David Kalnischkies Date: Tue, 20 Mar 2012 19:23:32 +0100 Subject: * methods/rred.cc: - check return of writev() as gcc recommends * methods/mirror.cc: - check return of chdir() as gcc recommends * apt-pkg/deb/dpkgpm.cc: - check return of write() a gcc recommends * apt-inst/deb/debfile.cc: - check return of chdir() as gcc recommends * apt-inst/deb/dpkgdb.cc: - check return of chdir() as gcc recommends --- apt-pkg/deb/dpkgpm.cc | 36 ++++++++++++++++++++++++++++-------- 1 file changed, 28 insertions(+), 8 deletions(-) (limited to 'apt-pkg/deb/dpkgpm.cc') diff --git a/apt-pkg/deb/dpkgpm.cc b/apt-pkg/deb/dpkgpm.cc index c46a81209..63c5a6380 100644 --- a/apt-pkg/deb/dpkgpm.cc +++ b/apt-pkg/deb/dpkgpm.cc @@ -163,6 +163,25 @@ pkgCache::VerIterator FindNowVersion(const pkgCache::PkgIterator &Pkg) return Ver; } /*}}}*/ +ssize_t retry_write(int fd, const void *buf, size_t count) +{ + int Res; + ssize_t i = 0; + errno = 0; + do + { + Res = write(fd, buf, count); + if (Res < 0 && errno == EINTR) + continue; + if (Res < 0) + break; + buf = (char *)buf + Res; + count -= Res; + i += Res; + } + while (Res > 0 && count > 0); + return i; +} // DPkgPM::pkgDPkgPM - Constructor /*{{{*/ // --------------------------------------------------------------------- @@ -425,7 +444,7 @@ void pkgDPkgPM::DoStdin(int master) unsigned char input_buf[256] = {0,}; ssize_t len = read(0, input_buf, sizeof(input_buf)); if (len) - write(master, input_buf, len); + retry_write(master, input_buf, len); else d->stdin_is_dev_null = true; } @@ -451,7 +470,7 @@ void pkgDPkgPM::DoTerminalPty(int master) } if(len <= 0) return; - write(1, term_buf, len); + retry_write(1, term_buf, len); if(d->term_out) fwrite(term_buf, len, sizeof(char), d->term_out); } @@ -526,7 +545,7 @@ void pkgDPkgPM::ProcessDpkgStatusLine(int OutStatusFd, char *line) << ":" << s << endl; if(OutStatusFd > 0) - write(OutStatusFd, status.str().c_str(), status.str().size()); + retry_write(OutStatusFd, status.str().c_str(), status.str().size()); if (Debug == true) std::clog << "send: '" << status.str() << "'" << endl; @@ -550,7 +569,7 @@ void pkgDPkgPM::ProcessDpkgStatusLine(int OutStatusFd, char *line) << ":" << list[3] << endl; if(OutStatusFd > 0) - write(OutStatusFd, status.str().c_str(), status.str().size()); + retry_write(OutStatusFd, status.str().c_str(), status.str().size()); if (Debug == true) std::clog << "send: '" << status.str() << "'" << endl; pkgFailures++; @@ -564,7 +583,7 @@ void pkgDPkgPM::ProcessDpkgStatusLine(int OutStatusFd, char *line) << ":" << list[3] << endl; if(OutStatusFd > 0) - write(OutStatusFd, status.str().c_str(), status.str().size()); + retry_write(OutStatusFd, status.str().c_str(), status.str().size()); if (Debug == true) std::clog << "send: '" << status.str() << "'" << endl; return; @@ -592,7 +611,7 @@ void pkgDPkgPM::ProcessDpkgStatusLine(int OutStatusFd, char *line) << ":" << s << endl; if(OutStatusFd > 0) - write(OutStatusFd, status.str().c_str(), status.str().size()); + retry_write(OutStatusFd, status.str().c_str(), status.str().size()); if (Debug == true) std::clog << "send: '" << status.str() << "'" << endl; } @@ -1055,7 +1074,8 @@ bool pkgDPkgPM::Go(int OutStatusFd) } int fd[2]; - pipe(fd); + if (pipe(fd) != 0) + return _error->Errno("pipe","Failed to create IPC pipe to dpkg"); #define ADDARG(X) Args.push_back(X); Size += strlen(X) #define ADDARGC(X) Args.push_back(X); Size += sizeof(X) - 1 @@ -1236,7 +1256,7 @@ bool pkgDPkgPM::Go(int OutStatusFd) << (PackagesDone/float(PackagesTotal)*100.0) << ":" << _("Running dpkg") << endl; - write(OutStatusFd, status.str().c_str(), status.str().size()); + retry_write(OutStatusFd, status.str().c_str(), status.str().size()); } Child = ExecFork(); -- cgit v1.2.3 From 136a6c13c8df7c403dd5284ff8bda20c8a84b614 Mon Sep 17 00:00:00 2001 From: David Kalnischkies Date: Thu, 22 Mar 2012 22:18:05 +0100 Subject: make these retry_write methods static so that they don't end up as symbols --- apt-pkg/deb/dpkgpm.cc | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'apt-pkg/deb/dpkgpm.cc') diff --git a/apt-pkg/deb/dpkgpm.cc b/apt-pkg/deb/dpkgpm.cc index 63c5a6380..1a21c03eb 100644 --- a/apt-pkg/deb/dpkgpm.cc +++ b/apt-pkg/deb/dpkgpm.cc @@ -163,7 +163,8 @@ pkgCache::VerIterator FindNowVersion(const pkgCache::PkgIterator &Pkg) return Ver; } /*}}}*/ -ssize_t retry_write(int fd, const void *buf, size_t count) +static ssize_t +retry_write(int fd, const void *buf, size_t count) { int Res; ssize_t i = 0; -- cgit v1.2.3 From d68d65ad637526e46ea77ab83e07470d26df15fc Mon Sep 17 00:00:00 2001 From: David Kalnischkies Date: Wed, 11 Apr 2012 13:25:28 +0200 Subject: use a static FileFd::Write overload to reduce duplication of write()-retry code --- apt-pkg/deb/dpkgpm.cc | 34 +++++++--------------------------- 1 file changed, 7 insertions(+), 27 deletions(-) (limited to 'apt-pkg/deb/dpkgpm.cc') diff --git a/apt-pkg/deb/dpkgpm.cc b/apt-pkg/deb/dpkgpm.cc index 1a21c03eb..496daf1df 100644 --- a/apt-pkg/deb/dpkgpm.cc +++ b/apt-pkg/deb/dpkgpm.cc @@ -163,26 +163,6 @@ pkgCache::VerIterator FindNowVersion(const pkgCache::PkgIterator &Pkg) return Ver; } /*}}}*/ -static ssize_t -retry_write(int fd, const void *buf, size_t count) -{ - int Res; - ssize_t i = 0; - errno = 0; - do - { - Res = write(fd, buf, count); - if (Res < 0 && errno == EINTR) - continue; - if (Res < 0) - break; - buf = (char *)buf + Res; - count -= Res; - i += Res; - } - while (Res > 0 && count > 0); - return i; -} // DPkgPM::pkgDPkgPM - Constructor /*{{{*/ // --------------------------------------------------------------------- @@ -445,7 +425,7 @@ void pkgDPkgPM::DoStdin(int master) unsigned char input_buf[256] = {0,}; ssize_t len = read(0, input_buf, sizeof(input_buf)); if (len) - retry_write(master, input_buf, len); + FileFd::Write(master, input_buf, len); else d->stdin_is_dev_null = true; } @@ -471,7 +451,7 @@ void pkgDPkgPM::DoTerminalPty(int master) } if(len <= 0) return; - retry_write(1, term_buf, len); + FileFd::Write(1, term_buf, len); if(d->term_out) fwrite(term_buf, len, sizeof(char), d->term_out); } @@ -546,7 +526,7 @@ void pkgDPkgPM::ProcessDpkgStatusLine(int OutStatusFd, char *line) << ":" << s << endl; if(OutStatusFd > 0) - retry_write(OutStatusFd, status.str().c_str(), status.str().size()); + FileFd::Write(OutStatusFd, status.str().c_str(), status.str().size()); if (Debug == true) std::clog << "send: '" << status.str() << "'" << endl; @@ -570,7 +550,7 @@ void pkgDPkgPM::ProcessDpkgStatusLine(int OutStatusFd, char *line) << ":" << list[3] << endl; if(OutStatusFd > 0) - retry_write(OutStatusFd, status.str().c_str(), status.str().size()); + FileFd::Write(OutStatusFd, status.str().c_str(), status.str().size()); if (Debug == true) std::clog << "send: '" << status.str() << "'" << endl; pkgFailures++; @@ -584,7 +564,7 @@ void pkgDPkgPM::ProcessDpkgStatusLine(int OutStatusFd, char *line) << ":" << list[3] << endl; if(OutStatusFd > 0) - retry_write(OutStatusFd, status.str().c_str(), status.str().size()); + FileFd::Write(OutStatusFd, status.str().c_str(), status.str().size()); if (Debug == true) std::clog << "send: '" << status.str() << "'" << endl; return; @@ -612,7 +592,7 @@ void pkgDPkgPM::ProcessDpkgStatusLine(int OutStatusFd, char *line) << ":" << s << endl; if(OutStatusFd > 0) - retry_write(OutStatusFd, status.str().c_str(), status.str().size()); + FileFd::Write(OutStatusFd, status.str().c_str(), status.str().size()); if (Debug == true) std::clog << "send: '" << status.str() << "'" << endl; } @@ -1257,7 +1237,7 @@ bool pkgDPkgPM::Go(int OutStatusFd) << (PackagesDone/float(PackagesTotal)*100.0) << ":" << _("Running dpkg") << endl; - retry_write(OutStatusFd, status.str().c_str(), status.str().size()); + FileFd::Write(OutStatusFd, status.str().c_str(), status.str().size()); } Child = ExecFork(); -- cgit v1.2.3