Chromium Code Reviews| Index: native_client_sdk/src/libraries/nacl_io/kernel_proxy.cc |
| diff --git a/native_client_sdk/src/libraries/nacl_io/kernel_proxy.cc b/native_client_sdk/src/libraries/nacl_io/kernel_proxy.cc |
| index b554ade35226994cee50d28578dfc2fba3e156db..a1f74129424d180f1f912f0339026da0f00bf406 100644 |
| --- a/native_client_sdk/src/libraries/nacl_io/kernel_proxy.cc |
| +++ b/native_client_sdk/src/libraries/nacl_io/kernel_proxy.cc |
| @@ -39,6 +39,7 @@ |
| #include "nacl_io/pipe/pipe_node.h" |
| #include "nacl_io/socket/tcp_node.h" |
| #include "nacl_io/socket/udp_node.h" |
| +#include "nacl_io/socket/unix_socketpair_node.h" |
| #include "nacl_io/stream/stream_fs.h" |
| #include "nacl_io/typed_fs_factory.h" |
| #include "sdk_util/auto_lock.h" |
| @@ -1813,15 +1814,68 @@ int KernelProxy::socketpair(int domain, int type, int protocol, int* sv) { |
| return -1; |
| } |
| - // Catch-22: We don't support AF_UNIX, but any other AF doesn't support |
| - // socket pairs. Thus, this function always fails. |
| - if (AF_UNIX != domain) { |
| - errno = EPROTONOSUPPORT; |
| + if (AF_INET == domain || AF_INET6 == domain) { |
| + errno = EOPNOTSUPP; |
| return -1; |
| } |
| - if (AF_INET != domain && AF_INET6 != domain) { |
| - errno = EAFNOSUPPORT; |
| + // Catch-22: We don't support AF_UNIX, but any other AF doesn't support |
| + // socket pairs. Thus, this function always fails. |
| + if (AF_UNIX == domain) { |
| + int open_flags = O_RDWR; |
| + |
| +#if defined(SOCK_CLOEXEC) |
| + if (type & SOCK_CLOEXEC) { |
| +#if defined(O_CLOEXEC) |
| + // The NaCl newlib version of fcntl.h doesn't currently define |
| + // O_CLOEXEC. |
| + // TODO(sbc): remove this guard once it gets added. |
| + open_flags |= O_CLOEXEC; |
| +#endif |
| + type &= ~SOCK_CLOEXEC; |
| + } |
| +#endif |
| + |
| +#if defined(SOCK_NONBLOCK) |
| + if (type & SOCK_NONBLOCK) { |
| + open_flags |= O_NONBLOCK; |
| + type &= ~SOCK_NONBLOCK; |
| + } |
| +#endif |
| + |
| + UnixSocketpairNode* socket = new UnixSocketpairNode(stream_fs_.get()); |
| + Error rtn = socket->Init(O_RDWR); |
| + if (rtn != 0) { |
| + errno = rtn; |
| + return -1; |
| + } |
| + ScopedNode node0(socket); |
| + socket = new UnixSocketpairNode(stream_fs_.get(), *socket); |
| + rtn = socket->Init(O_RDWR); |
| + if (rtn != 0) { |
| + errno = rtn; |
| + return -1; |
| + } |
| + ScopedNode node1(socket); |
| + ScopedKernelHandle handle0(new KernelHandle(stream_fs_, node0)); |
| + rtn = handle0->Init(open_flags); |
| + if (rtn != 0) { |
| + errno = rtn; |
| + return -1; |
| + } |
| + ScopedKernelHandle handle1(new KernelHandle(stream_fs_, node1)); |
| + rtn = handle1->Init(open_flags); |
| + if (rtn != 0) { |
| + errno = rtn; |
| + return -1; |
| + } |
| + |
| + sv[0] = AllocateFD(handle0); |
| + sv[1] = AllocateFD(handle1); |
| + |
| + return 0; |
| + } else { |
| + errno = EPROTONOSUPPORT; |
| return -1; |
|
Sam Clegg
2015/09/17 09:40:39
Can you use early return if domain != AF_UNIX then
avallee
2015/09/17 19:00:31
Done.
|
| } |