summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMichael Vogt <mvo@debian.org>2013-10-31 22:55:38 +0100
committerMichael Vogt <mvo@debian.org>2013-10-31 22:55:38 +0100
commite45c4617e496b49f8d7225546a751022f246a2f3 (patch)
tree19fa436f3760c896d997baedb89fd128594279ce
parent177296dffd8bf7d9ce5870b135c412958aab3756 (diff)
add new pid_t ExecFork(std::set<int> KeepFDs) to get rid of the super ugly APT::Keep-Fds hack and also add a new PackageManagerProgressFd::StartDpkg() progress state
-rw-r--r--apt-pkg/contrib/fileutl.cc33
-rw-r--r--apt-pkg/contrib/fileutl.h2
-rw-r--r--apt-pkg/deb/dpkgpm.cc26
-rw-r--r--apt-pkg/install-progress.cc6
-rw-r--r--apt-pkg/install-progress.h8
5 files changed, 43 insertions, 32 deletions
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
@@ -767,6 +767,25 @@ bool WaitFd(int Fd,bool write,unsigned long timeout)
otherwise acts like normal fork. */
pid_t ExecFork()
{
+ set<int> 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<int> KeepFDs)
+{
// Fork off the process
pid_t Process = fork();
if (Process < 0)
@@ -786,20 +805,6 @@ pid_t ExecFork()
signal(SIGCONT,SIG_DFL);
signal(SIGTSTP,SIG_DFL);
- set<int> 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 <string>
#include <vector>
+#include <set>
#include <zlib.h>
@@ -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<int> 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<int> 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<int> 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,