Browse Source

streamline dpkgpm cleanup-handling

The (unlikely) waitpid failure case should fallthrough the code just
like the other failures (and successes) instead of taking a shortcut
avoiding all the cleanup (progress) and finishing touches (log, state).

This also delays the cleanup of the progress until apt is really done
with everything and "just" has the post-invokes left to do, so the
period of 'apt looks finished as it stopped the progress' and 'apt
really finished as I have the shell-prompt back' is shorter even if
there is no progress reported anymore, so the bar lingers at 100%…

Ideally even the post-invokes would be covered by progress, but they
can have their own output and dealing with that could be hard.

Git-Dch: Ignore
David Kalnischkies 10 years ago
parent
commit
6a1de8b792
1 changed files with 17 additions and 14 deletions
  1. 17 14
      apt-pkg/deb/dpkgpm.cc

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

@@ -1530,20 +1530,14 @@ bool pkgDPkgPM::Go(APT::Progress::PackageManager *progress)
       // the result of the waitpid call
       int res;
       int select_ret;
+      bool waitpid_failure = false;
       while ((res=waitpid(Child,&Status, WNOHANG)) != Child) {
 	 if(res < 0) {
-	    // FIXME: move this to a function or something, looks ugly here
 	    // error handling, waitpid returned -1
 	    if (errno == EINTR)
 	       continue;
-	    RunScripts("DPkg::Post-Invoke");
-
-	    // Restore sig int/quit
-	    signal(SIGQUIT,old_SIGQUIT);
-	    signal(SIGINT,old_SIGINT);
-
-	    signal(SIGHUP,old_SIGHUP);
-	    return _error->Errno("waitpid","Couldn't wait for subprocess");
+	    waitpid_failure = true;
+	    break;
 	 }
 
 	 // wait for input or output here
@@ -1583,8 +1577,15 @@ bool pkgDPkgPM::Go(APT::Progress::PackageManager *progress)
       // Restore sig int/quit
       signal(SIGQUIT,old_SIGQUIT);
       signal(SIGINT,old_SIGINT);
-      
       signal(SIGHUP,old_SIGHUP);
+
+      if (waitpid_failure == true)
+      {
+	 strprintf(d->dpkg_error, "Sub-process %s couldn't be waited for.",Args[0]);
+	 _error->Error("%s", d->dpkg_error.c_str());
+	 break;
+      }
+
       // Check for an error code.
       if (WIFEXITED(Status) == 0 || WEXITSTATUS(Status) != 0)
       {
@@ -1606,16 +1607,12 @@ bool pkgDPkgPM::Go(APT::Progress::PackageManager *progress)
       }
    }
    // dpkg is done at this point
-   d->progress->Stop();
    StopPtyMagic();
    CloseLog();
 
    if (pkgPackageManager::SigINTStop)
        _error->Warning(_("Operation was interrupted before it could finish"));
 
-   if (RunScripts("DPkg::Post-Invoke") == false)
-      return false;
-
    if (_config->FindB("Debug::pkgDPkgPM",false) == false)
    {
       std::string const oldpkgcache = _config->FindFile("Dir::cache::pkgcache");
@@ -1634,6 +1631,12 @@ bool pkgDPkgPM::Go(APT::Progress::PackageManager *progress)
    }
 
    Cache.writeStateFile(NULL);
+
+   d->progress->Stop();
+
+   if (RunScripts("DPkg::Post-Invoke") == false)
+      return false;
+
    return d->dpkg_error.empty();
 }