diff --git a/include/nng/supplemental/util/platform.h b/include/nng/supplemental/util/platform.h index f98bc176b..dc3c47ddd 100644 --- a/include/nng/supplemental/util/platform.h +++ b/include/nng/supplemental/util/platform.h @@ -109,7 +109,7 @@ NNG_DECL uint32_t nng_random(void); // by reliable, bidirectional, byte streams. This will return NNG_ENOTSUP // if the platform lacks support for this. The argument is a pointer // to an array of file descriptors (or HANDLES or similar). -NNG_DECL int nng_socket_pair(int *); +NNG_DECL int nng_socket_pair(int [2]); #ifdef __cplusplus } diff --git a/src/platform/posix/posix_socketpair.c b/src/platform/posix/posix_socketpair.c index 9674383f8..3a01ad2bb 100644 --- a/src/platform/posix/posix_socketpair.c +++ b/src/platform/posix/posix_socketpair.c @@ -18,7 +18,7 @@ #include int -nni_socket_pair(int *fds) +nni_socket_pair(int fds[2]) { int rv; rv = socketpair(PF_UNIX, SOCK_STREAM, 0, fds); diff --git a/src/platform/windows/win_socketpair.c b/src/platform/windows/win_socketpair.c index 794b3660f..0ed0443ae 100644 --- a/src/platform/windows/win_socketpair.c +++ b/src/platform/windows/win_socketpair.c @@ -30,7 +30,7 @@ nni_socket_pair(int *fds) } #else int -nni_socket_pair(int *fds) +nni_socket_pair(int fds[2]) { NNI_ARG_UNUSED(fds); return (NNG_ENOTSUP); diff --git a/src/sp/transport/socket/sockfd_test.c b/src/sp/transport/socket/sockfd_test.c index 01c9aa35d..485c67baf 100644 --- a/src/sp/transport/socket/sockfd_test.c +++ b/src/sp/transport/socket/sockfd_test.c @@ -188,8 +188,43 @@ test_sfd_large(void) nng_free(buf, sz); } -NUTS_TESTS = { +void +test_sockfd_close_pending(void) +{ + // this test verifies that closing a socket pair that has not + // started negotiation with the other side still works. + int fds[2]; + nng_socket s0; + nng_listener l; + + NUTS_PASS(nng_socket_pair(fds)); + NUTS_OPEN(s0); + nng_listen(s0, "sock://", &l, 0); + nng_listener_set_int(l, NNG_OPT_SOCKET_FD, fds[0]); + nng_msleep(10); + NUTS_CLOSE(s0); + close(fds[1]); +} + +void +test_sockfd_close_peer(void) +{ + // this test verifies that closing a socket peer + // during negotiation is ok. + int fds[2]; + nng_socket s0; + nng_listener l; + NUTS_PASS(nng_socket_pair(fds)); + NUTS_OPEN(s0); + nng_listen(s0, "sock://", &l, 0); + nng_listener_set_int(l, NNG_OPT_SOCKET_FD, fds[0]); + close(fds[1]); + nng_msleep(100); + NUTS_CLOSE(s0); +} + +NUTS_TESTS = { { "socket connect fail", test_sfd_connect_fail }, { "socket malformed address", test_sfd_malformed_address }, #ifdef NNG_HAVE_SOCKETPAIR @@ -198,6 +233,8 @@ NUTS_TESTS = { { "socket exchange", test_sfd_exchange }, { "socket recv max", test_sfd_recv_max }, { "socket exchange large", test_sfd_large }, + { "socket close pending", test_sockfd_close_pending }, + { "socket close peer", test_sockfd_close_peer }, #endif { NULL, NULL },