]> git.saurik.com Git - apt.git/commitdiff
add new pid_t ExecFork(std::set<int> KeepFDs) to get rid of the super ugly APT::Keep...
authorMichael Vogt <mvo@debian.org>
Thu, 31 Oct 2013 21:55:38 +0000 (22:55 +0100)
committerMichael Vogt <mvo@debian.org>
Thu, 31 Oct 2013 21:55:38 +0000 (22:55 +0100)
apt-pkg/contrib/fileutl.cc
apt-pkg/contrib/fileutl.h
apt-pkg/deb/dpkgpm.cc
apt-pkg/install-progress.cc
apt-pkg/install-progress.h

index 0261119ba120001b2f233b343a9f40503f4eb5f4..2347ef14034b38417e81b3e8cab4b40b804c3c3c 100644 (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()
    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();
 {
    // Fork off the process
    pid_t Process = fork();
@@ -786,20 +805,6 @@ pid_t ExecFork()
       signal(SIGCONT,SIG_DFL);
       signal(SIGTSTP,SIG_DFL);
 
       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++)
       {
       // Close all of our FDs - just in case
       for (int K = 3; K != 40; K++)
       {
index decd64d9d37b06d1d1f8ea27a0d7b5d11a8516d9..63a999c30abd798e25ca19b091c2ad826954be20 100644 (file)
@@ -26,6 +26,7 @@
 
 #include <string>
 #include <vector>
 
 #include <string>
 #include <vector>
+#include <set>
 
 #include <zlib.h>
 
 
 #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();
 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
 bool ExecWait(pid_t Pid,const char *Name,bool Reap = false);
 
 // File string manipulators
index d1b11098c5304f5a8316ff478c8a3226cbb4fa8d..26d79dbb11b281ca64aed4c33d87e55b397da781 100644 (file)
@@ -416,17 +416,20 @@ bool pkgDPkgPM::RunScriptsWithPkgs(const char *Cnf)
       unsigned int InfoFD = _config->FindI(OptSec + "::InfoFD", STDIN_FILENO);
       
       // Create the pipes
       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
       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
       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
       if (Process == 0)
       {
         // Setup the FDs
@@ -448,8 +451,6 @@ bool pkgDPkgPM::RunScriptsWithPkgs(const char *Cnf)
         execv(Args[0],(char **)Args);
         _exit(100);
       }
         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)
       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);
 
       // 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)
       {
       if (Child == 0)
       {
-
+         // This is the child
         if(d->slave >= 0 && d->master >= 0) 
         {
            setsid();
         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);
 
       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;
 
       // 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);
         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);
         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)
         if (select_ret == 0) 
            continue;
         else if (select_ret < 0 && errno == EINTR)
index a9146f27d600ac1f1748a172fa193fc1a7de136a..79660b29e19b06cb53b9a603123464b30d5134d6 100644 (file)
@@ -63,7 +63,7 @@ void PackageManagerProgressFd::WriteToStatusFd(std::string s)
    FileFd::Write(OutStatusFd, s.c_str(), s.size());   
 }
 
    FileFd::Write(OutStatusFd, s.c_str(), s.size());   
 }
 
-void PackageManagerProgressFd::Start()
+void PackageManagerProgressFd::StartDpkg()
 {
    if(OutStatusFd <= 0)
       return;
 {
    if(OutStatusFd <= 0)
       return;
@@ -83,8 +83,6 @@ void PackageManagerProgressFd::Start()
 
 void PackageManagerProgressFd::Stop()
 {
 
 void PackageManagerProgressFd::Stop()
 {
-   // clear the Keep-Fd again
-   _config->Clear("APT::Keep-Fds", OutStatusFd);
 }
 
 void PackageManagerProgressFd::Error(std::string PackageName,
 }
 
 void PackageManagerProgressFd::Error(std::string PackageName,
@@ -168,8 +166,6 @@ void PackageManagerProgressDeb822Fd::Start()
 
 void PackageManagerProgressDeb822Fd::Stop()
 {
 
 void PackageManagerProgressDeb822Fd::Stop()
 {
-   // clear the Keep-Fd again
-   _config->Clear("APT::Keep-Fds", OutStatusFd);
 }
 
 void PackageManagerProgressDeb822Fd::Error(std::string PackageName,
 }
 
 void PackageManagerProgressDeb822Fd::Error(std::string PackageName,
index 050954bb5c74dc82158c6daddf56b97e5d8af366..5291039d809b209c3590e25cb177ca6a8ab789e8 100644 (file)
@@ -27,9 +27,15 @@ namespace Progress {
        : percentage(0.0), last_reported_progress(-1) {};
     virtual ~PackageManager() {};
 
        : percentage(0.0), last_reported_progress(-1) {};
     virtual ~PackageManager() {};
 
+    /* Global Start/Stop */
     virtual void Start() {};
     virtual void 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() {};
     virtual pid_t fork() {return fork(); };
 
     virtual void Pulse() {};
@@ -62,7 +68,7 @@ namespace Progress {
  public:
     PackageManagerProgressFd(int progress_fd);
 
  public:
     PackageManagerProgressFd(int progress_fd);
 
-    virtual void Start();
+    virtual void StartDpkg();
     virtual void Stop();
 
     virtual bool StatusChanged(std::string PackageName, 
     virtual void Stop();
 
     virtual bool StatusChanged(std::string PackageName,