Furthermore, explain in a comment that *not* calling set_error() upon
nbd_internal_socket_create() failing is intentional, and not an omission.
Signed-off-by: Laszlo Ersek <lersek(a)redhat.com>
Reviewed-by: Richard W.M. Jones <rjones(a)redhat.com>
---
Notes:
v4:
- pick up Rich's R-b
context:-W
generator/states-connect.c | 2 ++
1 file changed, 2 insertions(+)
diff --git a/generator/states-connect.c b/generator/states-connect.c
index 137350cc77e6..2fd7429ae056 100644
--- a/generator/states-connect.c
+++ b/generator/states-connect.c
@@ -240,71 +240,73 @@ CONNECT_TCP.NEXT_ADDRESS:
CONNECT_COMMAND.START:
int sv[2];
pid_t pid;
int flags;
assert (!h->sock);
assert (h->argv.ptr);
assert (h->argv.ptr[0]);
if (nbd_internal_socketpair (AF_UNIX, SOCK_STREAM, 0, sv) == -1) {
SET_NEXT_STATE (%.DEAD);
set_error (errno, "socketpair");
return 0;
}
pid = fork ();
if (pid == -1) {
SET_NEXT_STATE (%.DEAD);
set_error (errno, "fork");
close (sv[0]);
close (sv[1]);
return 0;
}
if (pid == 0) { /* child - run command */
close (0);
close (1);
close (sv[0]);
dup2 (sv[1], 0);
dup2 (sv[1], 1);
close (sv[1]);
/* Restore SIGPIPE back to SIG_DFL. */
signal (SIGPIPE, SIG_DFL);
execvp (h->argv.ptr[0], h->argv.ptr);
nbd_internal_fork_safe_perror (h->argv.ptr[0]);
if (errno == ENOENT)
_exit (127);
else
_exit (126);
}
/* Parent. */
close (sv[1]);
h->pid = pid;
/* Only the parent-side end of the socket pair must be set to non-blocking,
* 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);
+ set_error (errno, "fcntl");
close (sv[0]);
return 0;
}
h->sock = nbd_internal_socket_create (sv[0]);
if (!h->sock) {
SET_NEXT_STATE (%.DEAD);
+ /* nbd_internal_socket_create() calls set_error() internally */
close (sv[0]);
return 0;
}
/* The sockets are connected already, we can jump directly to
* receiving the server magic.
*/
SET_NEXT_STATE (%^MAGIC.START);
return 0;
} /* END STATE MACHINE */