summaryrefslogtreecommitdiff
path: root/apt-pkg/deb/dpkgpm.cc
diff options
context:
space:
mode:
authorMichael Vogt <michael.vogt@ubuntu.com>2007-10-20 07:52:26 +0200
committerMichael Vogt <michael.vogt@ubuntu.com>2007-10-20 07:52:26 +0200
commit7052511ef60897a02c00da43a309465380f93603 (patch)
tree9d8a1030632fba5ec6513263240e885247969e8d /apt-pkg/deb/dpkgpm.cc
parent477b5d6cacb53e868ec182330ffdcc3678a98560 (diff)
apt-pkg/deb/dpkgpm.cc:
- use pselect() instead of select() - on EIO error on pty master read, usleep(0.5s) to give up timeslice so that the child can properly exit
Diffstat (limited to 'apt-pkg/deb/dpkgpm.cc')
-rw-r--r--apt-pkg/deb/dpkgpm.cc22
1 files changed, 18 insertions, 4 deletions
diff --git a/apt-pkg/deb/dpkgpm.cc b/apt-pkg/deb/dpkgpm.cc
index 3235b0b06..8e1d7c85a 100644
--- a/apt-pkg/deb/dpkgpm.cc
+++ b/apt-pkg/deb/dpkgpm.cc
@@ -357,7 +357,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)
@@ -793,7 +801,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) {
@@ -816,8 +829,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)