Browse Source

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

tags/debian/0.9.13.exp1
Michael Vogt 8 years ago
parent
commit
e45c4617e4
5 changed files with 43 additions and 32 deletions
  1. +19
    -14
      apt-pkg/contrib/fileutl.cc
  2. +2
    -0
      apt-pkg/contrib/fileutl.h
  3. +14
    -12
      apt-pkg/deb/dpkgpm.cc
  4. +1
    -5
      apt-pkg/install-progress.cc
  5. +7
    -1
      apt-pkg/install-progress.h

+ 19
- 14
apt-pkg/contrib/fileutl.cc View File

@@ -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<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();
@@ -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++)
{


+ 2
- 0
apt-pkg/contrib/fileutl.h View File

@@ -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


+ 14
- 12
apt-pkg/deb/dpkgpm.cc View File

@@ -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)


+ 1
- 5
apt-pkg/install-progress.cc View File

@@ -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,


+ 7
- 1
apt-pkg/install-progress.h View File

@@ -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,


Loading…
Cancel
Save