ext/libuv/src/unix/tcp.c in libuv-2.0.12 vs ext/libuv/src/unix/tcp.c in libuv-3.0.0
- old
+ new
@@ -113,10 +113,14 @@
if (setsockopt(tcp->io_watcher.fd,
IPPROTO_IPV6,
IPV6_V6ONLY,
&on,
sizeof on) == -1) {
+#if defined(__MVS__)
+ if (errno == EOPNOTSUPP)
+ return -EINVAL;
+#endif
return -errno;
}
}
#endif
@@ -128,10 +132,11 @@
return -EINVAL;
return -errno;
}
tcp->delayed_error = -errno;
+ tcp->flags |= UV_HANDLE_BOUND;
if (addr->sa_family == AF_INET6)
tcp->flags |= UV_HANDLE_IPV6;
return 0;
}
@@ -270,13 +275,35 @@
err = maybe_new_socket(tcp, AF_INET, UV_STREAM_READABLE);
if (err)
return err;
+#ifdef __MVS__
+ /* on zOS the listen call does not bind automatically
+ if the socket is unbound. Hence the manual binding to
+ an arbitrary port is required to be done manually
+ */
+
+ if (!(tcp->flags & UV_HANDLE_BOUND)) {
+ struct sockaddr_storage saddr;
+ socklen_t slen = sizeof(saddr);
+ memset(&saddr, 0, sizeof(saddr));
+
+ if (getsockname(tcp->io_watcher.fd, (struct sockaddr*) &saddr, &slen))
+ return -errno;
+
+ if (bind(tcp->io_watcher.fd, (struct sockaddr*) &saddr, slen))
+ return -errno;
+
+ tcp->flags |= UV_HANDLE_BOUND;
+ }
+#endif
+
if (listen(tcp->io_watcher.fd, backlog))
return -errno;
tcp->connection_cb = cb;
+ tcp->flags |= UV_HANDLE_BOUND;
/* Start listening for connections. */
tcp->io_watcher.cb = uv__server_io;
uv__io_start(tcp->loop, &tcp->io_watcher, POLLIN);