diff options
author | Michael Vogt <michael.vogt@ubuntu.com> | 2007-10-24 15:08:08 +0200 |
---|---|---|
committer | Michael Vogt <michael.vogt@ubuntu.com> | 2007-10-24 15:08:08 +0200 |
commit | 1fc825bf7be1e9842a0560261d684264c565589e (patch) | |
tree | 41be895f328bccbc7d3efec3cb3edd1fda3bd979 /apt-pkg/deb/dpkgpm.cc | |
parent | 9a3a3d1324c83206033ad275fb068867b5c58e05 (diff) |
* 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)
Diffstat (limited to 'apt-pkg/deb/dpkgpm.cc')
-rw-r--r-- | apt-pkg/deb/dpkgpm.cc | 22 |
1 files changed, 18 insertions, 4 deletions
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) |