From 26b3ade25dc90ab9288fcdd19af747eb62743013 Mon Sep 17 00:00:00 2001 From: Michael Vogt Date: Tue, 1 Apr 2014 12:17:17 +0200 Subject: [PATCH] do not crash on SIGPIPE in pkgDPkgPM::RunScriptsWithPkgs() If a external command closes the PIPE unexpectedly, do not crash in pkgDPkgPM::RunScriptsWithPkgs but ignore the SIGPIPE. --- apt-pkg/deb/dpkgpm.cc | 25 ++++++++++++++++++------- 1 file changed, 18 insertions(+), 7 deletions(-) diff --git a/apt-pkg/deb/dpkgpm.cc b/apt-pkg/deb/dpkgpm.cc index e68c2ca3..c3e7e1d1 100644 --- a/apt-pkg/deb/dpkgpm.cc +++ b/apt-pkg/deb/dpkgpm.cc @@ -399,10 +399,14 @@ bool pkgDPkgPM::SendPkgsInfo(FILE * const F, unsigned int const &Version) that are due to be installed. */ bool pkgDPkgPM::RunScriptsWithPkgs(const char *Cnf) { + bool result = true; + Configuration::Item const *Opts = _config->Tree(Cnf); if (Opts == 0 || Opts->Child == 0) return true; Opts = Opts->Child; + + sighandler_t old_sigpipe = signal(SIGPIPE, SIG_IGN); unsigned int Count = 1; for (; Opts != 0; Opts = Opts->Next, Count++) @@ -428,8 +432,10 @@ bool pkgDPkgPM::RunScriptsWithPkgs(const char *Cnf) std::set KeepFDs; MergeKeepFdsFromConfiguration(KeepFDs); int Pipes[2]; - if (pipe(Pipes) != 0) - return _error->Errno("pipe","Failed to create IPC pipe to subprocess"); + if (pipe(Pipes) != 0) { + result = _error->Errno("pipe","Failed to create IPC pipe to subprocess"); + break; + } if (InfoFD != (unsigned)Pipes[0]) SetCloseExec(Pipes[0],true); else @@ -463,8 +469,10 @@ bool pkgDPkgPM::RunScriptsWithPkgs(const char *Cnf) } close(Pipes[0]); FILE *F = fdopen(Pipes[1],"w"); - if (F == 0) - return _error->Errno("fdopen","Faild to open new FD"); + if (F == 0) { + result = _error->Errno("fdopen","Faild to open new FD"); + break; + } // Feed it the filenames. if (Version <= 1) @@ -492,11 +500,14 @@ bool pkgDPkgPM::RunScriptsWithPkgs(const char *Cnf) fclose(F); // Clean up the sub process - if (ExecWait(Process,Opts->Value.c_str()) == false) - return _error->Error("Failure running script %s",Opts->Value.c_str()); + if (ExecWait(Process,Opts->Value.c_str()) == false) { + result = _error->Error("Failure running script %s",Opts->Value.c_str()); + break; + } } + signal(SIGPIPE, old_sigpipe); - return true; + return result; } /*}}}*/ // DPkgPM::DoStdin - Read stdin and pass to slave pty /*{{{*/ -- 2.20.1