unix: make uv_guess_handle work properly for AIX
On AIX, the getsockname API does not operate on the UNIX domain sockets Please see: https://www-01.ibm.com/support/knowledgecenter/ssw_aix_61/ com.ibm.aix.commtrf2/getsockname.htm This means that the internal helper routine uv_guess_handle in tty.c fails in AIX, for common use cases. There is no direct API support which helps identifying a UNIX domain socket in AIX. getpeername() retrieves the information pertinent to connected UNIX domain socket pairs, and using getpeername where getsockname fails was a good workaround. However, there are edge cases where one end of a socketpair comes for introspection while the other end has been closed, which causes getpeername to fail. A better solution is derived based on these facts: 1.getsockname() on a broken / un-broken socketpair does not actually fail with -1, instead it returns 0. However, the API does not modify the socketaddr structure passed to it, with the socket information. 2.This behavior of getsockname is observed only for UNIX domain socket, among all possible types of sockets which I tested - ~30 of them. So a practical and stable workaround for AIX is to return UV_UNKNOWN_HANDLE if getsockname fails. If it passes and the length of the structure returned is 0 then we know that the type is AF_UNIX and return UV_NAMED_PIPE , otherwise we inspect in the same way as for other platforms to derive the type. PR-URL: https://github.com/libuv/libuv/pull/539 Reviewed-By: Ben Noordhuis <info@bnoordhuis.nl> Reviewed-By: Michael Dawson <michael_dawson@ca.ibm.com> Reviewed-By: Saúl Ibarra Corretgé <saghul@gmail.com>
This commit is contained in:
parent
25c369d4cf
commit
25506bb331
@ -236,6 +236,15 @@ uv_handle_type uv_guess_handle(uv_file file) {
|
||||
return UV_UDP;
|
||||
|
||||
if (type == SOCK_STREAM) {
|
||||
#if defined(_AIX)
|
||||
/* on AIX the getsockname call returns an empty sa structure
|
||||
* for sockets of type AF_UNIX. For all other types it will
|
||||
* return a properly filled in structure.
|
||||
*/
|
||||
if (len == 0)
|
||||
return UV_NAMED_PIPE;
|
||||
#endif /* defined(_AIX) */
|
||||
|
||||
if (sa.sa_family == AF_INET || sa.sa_family == AF_INET6)
|
||||
return UV_TCP;
|
||||
if (sa.sa_family == AF_UNIX)
|
||||
|
||||
Loading…
Reference in New Issue
Block a user