X-Git-Url: https://git.saurik.com/apt.git/blobdiff_plain/b2e465d6d32d2dc884f58b94acb7e35f671a87fe..f8ac1720a94468d1384e88a57729e6d9801b56fd:/apt-pkg/deb/dpkgpm.cc diff --git a/apt-pkg/deb/dpkgpm.cc b/apt-pkg/deb/dpkgpm.cc index 34c19ef4b..61c48dcbb 100644 --- a/apt-pkg/deb/dpkgpm.cc +++ b/apt-pkg/deb/dpkgpm.cc @@ -1,6 +1,6 @@ // -*- mode: cpp; mode: fold -*- // Description /*{{{*/ -// $Id: dpkgpm.cc,v 1.18 2001/02/20 07:03:17 jgg Exp $ +// $Id: dpkgpm.cc,v 1.28 2004/01/27 02:25:01 mdz Exp $ /* ###################################################################### DPKG Package Manager - Provide an interface to dpkg @@ -16,7 +16,7 @@ #include #include #include - + #include #include #include @@ -25,8 +25,11 @@ #include #include #include +#include /*}}}*/ +using namespace std; + // DPkgPM::pkgDPkgPM - Constructor /*{{{*/ // --------------------------------------------------------------------- /* */ @@ -141,7 +144,6 @@ bool pkgDPkgPM::RunScripts(const char *Cnf) return true; } - /*}}}*/ // DPkgPM::SendV2Pkgs - Send version 2 package info /*{{{*/ // --------------------------------------------------------------------- @@ -250,8 +252,6 @@ bool pkgDPkgPM::RunScriptsWithPkgs(const char *Cnf) string::size_type Pos; if ((Pos = OptSec.find(' ')) == string::npos || Pos == 0) Pos = OptSec.length(); - else - Pos--; OptSec = "DPkg::Tools::Options::" + string(Opts->Value.c_str(),Pos); unsigned int Version = _config->FindI(OptSec+"::Version",1); @@ -314,12 +314,6 @@ bool pkgDPkgPM::RunScriptsWithPkgs(const char *Cnf) Die = !SendV2Pkgs(F); fclose(F); - if (Die == true) - { - kill(Process,SIGINT); - ExecWait(Process,Opts->Value.c_str(),true); - return _error->Error("Failure running script %s",Opts->Value.c_str()); - } // Clean up the sub process if (ExecWait(Process,Opts->Value.c_str()) == false) @@ -328,13 +322,15 @@ bool pkgDPkgPM::RunScriptsWithPkgs(const char *Cnf) return true; } - /*}}}*/ // DPkgPM::Go - Run the sequence /*{{{*/ // --------------------------------------------------------------------- /* This globs the operations and calls dpkg */ -bool pkgDPkgPM::Go() +bool pkgDPkgPM::Go(int status_fd) { + unsigned int MaxArgs = _config->FindI("Dpkg::MaxArgs",8*1024); + unsigned int MaxArgBytes = _config->FindI("Dpkg::MaxArgBytes",32*1024); + if (RunScripts("DPkg::Pre-Invoke") == false) return false; @@ -347,13 +343,14 @@ bool pkgDPkgPM::Go() for (; J != List.end() && J->Op == I->Op; J++); // Generate the argument list - const char *Args[400]; - if (J - I > 350) - J = I + 350; + const char *Args[MaxArgs + 50]; + if (J - I > (signed)MaxArgs) + J = I + MaxArgs; unsigned int n = 0; unsigned long Size = 0; - Args[n++] = _config->Find("Dir::Bin::dpkg","dpkg").c_str(); + string Tmp = _config->Find("Dir::Bin::dpkg","dpkg"); + Args[n++] = Tmp.c_str(); Size += strlen(Args[n-1]); // Stick in any custom dpkg options @@ -370,6 +367,17 @@ bool pkgDPkgPM::Go() } } + // if we got a status_fd argument, we pass it to apt + char status_fd_buf[20]; + if(status_fd > 0) + { + Args[n++] = "--status-fd"; + Size += strlen(Args[n-1]); + snprintf(status_fd_buf,20,"%i",status_fd); + Args[n++] = status_fd_buf; + Size += strlen(Args[n-1]); + } + switch (I->Op) { case Item::Remove: @@ -404,7 +412,7 @@ bool pkgDPkgPM::Go() // Write in the file or package names if (I->Op == Item::Install) { - for (;I != J && Size < 1024; I++) + for (;I != J && Size < MaxArgBytes; I++) { if (I->File[0] != '/') return _error->Error("Internal Error, Pathname to install is not absolute '%s'",I->File.c_str()); @@ -414,7 +422,7 @@ bool pkgDPkgPM::Go() } else { - for (;I != J && Size < 1024; I++) + for (;I != J && Size < MaxArgBytes; I++) { Args[n++] = I->Pkg.Name(); Size += strlen(Args[n-1]); @@ -439,11 +447,15 @@ bool pkgDPkgPM::Go() it forks scripts. What happens is that when you hit ctrl-c it sends it to all processes in the group. Since dpkg ignores the signal it doesn't die but we do! So we must also ignore it */ - signal(SIGQUIT,SIG_IGN); - signal(SIGINT,SIG_IGN); + sighandler_t old_SIGQUIT = signal(SIGQUIT,SIG_IGN); + sighandler_t old_SIGINT = signal(SIGINT,SIG_IGN); // Fork dpkg - pid_t Child = ExecFork(); + pid_t Child; + if(status_fd > 0) + Child = ExecFork(status_fd); + else + Child = ExecFork(); // This is the child if (Child == 0) @@ -451,7 +463,7 @@ bool pkgDPkgPM::Go() if (chdir(_config->FindDir("DPkg::Run-Directory","/").c_str()) != 0) _exit(100); - if (_config->FindB("DPkg::FlushSTDIN",true) == true) + if (_config->FindB("DPkg::FlushSTDIN",true) == true && isatty(STDIN_FILENO)) { int Flags,dummy; if ((Flags = fcntl(STDIN_FILENO,F_GETFL,dummy)) < 0) @@ -482,12 +494,16 @@ bool pkgDPkgPM::Go() if (errno == EINTR) continue; RunScripts("DPkg::Post-Invoke"); + + // Restore sig int/quit + signal(SIGQUIT,old_SIGQUIT); + signal(SIGINT,old_SIGINT); return _error->Errno("waitpid","Couldn't wait for subprocess"); } // Restore sig int/quit - signal(SIGQUIT,SIG_DFL); - signal(SIGINT,SIG_DFL); + signal(SIGQUIT,old_SIGQUIT); + signal(SIGINT,old_SIGINT); // Check for an error code. if (WIFEXITED(Status) == 0 || WEXITSTATUS(Status) != 0)