]> 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)
committerMichal Privoznik <mprivozn@redhat.com>
Wed, 4 Jan 2012 09:40:23 +0000 (10:40 +0100)
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.

src/util/command.c

index f5effdf3e715aaa26cc2aa606d095f012c9ac13e..bdaa88b6d5ab6dd8dc23da043990a5d233226cc3 100644 (file)
@@ -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;
+                }
+            }
         }
     }