diff --git a/src/signaler.cpp b/src/signaler.cpp index f199d08c..8a5d38e0 100644 --- a/src/signaler.cpp +++ b/src/signaler.cpp @@ -286,7 +286,7 @@ int zmq::signaler_t::make_fdpair (fd_t *r_, fd_t *w_) (char *)&tcp_nodelay, sizeof (tcp_nodelay)); wsa_assert (rc != SOCKET_ERROR); - // Bind listening socket to any free local port. + // Bind listening socket to signaler port. struct sockaddr_in addr; memset (&addr, 0, sizeof (addr)); addr.sin_family = AF_INET; @@ -314,15 +314,19 @@ int zmq::signaler_t::make_fdpair (fd_t *r_, fd_t *w_) // Connect writer to the listener. rc = connect (*w_, (struct sockaddr*) &addr, sizeof (addr)); - wsa_assert (rc != SOCKET_ERROR); - // Accept connection from writer. - *r_ = accept (listener, NULL, NULL); - wsa_assert (*r_ != INVALID_SOCKET); + // Save errno if connection fails + int conn_errno = 0; + if (rc == SOCKET_ERROR) { + conn_errno = WSAGetLastError (); + } else { + // Accept connection from writer. + *r_ = accept (listener, NULL, NULL); - // On Windows, preventing sockets to be inherited by child processes. - brc = SetHandleInformation ((HANDLE) *r_, HANDLE_FLAG_INHERIT, 0); - win_assert (brc); + if (*r_ == INVALID_SOCKET) { + conn_errno = WSAGetLastError (); + } + } // We don't need the listening socket anymore. Close it. rc = closesocket (listener); @@ -332,11 +336,33 @@ int zmq::signaler_t::make_fdpair (fd_t *r_, fd_t *w_) brc = SetEvent (sync); win_assert (brc != 0); - // Release the kernel object + // Release the kernel object brc = CloseHandle (sync); win_assert (brc != 0); - return 0; + if (*r_ != INVALID_SOCKET) { + // On Windows, preventing sockets to be inherited by child processes. + brc = SetHandleInformation ((HANDLE) *r_, HANDLE_FLAG_INHERIT, 0); + win_assert (brc); + + return 0; + } else { + // Cleanup writer if connection failed + rc = closesocket (*w_); + wsa_assert (rc != SOCKET_ERROR); + + *w_ = INVALID_SOCKET; + + // Set errno from saved value + errno = wsa_error_to_errno (conn_errno); + + // Ideally, we would return errno to the caller signaler_t() + // Unfortunately, it uses errno_assert() which gives "Unknown error" + // We might as well assert here and print the actual error message + wsa_assert_no (conn_errno); + + return -1; + } #elif defined ZMQ_HAVE_OPENVMS