From: Michal Privoznik Date: Tue, 3 Jan 2012 17:40:55 +0000 (+0100) Subject: virCommand: Properly handle POLLHUP X-Git-Tag: v0.9.9-rc2~5 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=06b9c5b9231ef4dbd4b5ff69564305cd4f814879;p=thirdparty%2Flibvirt.git virCommand: Properly handle POLLHUP It is a good practise to set revents to zero before doing any poll(). Moreover, we should check if event we waited for really occurred or if any of fds we were polling on didn't encountered hangup. --- diff --git a/src/util/command.c b/src/util/command.c index f5effdf3e7..bdaa88b6d5 100644 --- a/src/util/command.c +++ b/src/util/command.c @@ -1620,16 +1620,19 @@ virCommandProcessIO(virCommandPtr cmd) if (infd != -1) { fds[nfds].fd = infd; fds[nfds].events = POLLOUT; + fds[nfds].revents = 0; nfds++; } if (outfd != -1) { fds[nfds].fd = outfd; fds[nfds].events = POLLIN; + fds[nfds].revents = 0; nfds++; } if (errfd != -1) { fds[nfds].fd = errfd; fds[nfds].events = POLLIN; + fds[nfds].revents = 0; nfds++; } @@ -1645,8 +1648,8 @@ virCommandProcessIO(virCommandPtr cmd) } for (i = 0; i < nfds ; i++) { - if (fds[i].fd == errfd || - fds[i].fd == outfd) { + if (fds[i].revents & POLLIN && + (fds[i].fd == errfd || fds[i].fd == outfd)) { char data[1024]; char **buf; size_t *len; @@ -1684,7 +1687,10 @@ virCommandProcessIO(virCommandPtr cmd) memcpy(*buf + *len, data, done); *len += done; } - } else { + } + + if (fds[i].revents & POLLOUT && + fds[i].fd == infd) { int done; /* Coverity 5.3.0 can't see that we only get here if @@ -1710,6 +1716,18 @@ virCommandProcessIO(virCommandPtr cmd) } } + if (fds[i].revents & (POLLHUP | POLLERR)) { + if (fds[i].fd == errfd) { + VIR_DEBUG("hangup on stderr"); + errfd = -1; + } else if (fds[i].fd == outfd) { + VIR_DEBUG("hangup on stdout"); + outfd = -1; + } else { + VIR_DEBUG("hangup on stdin"); + infd = -1; + } + } } }