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

Michael Vogt 12 years ago
parent
commit
e45c4617e4

+ 19 - 14
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,
    child, it fixes up the important signals and nukes all of the fds,
    otherwise acts like normal fork. */
    otherwise acts like normal fork. */
 pid_t ExecFork()
 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
    // Fork off the process
    pid_t Process = fork();
    pid_t Process = fork();
@@ -786,20 +805,6 @@ pid_t ExecFork()
       signal(SIGCONT,SIG_DFL);
       signal(SIGCONT,SIG_DFL);
       signal(SIGTSTP,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
       // Close all of our FDs - just in case
       for (int K = 3; K != 40; K++)
       for (int K = 3; K != 40; K++)
       {
       {

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

@@ -26,6 +26,7 @@
 
 
 #include <string>
 #include <string>
 #include <vector>
 #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);
 void SetNonBlock(int Fd,bool Block);
 bool WaitFd(int Fd,bool write = false,unsigned long timeout = 0);
 bool WaitFd(int Fd,bool write = false,unsigned long timeout = 0);
 pid_t ExecFork();
 pid_t ExecFork();
+pid_t ExecFork(std::set<int> keep_fds);
 bool ExecWait(pid_t Pid,const char *Name,bool Reap = false);
 bool ExecWait(pid_t Pid,const char *Name,bool Reap = false);
 
 
 // File string manipulators
 // File string manipulators

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

@@ -416,17 +416,20 @@ bool pkgDPkgPM::RunScriptsWithPkgs(const char *Cnf)
       unsigned int InfoFD = _config->FindI(OptSec + "::InfoFD", STDIN_FILENO);
       unsigned int InfoFD = _config->FindI(OptSec + "::InfoFD", STDIN_FILENO);
       
       
       // Create the pipes
       // Create the pipes
+      std::set<int> KeepFDs;
       int Pipes[2];
       int Pipes[2];
       if (pipe(Pipes) != 0)
       if (pipe(Pipes) != 0)
 	 return _error->Errno("pipe","Failed to create IPC pipe to subprocess");
 	 return _error->Errno("pipe","Failed to create IPC pipe to subprocess");
       if (InfoFD != (unsigned)Pipes[0])
       if (InfoFD != (unsigned)Pipes[0])
 	 SetCloseExec(Pipes[0],true);
 	 SetCloseExec(Pipes[0],true);
       else
       else
-	 _config->Set("APT::Keep-Fds::", Pipes[0]);
+         KeepFDs.insert(Pipes[0]);
+
+
       SetCloseExec(Pipes[1],true);
       SetCloseExec(Pipes[1],true);
 
 
       // Purified Fork for running the script
       // Purified Fork for running the script
-      pid_t Process = ExecFork();
+      pid_t Process = ExecFork(KeepFDs);
       if (Process == 0)
       if (Process == 0)
       {
       {
 	 // Setup the FDs
 	 // Setup the FDs
@@ -448,8 +451,6 @@ bool pkgDPkgPM::RunScriptsWithPkgs(const char *Cnf)
 	 execv(Args[0],(char **)Args);
 	 execv(Args[0],(char **)Args);
 	 _exit(100);
 	 _exit(100);
       }
       }
-      if (InfoFD == (unsigned)Pipes[0])
-	 _config->Clear("APT::Keep-Fds", Pipes[0]);
       close(Pipes[0]);
       close(Pipes[0]);
       FILE *F = fdopen(Pipes[1],"w");
       FILE *F = fdopen(Pipes[1],"w");
       if (F == 0)
       if (F == 0)
@@ -1375,11 +1376,14 @@ bool pkgDPkgPM::GoNoABIBreak(APT::Progress::PackageManager *progress)
       // ignore SIGHUP as well (debian #463030)
       // ignore SIGHUP as well (debian #463030)
       sighandler_t old_SIGHUP = signal(SIGHUP,SIG_IGN);
       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) 
 	 if(d->slave >= 0 && d->master >= 0) 
 	 {
 	 {
 	    setsid();
 	    setsid();
@@ -1425,9 +1429,6 @@ bool pkgDPkgPM::GoNoABIBreak(APT::Progress::PackageManager *progress)
       if (_config->FindB("DPkg::UseIoNice", false) == true)
       if (_config->FindB("DPkg::UseIoNice", false) == true)
 	 ionice(Child);
 	 ionice(Child);
 
 
-      // clear the Keep-Fd again
-      _config->Clear("APT::Keep-Fds",fd[1]);
-
       // Wait for dpkg
       // Wait for dpkg
       int Status = 0;
       int Status = 0;
 
 
@@ -1471,13 +1472,14 @@ bool pkgDPkgPM::GoNoABIBreak(APT::Progress::PackageManager *progress)
 	 FD_SET(_dpkgin, &rfds);
 	 FD_SET(_dpkgin, &rfds);
 	 if(d->master >= 0)
 	 if(d->master >= 0)
 	    FD_SET(d->master, &rfds);
 	    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, 
 	 select_ret = pselect(max(d->master, _dpkgin)+1, &rfds, NULL, NULL, 
 			      &tv, &d->original_sigmask);
 			      &tv, &d->original_sigmask);
 	 if (select_ret < 0 && (errno == EINVAL || errno == ENOSYS))
 	 if (select_ret < 0 && (errno == EINVAL || errno == ENOSYS))
 	    select_ret = racy_pselect(max(d->master, _dpkgin)+1, &rfds, NULL,
 	    select_ret = racy_pselect(max(d->master, _dpkgin)+1, &rfds, NULL,
 				      NULL, &tv, &d->original_sigmask);
 				      NULL, &tv, &d->original_sigmask);
+         d->progress->Pulse();
 	 if (select_ret == 0) 
 	 if (select_ret == 0) 
   	    continue;
   	    continue;
   	 else if (select_ret < 0 && errno == EINTR)
   	 else if (select_ret < 0 && errno == EINTR)

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

@@ -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)
    if(OutStatusFd <= 0)
       return;
       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,

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

@@ -27,9 +27,15 @@ namespace Progress {
        : percentage(0.0), last_reported_progress(-1) {};
        : percentage(0.0), last_reported_progress(-1) {};
     virtual ~PackageManager() {};
     virtual ~PackageManager() {};
 
 
+    /* Global Start/Stop */
     virtual void Start() {};
     virtual void Start() {};
     virtual void Stop() {};
     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 pid_t fork() {return fork(); };
 
 
     virtual void Pulse() {};
     virtual void Pulse() {};
@@ -62,7 +68,7 @@ namespace Progress {
  public:
  public:
     PackageManagerProgressFd(int progress_fd);
     PackageManagerProgressFd(int progress_fd);
 
 
-    virtual void Start();
+    virtual void StartDpkg();
     virtual void Stop();
     virtual void Stop();
 
 
     virtual bool StatusChanged(std::string PackageName, 
     virtual bool StatusChanged(std::string PackageName,