+ // Spawn the subprocess
+ if (Process == 0)
+ {
+ // Setup the signals
+ signal(SIGPIPE,SIG_DFL);
+ signal(SIGQUIT,SIG_DFL);
+ signal(SIGINT,SIG_DFL);
+ signal(SIGWINCH,SIG_DFL);
+ 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++)
+ {
+ if(KeepFDs.find(K) == KeepFDs.end())
+ fcntl(K,F_SETFD,FD_CLOEXEC);
+ }
+ }
+
+ return Process;
+}
+ /*}}}*/
+// ExecWait - Fancy waitpid /*{{{*/
+// ---------------------------------------------------------------------
+/* Waits for the given sub process. If Reap is set then no errors are
+ generated. Otherwise a failed subprocess will generate a proper descriptive
+ message */
+bool ExecWait(pid_t Pid,const char *Name,bool Reap)
+{
+ if (Pid <= 1)
+ return true;
+
+ // Wait and collect the error code
+ int Status;
+ while (waitpid(Pid,&Status,0) != Pid)
+ {
+ if (errno == EINTR)
+ continue;
+
+ if (Reap == true)
+ return false;
+
+ return _error->Error(_("Waited for %s but it wasn't there"),Name);
+ }
+
+
+ // Check for an error code.
+ if (WIFEXITED(Status) == 0 || WEXITSTATUS(Status) != 0)
+ {
+ if (Reap == true)
+ return false;
+ if (WIFSIGNALED(Status) != 0 && WTERMSIG(Status) == SIGSEGV)
+ return _error->Error(_("Sub-process %s received a segmentation fault."),Name);
+
+ if (WIFEXITED(Status) != 0)
+ return _error->Error(_("Sub-process %s returned an error code (%u)"),Name,WEXITSTATUS(Status));
+
+ return _error->Error(_("Sub-process %s exited unexpectedly"),Name);
+ }
+
+ return true;
+}
+ /*}}}*/
+
+// FileFd::Open - Open a file /*{{{*/