Просмотр исходного кода

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
Родитель
Сommit
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,
    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

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

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

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

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