]> git.ipfire.org Git - thirdparty/libvirt.git/commitdiff
virCommand: Properly handle POLLHUP
authorMichal Privoznik <mprivozn@redhat.com>
Tue, 3 Jan 2012 17:40:55 +0000 (18:40 +0100)
committerEric Blake <eblake@redhat.com>
Thu, 17 May 2012 14:40:52 +0000 (08:40 -0600)
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.
(cherry picked from commit 06b9c5b9231ef4dbd4b5ff69564305cd4f814879)

src/util/command.c

index d3904780294c871673b8572a06261fa6edf720d2..e444f237c97927dbb902330e4b0c3c9deb479d54 100644 (file)
@@ -1604,16 +1604,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++;
         }
 
@@ -1629,8 +1632,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;
@@ -1668,7 +1671,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
@@ -1693,6 +1699,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;
+                }
+            }
         }
     }