test-pipe-sendmsg.c
Go to the documentation of this file.
1 /* Copyright Joyent, Inc. and other Node contributors. All rights reserved.
2  *
3  * Permission is hereby granted, free of charge, to any person obtaining a copy
4  * of this software and associated documentation files (the "Software"), to
5  * deal in the Software without restriction, including without limitation the
6  * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
7  * sell copies of the Software, and to permit persons to whom the Software is
8  * furnished to do so, subject to the following conditions:
9  *
10  * The above copyright notice and this permission notice shall be included in
11  * all copies or substantial portions of the Software.
12  *
13  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
14  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
15  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
16  * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
17  * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
18  * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
19  * IN THE SOFTWARE.
20  */
21 
22 #include "uv.h"
23 #include "task.h"
24 
25 
26 #ifndef _WIN32
27 
28 #include <fcntl.h>
29 #include <errno.h>
30 #include <stdio.h>
31 #include <stdlib.h>
32 #include <string.h>
33 #include <sys/socket.h>
34 #include <unistd.h>
35 
36 
37 /* NOTE: size should be divisible by 2 */
38 static uv_pipe_t incoming[4];
39 static unsigned int incoming_count;
40 static unsigned int close_called;
41 
42 
43 static void set_nonblocking(uv_os_sock_t sock) {
44  int r;
45 #ifdef _WIN32
46  unsigned long on = 1;
47  r = ioctlsocket(sock, FIONBIO, &on);
48  ASSERT(r == 0);
49 #else
50  int flags = fcntl(sock, F_GETFL, 0);
51  ASSERT(flags >= 0);
52  r = fcntl(sock, F_SETFL, flags | O_NONBLOCK);
53  ASSERT(r >= 0);
54 #endif
55 }
56 
57 
58 
59 
60 static void close_cb(uv_handle_t* handle) {
61  close_called++;
62 }
63 
64 
65 static void alloc_cb(uv_handle_t* handle, size_t size, uv_buf_t* buf) {
66  static char base[1];
67 
68  buf->base = base;
69  buf->len = sizeof(base);
70 }
71 
72 
73 static void read_cb(uv_stream_t* handle,
74  ssize_t nread,
75  const uv_buf_t* buf) {
76  uv_pipe_t* p;
77  uv_pipe_t* inc;
79  unsigned int i;
80 
81  p = (uv_pipe_t*) handle;
82  ASSERT(nread >= 0);
83 
84  while (uv_pipe_pending_count(p) != 0) {
86  ASSERT(pending == UV_NAMED_PIPE);
87 
90  ASSERT(0 == uv_pipe_init(p->loop, inc, 0));
92  }
93 
95  return;
96 
97  ASSERT(0 == uv_read_stop((uv_stream_t*) p));
99  for (i = 0; i < ARRAY_SIZE(incoming); i++)
101 }
102 
103 
104 TEST_IMPL(pipe_sendmsg) {
105 #if defined(NO_SEND_HANDLE_ON_PIPE)
106  RETURN_SKIP(NO_SEND_HANDLE_ON_PIPE);
107 #endif
108  uv_pipe_t p;
109  int r;
110  int fds[2];
111  int send_fds[ARRAY_SIZE(incoming)];
112  struct msghdr msg;
113  char scratch[64];
114  struct cmsghdr *cmsg;
115  unsigned int i;
116  uv_buf_t buf;
117 
118  ASSERT(0 == socketpair(AF_UNIX, SOCK_STREAM, 0, fds));
119  for (i = 0; i < ARRAY_SIZE(send_fds); i += 2)
120  ASSERT(0 == socketpair(AF_UNIX, SOCK_STREAM, 0, send_fds + i));
121  ASSERT(i == ARRAY_SIZE(send_fds));
122  ASSERT(0 == uv_pipe_init(uv_default_loop(), &p, 1));
123  ASSERT(0 == uv_pipe_open(&p, fds[1]));
124 
125  buf = uv_buf_init("X", 1);
126  memset(&msg, 0, sizeof(msg));
127  msg.msg_iov = (struct iovec*) &buf;
128  msg.msg_iovlen = 1;
129  msg.msg_flags = 0;
130 
131  msg.msg_control = (void*) scratch;
132  msg.msg_controllen = CMSG_LEN(sizeof(send_fds));
133  ASSERT(sizeof(scratch) >= msg.msg_controllen);
134 
135  cmsg = CMSG_FIRSTHDR(&msg);
136  cmsg->cmsg_level = SOL_SOCKET;
137  cmsg->cmsg_type = SCM_RIGHTS;
138  cmsg->cmsg_len = msg.msg_controllen;
139 
140  /* silence aliasing warning */
141  {
142  void* pv = CMSG_DATA(cmsg);
143  int* pi = pv;
144  for (i = 0; i < ARRAY_SIZE(send_fds); i++)
145  pi[i] = send_fds[i];
146  }
147 
148  set_nonblocking(fds[1]);
150 
151  do
152  r = sendmsg(fds[0], &msg, 0);
153  while (r == -1 && errno == EINTR);
154  ASSERT(r == 1);
155 
159  close(fds[0]);
160 
162  return 0;
163 }
164 
165 #else /* !_WIN32 */
166 
167 TEST_IMPL(pipe_sendmsg) {
169  return 0;
170 }
171 
172 #endif /* _WIN32 */
alloc_cb
static void alloc_cb(uv_handle_t *handle, size_t size, uv_buf_t *buf)
Definition: test-pipe-sendmsg.c:65
uv_pipe_pending_count
UV_EXTERN int uv_pipe_pending_count(uv_pipe_t *handle)
Definition: unix/pipe.c:298
incoming
static uv_pipe_t incoming[4]
Definition: test-pipe-sendmsg.c:38
ARRAY_SIZE
#define ARRAY_SIZE(array)
Definition: bloaty.cc:101
task.h
memset
return memset(p, 0, total)
inc
static void inc(void *v)
Definition: spinlock_test.cc:125
uv_pipe_init
UV_EXTERN int uv_pipe_init(uv_loop_t *, uv_pipe_t *handle, int ipc)
Definition: unix/pipe.c:33
uv_handle_type
uv_handle_type
Definition: uv.h:189
close_cb
static void close_cb(uv_handle_t *handle)
Definition: test-pipe-sendmsg.c:60
set_nonblocking
static void set_nonblocking(uv_os_sock_t sock)
Definition: test-pipe-sendmsg.c:43
string.h
buf
voidpf void * buf
Definition: bloaty/third_party/zlib/contrib/minizip/ioapi.h:136
TEST_IMPL
TEST_IMPL(pipe_sendmsg)
Definition: test-pipe-sendmsg.c:104
ASSERT
#define ASSERT(expr)
Definition: task.h:102
read_cb
static void read_cb(uv_stream_t *handle, ssize_t nread, const uv_buf_t *buf)
Definition: test-pipe-sendmsg.c:73
xds_manager.p
p
Definition: xds_manager.py:60
uv_run
UV_EXTERN int uv_run(uv_loop_t *, uv_run_mode mode)
Definition: unix/core.c:361
grpc_core::pending
P< T > pending()
Definition: try_join_test.cc:50
uv_close
UV_EXTERN void uv_close(uv_handle_t *handle, uv_close_cb close_cb)
Definition: unix/core.c:112
uv_stream_s
Definition: uv.h:491
uv_os_sock_t
int uv_os_sock_t
Definition: unix.h:127
uv_default_loop
UV_EXTERN uv_loop_t * uv_default_loop(void)
Definition: uv-common.c:733
ssize_t
intptr_t ssize_t
Definition: win.h:27
close_called
static unsigned int close_called
Definition: test-pipe-sendmsg.c:40
UV_RUN_DEFAULT
@ UV_RUN_DEFAULT
Definition: uv.h:254
uv_read_start
UV_EXTERN int uv_read_start(uv_stream_t *, uv_alloc_cb alloc_cb, uv_read_cb read_cb)
Definition: unix/stream.c:1555
close
#define close
Definition: test-fs.c:48
gen_synthetic_protos.base
base
Definition: gen_synthetic_protos.py:31
uv_accept
UV_EXTERN int uv_accept(uv_stream_t *server, uv_stream_t *client)
Definition: unix/stream.c:591
msg
std::string msg
Definition: client_interceptors_end2end_test.cc:372
uv.h
MAKE_VALGRIND_HAPPY
#define MAKE_VALGRIND_HAPPY()
Definition: task.h:229
uv_buf_t
Definition: unix.h:121
iovec
Definition: gsec.h:33
scratch
static char scratch[256]
Definition: test-random.c:27
absl::flags_internal
Definition: abseil-cpp/absl/flags/commandlineflag.h:40
uv_pipe_pending_type
UV_EXTERN uv_handle_type uv_pipe_pending_type(uv_pipe_t *handle)
Definition: unix/pipe.c:315
fix_build_deps.r
r
Definition: fix_build_deps.py:491
uv_pipe_s
Definition: uv.h:757
uv_buf_init
UV_EXTERN uv_buf_t uv_buf_init(char *base, unsigned int len)
Definition: uv-common.c:157
RETURN_SKIP
#define RETURN_SKIP(explanation)
Definition: task.h:262
handle
static csh handle
Definition: test_arm_regression.c:16
uv_handle_s
Definition: uv.h:441
size
voidpf void uLong size
Definition: bloaty/third_party/zlib/contrib/minizip/ioapi.h:136
uv_read_stop
UV_EXTERN int uv_read_stop(uv_stream_t *)
Definition: unix/stream.c:1590
uv_pipe_open
UV_EXTERN int uv_pipe_open(uv_pipe_t *, uv_file file)
Definition: unix/pipe.c:137
errno.h
i
uint64_t i
Definition: abseil-cpp/absl/container/btree_benchmark.cc:230
incoming_count
static unsigned int incoming_count
Definition: test-pipe-sendmsg.c:39


grpc
Author(s):
autogenerated on Thu Mar 13 2025 03:01:30