1e66f31c5Sopenharmony_ci/* Copyright Joyent, Inc. and other Node contributors. All rights reserved. 2e66f31c5Sopenharmony_ci * 3e66f31c5Sopenharmony_ci * Permission is hereby granted, free of charge, to any person obtaining a copy 4e66f31c5Sopenharmony_ci * of this software and associated documentation files (the "Software"), to 5e66f31c5Sopenharmony_ci * deal in the Software without restriction, including without limitation the 6e66f31c5Sopenharmony_ci * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or 7e66f31c5Sopenharmony_ci * sell copies of the Software, and to permit persons to whom the Software is 8e66f31c5Sopenharmony_ci * furnished to do so, subject to the following conditions: 9e66f31c5Sopenharmony_ci * 10e66f31c5Sopenharmony_ci * The above copyright notice and this permission notice shall be included in 11e66f31c5Sopenharmony_ci * all copies or substantial portions of the Software. 12e66f31c5Sopenharmony_ci * 13e66f31c5Sopenharmony_ci * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 14e66f31c5Sopenharmony_ci * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 15e66f31c5Sopenharmony_ci * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 16e66f31c5Sopenharmony_ci * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 17e66f31c5Sopenharmony_ci * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 18e66f31c5Sopenharmony_ci * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS 19e66f31c5Sopenharmony_ci * IN THE SOFTWARE. 20e66f31c5Sopenharmony_ci */ 21e66f31c5Sopenharmony_ci 22e66f31c5Sopenharmony_ci#include "uv.h" 23e66f31c5Sopenharmony_ci#include "task.h" 24e66f31c5Sopenharmony_ci 25e66f31c5Sopenharmony_ci 26e66f31c5Sopenharmony_ci#ifndef _WIN32 27e66f31c5Sopenharmony_ci 28e66f31c5Sopenharmony_ci#include <fcntl.h> 29e66f31c5Sopenharmony_ci#include <errno.h> 30e66f31c5Sopenharmony_ci#include <stdio.h> 31e66f31c5Sopenharmony_ci#include <stdlib.h> 32e66f31c5Sopenharmony_ci#include <string.h> 33e66f31c5Sopenharmony_ci#include <sys/socket.h> 34e66f31c5Sopenharmony_ci#include <unistd.h> 35e66f31c5Sopenharmony_ci 36e66f31c5Sopenharmony_ci 37e66f31c5Sopenharmony_ci/* NOTE: size should be divisible by 2 */ 38e66f31c5Sopenharmony_cistatic uv_pipe_t incoming[4]; 39e66f31c5Sopenharmony_cistatic unsigned int incoming_count; 40e66f31c5Sopenharmony_cistatic unsigned int close_called; 41e66f31c5Sopenharmony_ci 42e66f31c5Sopenharmony_ci 43e66f31c5Sopenharmony_cistatic void set_nonblocking(uv_os_sock_t sock) { 44e66f31c5Sopenharmony_ci int r; 45e66f31c5Sopenharmony_ci#ifdef _WIN32 46e66f31c5Sopenharmony_ci unsigned long on = 1; 47e66f31c5Sopenharmony_ci r = ioctlsocket(sock, FIONBIO, &on); 48e66f31c5Sopenharmony_ci ASSERT_OK(r); 49e66f31c5Sopenharmony_ci#else 50e66f31c5Sopenharmony_ci int flags = fcntl(sock, F_GETFL, 0); 51e66f31c5Sopenharmony_ci ASSERT_GE(flags, 0); 52e66f31c5Sopenharmony_ci r = fcntl(sock, F_SETFL, flags | O_NONBLOCK); 53e66f31c5Sopenharmony_ci ASSERT_GE(r, 0); 54e66f31c5Sopenharmony_ci#endif 55e66f31c5Sopenharmony_ci} 56e66f31c5Sopenharmony_ci 57e66f31c5Sopenharmony_ci 58e66f31c5Sopenharmony_ci 59e66f31c5Sopenharmony_ci 60e66f31c5Sopenharmony_cistatic void close_cb(uv_handle_t* handle) { 61e66f31c5Sopenharmony_ci close_called++; 62e66f31c5Sopenharmony_ci} 63e66f31c5Sopenharmony_ci 64e66f31c5Sopenharmony_ci 65e66f31c5Sopenharmony_cistatic void alloc_cb(uv_handle_t* handle, size_t size, uv_buf_t* buf) { 66e66f31c5Sopenharmony_ci static char base[1]; 67e66f31c5Sopenharmony_ci 68e66f31c5Sopenharmony_ci buf->base = base; 69e66f31c5Sopenharmony_ci buf->len = sizeof(base); 70e66f31c5Sopenharmony_ci} 71e66f31c5Sopenharmony_ci 72e66f31c5Sopenharmony_ci 73e66f31c5Sopenharmony_cistatic void read_cb(uv_stream_t* handle, 74e66f31c5Sopenharmony_ci ssize_t nread, 75e66f31c5Sopenharmony_ci const uv_buf_t* buf) { 76e66f31c5Sopenharmony_ci uv_pipe_t* p; 77e66f31c5Sopenharmony_ci uv_pipe_t* inc; 78e66f31c5Sopenharmony_ci uv_handle_type pending; 79e66f31c5Sopenharmony_ci unsigned int i; 80e66f31c5Sopenharmony_ci 81e66f31c5Sopenharmony_ci p = (uv_pipe_t*) handle; 82e66f31c5Sopenharmony_ci ASSERT_GE(nread, 0); 83e66f31c5Sopenharmony_ci 84e66f31c5Sopenharmony_ci while (uv_pipe_pending_count(p) != 0) { 85e66f31c5Sopenharmony_ci pending = uv_pipe_pending_type(p); 86e66f31c5Sopenharmony_ci ASSERT_EQ(pending, UV_NAMED_PIPE); 87e66f31c5Sopenharmony_ci 88e66f31c5Sopenharmony_ci ASSERT_LT(incoming_count, ARRAY_SIZE(incoming)); 89e66f31c5Sopenharmony_ci inc = &incoming[incoming_count++]; 90e66f31c5Sopenharmony_ci ASSERT_OK(uv_pipe_init(p->loop, inc, 0)); 91e66f31c5Sopenharmony_ci ASSERT_OK(uv_accept(handle, (uv_stream_t*) inc)); 92e66f31c5Sopenharmony_ci } 93e66f31c5Sopenharmony_ci 94e66f31c5Sopenharmony_ci if (incoming_count != ARRAY_SIZE(incoming)) 95e66f31c5Sopenharmony_ci return; 96e66f31c5Sopenharmony_ci 97e66f31c5Sopenharmony_ci ASSERT_OK(uv_read_stop((uv_stream_t*) p)); 98e66f31c5Sopenharmony_ci uv_close((uv_handle_t*) p, close_cb); 99e66f31c5Sopenharmony_ci for (i = 0; i < ARRAY_SIZE(incoming); i++) 100e66f31c5Sopenharmony_ci uv_close((uv_handle_t*) &incoming[i], close_cb); 101e66f31c5Sopenharmony_ci} 102e66f31c5Sopenharmony_ci 103e66f31c5Sopenharmony_ci 104e66f31c5Sopenharmony_ciTEST_IMPL(pipe_sendmsg) { 105e66f31c5Sopenharmony_ci#if defined(NO_SEND_HANDLE_ON_PIPE) 106e66f31c5Sopenharmony_ci RETURN_SKIP(NO_SEND_HANDLE_ON_PIPE); 107e66f31c5Sopenharmony_ci#endif 108e66f31c5Sopenharmony_ci uv_pipe_t p; 109e66f31c5Sopenharmony_ci int r; 110e66f31c5Sopenharmony_ci int fds[2]; 111e66f31c5Sopenharmony_ci int send_fds[ARRAY_SIZE(incoming)]; 112e66f31c5Sopenharmony_ci struct msghdr msg; 113e66f31c5Sopenharmony_ci char scratch[64]; 114e66f31c5Sopenharmony_ci struct cmsghdr *cmsg; 115e66f31c5Sopenharmony_ci unsigned int i; 116e66f31c5Sopenharmony_ci uv_buf_t buf; 117e66f31c5Sopenharmony_ci 118e66f31c5Sopenharmony_ci ASSERT_OK(socketpair(AF_UNIX, SOCK_STREAM, 0, fds)); 119e66f31c5Sopenharmony_ci for (i = 0; i < ARRAY_SIZE(send_fds); i += 2) 120e66f31c5Sopenharmony_ci ASSERT_OK(socketpair(AF_UNIX, SOCK_STREAM, 0, send_fds + i)); 121e66f31c5Sopenharmony_ci ASSERT_EQ(i, ARRAY_SIZE(send_fds)); 122e66f31c5Sopenharmony_ci ASSERT_OK(uv_pipe_init(uv_default_loop(), &p, 1)); 123e66f31c5Sopenharmony_ci ASSERT_OK(uv_pipe_open(&p, fds[1])); 124e66f31c5Sopenharmony_ci 125e66f31c5Sopenharmony_ci buf = uv_buf_init("X", 1); 126e66f31c5Sopenharmony_ci memset(&msg, 0, sizeof(msg)); 127e66f31c5Sopenharmony_ci msg.msg_iov = (struct iovec*) &buf; 128e66f31c5Sopenharmony_ci msg.msg_iovlen = 1; 129e66f31c5Sopenharmony_ci msg.msg_flags = 0; 130e66f31c5Sopenharmony_ci 131e66f31c5Sopenharmony_ci msg.msg_control = (void*) scratch; 132e66f31c5Sopenharmony_ci msg.msg_controllen = CMSG_LEN(sizeof(send_fds)); 133e66f31c5Sopenharmony_ci ASSERT_GE(sizeof(scratch), msg.msg_controllen); 134e66f31c5Sopenharmony_ci 135e66f31c5Sopenharmony_ci cmsg = CMSG_FIRSTHDR(&msg); 136e66f31c5Sopenharmony_ci cmsg->cmsg_level = SOL_SOCKET; 137e66f31c5Sopenharmony_ci cmsg->cmsg_type = SCM_RIGHTS; 138e66f31c5Sopenharmony_ci cmsg->cmsg_len = msg.msg_controllen; 139e66f31c5Sopenharmony_ci 140e66f31c5Sopenharmony_ci /* silence aliasing warning */ 141e66f31c5Sopenharmony_ci { 142e66f31c5Sopenharmony_ci void* pv = CMSG_DATA(cmsg); 143e66f31c5Sopenharmony_ci int* pi = pv; 144e66f31c5Sopenharmony_ci for (i = 0; i < ARRAY_SIZE(send_fds); i++) 145e66f31c5Sopenharmony_ci pi[i] = send_fds[i]; 146e66f31c5Sopenharmony_ci } 147e66f31c5Sopenharmony_ci 148e66f31c5Sopenharmony_ci set_nonblocking(fds[1]); 149e66f31c5Sopenharmony_ci ASSERT_OK(uv_read_start((uv_stream_t*) &p, alloc_cb, read_cb)); 150e66f31c5Sopenharmony_ci 151e66f31c5Sopenharmony_ci do 152e66f31c5Sopenharmony_ci r = sendmsg(fds[0], &msg, 0); 153e66f31c5Sopenharmony_ci while (r == -1 && errno == EINTR); 154e66f31c5Sopenharmony_ci ASSERT_EQ(1, r); 155e66f31c5Sopenharmony_ci 156e66f31c5Sopenharmony_ci uv_run(uv_default_loop(), UV_RUN_DEFAULT); 157e66f31c5Sopenharmony_ci ASSERT_EQ(ARRAY_SIZE(incoming), incoming_count); 158e66f31c5Sopenharmony_ci ASSERT_EQ(ARRAY_SIZE(incoming) + 1, close_called); 159e66f31c5Sopenharmony_ci close(fds[0]); 160e66f31c5Sopenharmony_ci 161e66f31c5Sopenharmony_ci MAKE_VALGRIND_HAPPY(uv_default_loop()); 162e66f31c5Sopenharmony_ci return 0; 163e66f31c5Sopenharmony_ci} 164e66f31c5Sopenharmony_ci 165e66f31c5Sopenharmony_ci#else /* !_WIN32 */ 166e66f31c5Sopenharmony_ci 167e66f31c5Sopenharmony_ciTEST_IMPL(pipe_sendmsg) { 168e66f31c5Sopenharmony_ci MAKE_VALGRIND_HAPPY(uv_default_loop()); 169e66f31c5Sopenharmony_ci return 0; 170e66f31c5Sopenharmony_ci} 171e66f31c5Sopenharmony_ci 172e66f31c5Sopenharmony_ci#endif /* _WIN32 */ 173