]> git.saurik.com Git - apt.git/commitdiff
Merge remote-tracking branch 'mvo/feature/install-progress' into debian/sid
authorMichael Vogt <mvo@debian.org>
Wed, 28 Aug 2013 08:59:54 +0000 (10:59 +0200)
committerMichael Vogt <mvo@debian.org>
Wed, 28 Aug 2013 08:59:54 +0000 (10:59 +0200)
1  2 
apt-pkg/deb/dpkgpm.cc

diff --combined apt-pkg/deb/dpkgpm.cc
index 4b5467eff14a6a138708ebf61cc00e67bb108666,3fb80d158667a274405344c3bf5e1a81ec6252d6..3c101376192f6c5ed2a0cd59562ddf08bebe3e04
@@@ -134,8 -134,6 +134,8 @@@ static void dpkgChrootDirectory(
     std::cerr << "Chrooting into " << chrootDir << std::endl;
     if (chroot(chrootDir.c_str()) != 0)
        _exit(100);
 +   if (chdir("/") != 0)
 +      _exit(100);
  }
                                                                        /*}}}*/
  
@@@ -296,7 -294,7 +296,7 @@@ bool pkgDPkgPM::SendPkgsInfo(FILE * con
        if (CurVer.end() == true && (I->Op == Item::Remove || I->Op == Item::Purge))
         CurVer = FindNowVersion(I->Pkg);
  
 -      else if (CurVer.end() == true)
 +      if (CurVer.end() == true)
        {
         if (Version <= 2)
            fprintf(F, "- ");
@@@ -382,32 -380,24 +382,32 @@@ bool pkgDPkgPM::RunScriptsWithPkgs(cons
        OptSec = "DPkg::Tools::Options::" + string(Opts->Value.c_str(),Pos);
        
        unsigned int Version = _config->FindI(OptSec+"::Version",1);
 +      unsigned int InfoFD = _config->FindI(OptSec + "::InfoFD", STDIN_FILENO);
        
        // Create the pipes
        int Pipes[2];
        if (pipe(Pipes) != 0)
         return _error->Errno("pipe","Failed to create IPC pipe to subprocess");
 -      SetCloseExec(Pipes[0],true);
 +      if (InfoFD != (unsigned)Pipes[0])
 +       SetCloseExec(Pipes[0],true);
 +      else
 +       _config->Set("APT::Keep-Fds::", Pipes[0]);
        SetCloseExec(Pipes[1],true);
 -      
 +
        // Purified Fork for running the script
 -      pid_t Process = ExecFork();      
 +      pid_t Process = ExecFork();
        if (Process == 0)
        {
         // Setup the FDs
 -       dup2(Pipes[0],STDIN_FILENO);
 +       dup2(Pipes[0], InfoFD);
         SetCloseExec(STDOUT_FILENO,false);
 -       SetCloseExec(STDIN_FILENO,false);      
 +       SetCloseExec(STDIN_FILENO,false);
         SetCloseExec(STDERR_FILENO,false);
  
 +       string hookfd;
 +       strprintf(hookfd, "%d", InfoFD);
 +       setenv("APT_HOOK_INFO_FD", hookfd.c_str(), 1);
 +
         dpkgChrootDirectory();
         const char *Args[4];
         Args[0] = "/bin/sh";
         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)
@@@ -632,6 -620,9 +632,9 @@@ void pkgDPkgPM::ProcessDpkgStatusLine(i
             << ":"  << (PackagesDone/float(PackagesTotal)*100.0) 
             << ":" << s
             << endl;
+       if(_config->FindB("DPkgPM::Progress", false) == true)
+          SendTerminalProgress(PackagesDone/float(PackagesTotal)*100.0);
        if(OutStatusFd > 0)
         FileFd::Write(OutStatusFd, status.str().c_str(), status.str().size());
        if (Debug == true)
@@@ -761,15 -752,13 +764,15 @@@ bool pkgDPkgPM::OpenLog(
         return _error->WarningE("OpenLog", _("Could not open file '%s'"), logfile_name.c_str());
        setvbuf(d->term_out, NULL, _IONBF, 0);
        SetCloseExec(fileno(d->term_out), true);
 -      struct passwd *pw;
 -      struct group *gr;
 -      pw = getpwnam("root");
 -      gr = getgrnam("adm");
 -      if (pw != NULL && gr != NULL)
 -        chown(logfile_name.c_str(), pw->pw_uid, gr->gr_gid);
 -      chmod(logfile_name.c_str(), 0640);
 +      if (getuid() == 0) // if we aren't root, we can't chown a file, so don't try it
 +      {
 +       struct passwd *pw = getpwnam("root");
 +       struct group *gr = getgrnam("adm");
 +       if (pw != NULL && gr != NULL && chown(logfile_name.c_str(), pw->pw_uid, gr->gr_gid) != 0)
 +          _error->WarningE("OpenLog", "chown to root:adm of file %s failed", logfile_name.c_str());
 +      }
 +      if (chmod(logfile_name.c_str(), 0640) != 0)
 +       _error->WarningE("OpenLog", "chmod 0640 of file %s failed", logfile_name.c_str());
        fprintf(d->term_out, "\nLog started: %s\n", timestr);
     }
  
@@@ -874,6 -863,18 +877,18 @@@ bool pkgDPkgPM::CloseLog(
     return true;
  }
                                                                        /*}}}*/
+ // DPkgPM::SendTerminalProgress                                       /*{{{*/
+ // ---------------------------------------------------------------------
+ /* Send progress info to the terminal
+  */
+ void pkgDPkgPM::SendTerminalProgress(float percentage)
+ {
+    // FIXME: use colors too
+    std::cout << "\r\n"
+              << "Progress: [" << percentage << "%]"
+              << "\r\n";
+ }
+                                                                       /*}}}*/
  /*{{{*/
  // This implements a racy version of pselect for those architectures
  // that don't have a working implementation.
@@@ -1248,13 -1249,16 +1263,13 @@@ bool pkgDPkgPM::Go(int OutStatusFd
  
        // if tcgetattr does not return zero there was a error
        // and we do not do any pty magic
 -      if (tcgetattr(0, &tt) == 0)
 +      _error->PushToStack();
 +      if (tcgetattr(STDOUT_FILENO, &tt) == 0)
        {
         ioctl(0, TIOCGWINSZ, (char *)&win);
 -       if (openpty(&master, &slave, NULL, &tt, &win) < 0) 
 +       if (openpty(&master, &slave, NULL, &tt, &win) < 0)
         {
 -          const char *s = _("Can not write log, openpty() "
 -                            "failed (/dev/pts not mounted?)\n");
 -          fprintf(stderr, "%s",s);
 -            if(d->term_out)
 -              fprintf(d->term_out, "%s",s);
 +          _error->Errno("openpty", _("Can not write log (%s)"), _("Is /dev/pts mounted?"));
            master = slave = -1;
         }  else {
            struct termios rtt;
            sigprocmask(SIG_SETMASK, &original_sigmask, 0);
         }
        }
 +      // complain only if stdout is either a terminal (but still failed) or is an invalid
 +      // descriptor otherwise we would complain about redirection to e.g. /dev/null as well.
 +      else if (isatty(STDOUT_FILENO) == 1 || errno == EBADF)
 +         _error->Errno("tcgetattr", _("Can not write log (%s)"), _("Is stdout a terminal?"));
 +
 +      if (_error->PendingError() == true)
 +       _error->DumpErrors(std::cerr);
 +      _error->RevertToStack();
 +
         // Fork dpkg
        pid_t Child;
        _config->Set("APT::Keep-Fds::",fd[1]);
         FileFd::Write(OutStatusFd, status.str().c_str(), status.str().size());
        }
        Child = ExecFork();
-             
+       
        // This is the child
        if (Child == 0)
        {