[Libguestfs] [PATCH libnbd] states: connect_command: Don't set O_NONBLOCK on socket passed to child.

Richard W.M. Jones rjones at redhat.com
Sat May 25 18:33:13 UTC 2019


I also made the code a bit more robust about closing the socket along
error paths.
---
 generator/states-connect.c | 21 ++++++++++++++++++---
 1 file changed, 18 insertions(+), 3 deletions(-)

diff --git a/generator/states-connect.c b/generator/states-connect.c
index ba8b240..a69b70f 100644
--- a/generator/states-connect.c
+++ b/generator/states-connect.c
@@ -27,6 +27,7 @@
 #include <stdbool.h>
 #include <string.h>
 #include <unistd.h>
+#include <fcntl.h>
 #include <errno.h>
 #include <signal.h>
 #include <netdb.h>
@@ -183,12 +184,12 @@
  CONNECT_COMMAND.START:
   int sv[2];
   pid_t pid;
+  int flags;
 
   assert (!h->sock);
   assert (h->argv);
   assert (h->argv[0]);
-  if (socketpair (AF_UNIX, SOCK_STREAM|SOCK_NONBLOCK|SOCK_CLOEXEC, 0,
-                  sv) == -1) {
+  if (socketpair (AF_UNIX, SOCK_STREAM|SOCK_CLOEXEC, 0, sv) == -1) {
     SET_NEXT_STATE (%.DEAD);
     set_error (errno, "socketpair");
     return -1;
@@ -219,13 +220,27 @@
   }
 
   /* Parent. */
+  close (sv[1]);
+
   h->pid = pid;
+
+  /* The socket must be set to non-blocking only in the parent,
+   * because the child may not be expecting a non-blocking socket.
+   */
+  flags = fcntl (sv[0], F_GETFL, 0);
+  if (flags == -1 ||
+      fcntl (sv[0], F_SETFL, flags|O_NONBLOCK) == -1) {
+    SET_NEXT_STATE (%.DEAD);
+    close (sv[0]);
+    return -1;
+  }
+
   h->sock = nbd_internal_socket_create (sv[0]);
   if (!h->sock) {
     SET_NEXT_STATE (%.DEAD);
+    close (sv[0]);
     return -1;
   }
-  close (sv[1]);
 
   /* The sockets are connected already, we can jump directly to
    * receiving the server magic.
-- 
2.21.0




More information about the Libguestfs mailing list