From 1fc825bf7be1e9842a0560261d684264c565589e Mon Sep 17 00:00:00 2001 From: Michael Vogt Date: Wed, 24 Oct 2007 15:08:08 +0200 Subject: * apt-pkg/deb/dpkgpm.{cc,h}: - give up timeslice on EIO error in read from master terminal * apt-pkg/deb/dpkgpm.{cc,h}: - rewrite dpkgpm.cc to use pselect() instead of select() to block signals during select() (LP: #134858) --- apt-pkg/deb/dpkgpm.cc | 22 ++++++++++++++++++---- 1 file changed, 18 insertions(+), 4 deletions(-) (limited to 'apt-pkg/deb/dpkgpm.cc') diff --git a/apt-pkg/deb/dpkgpm.cc b/apt-pkg/deb/dpkgpm.cc index ff0a3c443..7a6b222f6 100644 --- a/apt-pkg/deb/dpkgpm.cc +++ b/apt-pkg/deb/dpkgpm.cc @@ -358,7 +358,15 @@ void pkgDPkgPM::DoTerminalPty(int master) char term_buf[1024] = {0,}; int len=read(master, term_buf, sizeof(term_buf)); - if(len <= 0) + if(len == -1 && errno == EIO) + { + // this happens when the child is about to exit, we + // give it time to actually exit, otherwise we run + // into a race + usleep(500000); + return; + } + if(len <= 0) return; write(1, term_buf, len); if(term_out) @@ -819,7 +827,12 @@ bool pkgDPkgPM::Go(int OutStatusFd) // setups fds fd_set rfds; - struct timeval tv; + struct timespec tv; + sigset_t sigmask; + sigset_t original_sigmask; + sigemptyset(&sigmask); + sigprocmask(SIG_BLOCK,&sigmask,&original_sigmask); + int select_ret; while ((res=waitpid(Child,&Status, WNOHANG)) != Child) { if(res < 0) { @@ -842,8 +855,9 @@ bool pkgDPkgPM::Go(int OutStatusFd) if(master >= 0) FD_SET(master, &rfds); tv.tv_sec = 1; - tv.tv_usec = 0; - select_ret = select(max(master, _dpkgin)+1, &rfds, NULL, NULL, &tv); + tv.tv_nsec = 0; + select_ret = pselect(max(master, _dpkgin)+1, &rfds, NULL, NULL, + &tv, &original_sigmask); if (select_ret == 0) continue; else if (select_ret < 0 && errno == EINTR) -- cgit v1.2.3