test-stdio-over-pipes.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 #include <stdlib.h>
26 #include <string.h>
27 
28 
29 static char exepath[1024];
30 static size_t exepath_size = 1024;
31 static char* args[3];
33 static int close_cb_called;
34 static int exit_cb_called;
35 static int on_read_cb_called;
37 static uv_pipe_t in;
38 static uv_pipe_t out;
39 static uv_loop_t* loop;
40 #define OUTPUT_SIZE 1024
41 static char output[OUTPUT_SIZE];
42 static int output_used;
43 
44 
45 static void close_cb(uv_handle_t* handle) {
47 }
48 
49 
51  int64_t exit_status,
52  int term_signal) {
53  printf("exit_cb\n");
55  ASSERT(exit_status == 0);
56  ASSERT(term_signal == 0);
60 }
61 
62 
65  ASSERT(r == 0);
66  exepath[exepath_size] = '\0';
67  args[0] = exepath;
68  args[1] = test;
69  args[2] = NULL;
71  options.args = args;
73 }
74 
75 
77  size_t suggested_size,
78  uv_buf_t* buf) {
79  buf->base = output + output_used;
80  buf->len = OUTPUT_SIZE - output_used;
81 }
82 
83 
84 static void after_write(uv_write_t* req, int status) {
85  if (status) {
86  fprintf(stderr, "uv_write error: %s\n", uv_strerror(status));
87  ASSERT(0);
88  }
89 
90  /* Free the read/write buffer and the request */
91  free(req);
92 
94 }
95 
96 
97 static void on_read(uv_stream_t* pipe, ssize_t nread, const uv_buf_t* rdbuf) {
98  uv_write_t* req;
99  uv_buf_t wrbuf;
100  int r;
101 
102  ASSERT(nread > 0 || nread == UV_EOF);
103 
104  if (nread > 0) {
105  output_used += nread;
106  if (output_used % 12 == 0) {
107  ASSERT(memcmp("hello world\n", output, 12) == 0);
108  wrbuf = uv_buf_init(output, 12);
109  req = malloc(sizeof(*req));
110  r = uv_write(req, (uv_stream_t*) &in, &wrbuf, 1, after_write);
111  ASSERT(r == 0);
112  }
113  }
114 
116 }
117 
118 
119 static void test_stdio_over_pipes(int overlapped) {
120  int r;
122  uv_stdio_container_t stdio[3];
123 
124  loop = uv_default_loop();
125 
126  init_process_options("stdio_over_pipes_helper", exit_cb);
127 
128  uv_pipe_init(loop, &out, 0);
129  uv_pipe_init(loop, &in, 0);
130 
131  options.stdio = stdio;
133  (overlapped ? UV_OVERLAPPED_PIPE : 0);
136  (overlapped ? UV_OVERLAPPED_PIPE : 0);
139  options.stdio[2].data.fd = 2;
140  options.stdio_count = 3;
141 
142  r = uv_spawn(loop, &process, &options);
143  ASSERT(r == 0);
144 
146  ASSERT(r == 0);
147 
149  ASSERT(r == 0);
150 
153  ASSERT(exit_cb_called == 1);
154  ASSERT(close_cb_called == 3);
155  ASSERT(memcmp("hello world\nhello world\n", output, 24) == 0);
156  ASSERT(output_used == 24);
157 
159 }
160 
161 TEST_IMPL(stdio_over_pipes) {
163  return 0;
164 }
165 
166 TEST_IMPL(stdio_emulate_iocp) {
168  return 0;
169 }
170 
171 
172 /* Everything here runs in a child process. */
173 
180 
181 static void on_pipe_read(uv_stream_t* pipe, ssize_t nread, const uv_buf_t* buf) {
182  ASSERT(nread > 0);
183  ASSERT(memcmp("hello world\n", buf->base, nread) == 0);
185 
186  free(buf->base);
187 
188  uv_read_stop(pipe);
189 }
190 
191 
192 static void after_pipe_write(uv_write_t* req, int status) {
193  ASSERT(status == 0);
195 }
196 
197 
199  size_t suggested_size,
200  uv_buf_t* buf) {
201  buf->base = malloc(suggested_size);
202  buf->len = suggested_size;
203 }
204 
205 
207  /* Write several buffers to test that the write order is preserved. */
208  char* buffers[] = {
209  "he",
210  "ll",
211  "o ",
212  "wo",
213  "rl",
214  "d",
215  "\n"
216  };
217 
218  uv_write_t write_req[ARRAY_SIZE(buffers)];
219  uv_buf_t buf[ARRAY_SIZE(buffers)];
220  unsigned int i;
221  int j;
222  int r;
224 
225  ASSERT(UV_NAMED_PIPE == uv_guess_handle(0));
226  ASSERT(UV_NAMED_PIPE == uv_guess_handle(1));
227 
228  r = uv_pipe_init(loop, &stdin_pipe1, 0);
229  ASSERT(r == 0);
231  ASSERT(r == 0);
232  r = uv_pipe_init(loop, &stdin_pipe2, 0);
233  ASSERT(r == 0);
235  ASSERT(r == 0);
236 
241 
242  for (j = 0; j < 2; j++) {
243  /* Unref both stdio handles to make sure that all writes complete. */
248 
249  for (i = 0; i < ARRAY_SIZE(buffers); i++) {
250  buf[i] = uv_buf_init((char*) buffers[i], strlen(buffers[i]));
251  }
252 
253  for (i = 0; i < ARRAY_SIZE(buffers); i++) {
254  r = uv_write(&write_req[i],
255  (uv_stream_t*) (j == 0 ? &stdout_pipe1 : &stdout_pipe2),
256  &buf[i],
257  1,
259  ASSERT(r == 0);
260  }
261 
264 
265  ASSERT(after_write_called == 7 * (j + 1));
267  ASSERT(close_cb_called == 0);
268 
273 
274  r = uv_read_start((uv_stream_t*) (j == 0 ? &stdin_pipe1 : &stdin_pipe2),
276  on_pipe_read);
277  ASSERT(r == 0);
278 
280 
281  ASSERT(after_write_called == 7 * (j + 1));
282  ASSERT(on_pipe_read_called == j + 1);
283  ASSERT(close_cb_called == 0);
284  }
285 
290 
292 
293  ASSERT(after_write_called == 14);
295  ASSERT(close_cb_called == 4);
296 
298  return 0;
299 }
stdout_pipe1
static uv_pipe_t stdout_pipe1
Definition: test-stdio-over-pipes.c:177
uv_process_options_s
Definition: uv.h:940
uv_guess_handle
UV_EXTERN uv_handle_type uv_guess_handle(uv_file file)
Definition: unix/tty.c:315
uv_process_s
Definition: uv.h:1037
ARRAY_SIZE
#define ARRAY_SIZE(array)
Definition: bloaty.cc:101
task.h
UV_READABLE_PIPE
@ UV_READABLE_PIPE
Definition: uv.h:921
uv_pipe_init
UV_EXTERN int uv_pipe_init(uv_loop_t *, uv_pipe_t *handle, int ipc)
Definition: unix/pipe.c:33
test
Definition: spinlock_test.cc:36
string.h
buf
voidpf void * buf
Definition: bloaty/third_party/zlib/contrib/minizip/ioapi.h:136
printf
_Use_decl_annotations_ int __cdecl printf(const char *_Format,...)
Definition: cs_driver.c:91
exit_cb
static void exit_cb(uv_process_t *process, int64_t exit_status, int term_signal)
Definition: test-stdio-over-pipes.c:50
uv_process_options_s::exit_cb
uv_exit_cb exit_cb
Definition: uv.h:941
UV_OVERLAPPED_PIPE
@ UV_OVERLAPPED_PIPE
Definition: uv.h:928
ASSERT
#define ASSERT(expr)
Definition: task.h:102
on_read
static void on_read(uv_stream_t *pipe, ssize_t nread, const uv_buf_t *rdbuf)
Definition: test-stdio-over-pipes.c:97
status
absl::Status status
Definition: rls.cc:251
on_alloc
static void on_alloc(uv_handle_t *handle, size_t suggested_size, uv_buf_t *buf)
Definition: test-stdio-over-pipes.c:76
uv_strerror
const UV_EXTERN char * uv_strerror(int err)
Definition: uv-common.c:212
write_req
Definition: benchmark-tcp-write-batch.c:31
stdout_pipe2
static uv_pipe_t stdout_pipe2
Definition: test-stdio-over-pipes.c:179
close_cb
static void close_cb(uv_handle_t *handle)
Definition: test-stdio-over-pipes.c:45
uv_run
UV_EXTERN int uv_run(uv_loop_t *, uv_run_mode mode)
Definition: unix/core.c:361
after_write_cb_called
static int after_write_cb_called
Definition: test-stdio-over-pipes.c:36
on_pipe_read
static void on_pipe_read(uv_stream_t *pipe, ssize_t nread, const uv_buf_t *buf)
Definition: test-stdio-over-pipes.c:181
uv_unref
UV_EXTERN void uv_unref(uv_handle_t *)
Definition: uv-common.c:522
python_utils.port_server.stderr
stderr
Definition: port_server.py:51
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_process_options_s::file
const char * file
Definition: uv.h:942
options
static uv_process_options_t options
Definition: test-stdio-over-pipes.c:32
UV_WRITABLE_PIPE
@ UV_WRITABLE_PIPE
Definition: uv.h:922
on_pipe_read_called
static int on_pipe_read_called
Definition: test-stdio-over-pipes.c:174
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
process
static uv_process_t process
Definition: benchmark-spawn.c:32
args
static char * args[3]
Definition: test-stdio-over-pipes.c:31
TEST_IMPL
TEST_IMPL(stdio_over_pipes)
Definition: test-stdio-over-pipes.c:161
uv_stdio_container_s::flags
uv_stdio_flags flags
Definition: uv.h:932
uv_process_options_s::stdio
uv_stdio_container_t * stdio
Definition: uv.h:975
output_used
static int output_used
Definition: test-stdio-over-pipes.c:42
in
static uv_pipe_t in
Definition: test-stdio-over-pipes.c:37
int64_t
signed __int64 int64_t
Definition: stdint-msvc2008.h:89
uv_process_options_s::args
char ** args
Definition: uv.h:949
uv_write
UV_EXTERN int uv_write(uv_write_t *req, uv_stream_t *handle, const uv_buf_t bufs[], unsigned int nbufs, uv_write_cb cb)
Definition: unix/stream.c:1492
req
static uv_connect_t req
Definition: test-connection-fail.c:30
UV_RUN_DEFAULT
@ UV_RUN_DEFAULT
Definition: uv.h:254
uv_process_options_s::stdio_count
int stdio_count
Definition: uv.h:974
UV_INHERIT_FD
@ UV_INHERIT_FD
Definition: uv.h:913
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_cb_called
static int close_cb_called
Definition: test-stdio-over-pipes.c:33
after_write_called
static int after_write_called
Definition: test-stdio-over-pipes.c:175
on_read_alloc
static void on_read_alloc(uv_handle_t *handle, size_t suggested_size, uv_buf_t *buf)
Definition: test-stdio-over-pipes.c:198
uv_exit_cb
void(* uv_exit_cb)(uv_process_t *, int64_t exit_status, int term_signal)
Definition: uv.h:323
stdin_pipe2
static uv_pipe_t stdin_pipe2
Definition: test-stdio-over-pipes.c:178
uv_stdio_container_s
Definition: uv.h:931
uv_stdio_container_s::fd
int fd
Definition: uv.h:936
exepath
static char exepath[1024]
Definition: test-stdio-over-pipes.c:29
uv_spawn
UV_EXTERN int uv_spawn(uv_loop_t *loop, uv_process_t *handle, const uv_process_options_t *options)
Definition: unix/process.c:408
notify_parent_process
void notify_parent_process(void)
Definition: runner-unix.c:54
uv_exepath
UV_EXTERN int uv_exepath(char *buffer, size_t *size)
Definition: aix-common.c:79
uv_stdio_container_s::stream
uv_stream_t * stream
Definition: uv.h:935
uv.h
MAKE_VALGRIND_HAPPY
#define MAKE_VALGRIND_HAPPY()
Definition: task.h:229
update_failure_list.test
test
Definition: bloaty/third_party/protobuf/conformance/update_failure_list.py:69
stdio_over_pipes_helper
int stdio_over_pipes_helper(void)
Definition: test-stdio-over-pipes.c:206
uv_buf_t
Definition: unix.h:121
uv_ref
UV_EXTERN void uv_ref(uv_handle_t *)
Definition: uv-common.c:517
test_stdio_over_pipes
static void test_stdio_over_pipes(int overlapped)
Definition: test-stdio-over-pipes.c:119
OUTPUT_SIZE
#define OUTPUT_SIZE
Definition: test-stdio-over-pipes.c:40
stdin_pipe1
static uv_pipe_t stdin_pipe1
Definition: test-stdio-over-pipes.c:176
fix_build_deps.r
r
Definition: fix_build_deps.py:491
exit_cb_called
static int exit_cb_called
Definition: test-stdio-over-pipes.c:34
on_read_cb_called
static int on_read_cb_called
Definition: test-stdio-over-pipes.c:35
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
UV_CREATE_PIPE
@ UV_CREATE_PIPE
Definition: uv.h:912
uv_write_s
Definition: uv.h:522
loop
static uv_loop_t * loop
Definition: test-stdio-over-pipes.c:39
uv_stdio_container_s::data
union uv_stdio_container_s::@399 data
handle
static csh handle
Definition: test_arm_regression.c:16
uv_handle_s
Definition: uv.h:441
init_process_options
static void init_process_options(char *test, uv_exit_cb exit_cb)
Definition: test-stdio-over-pipes.c:63
uv_loop_s
Definition: uv.h:1767
out
static uv_pipe_t out
Definition: test-stdio-over-pipes.c:38
after_pipe_write
static void after_pipe_write(uv_write_t *req, int status)
Definition: test-stdio-over-pipes.c:192
uv_read_stop
UV_EXTERN int uv_read_stop(uv_stream_t *)
Definition: unix/stream.c:1590
after_write
static void after_write(uv_write_t *req, int status)
Definition: test-stdio-over-pipes.c:84
uv_pipe_open
UV_EXTERN int uv_pipe_open(uv_pipe_t *, uv_file file)
Definition: unix/pipe.c:137
i
uint64_t i
Definition: abseil-cpp/absl/container/btree_benchmark.cc:230
output
static char output[OUTPUT_SIZE]
Definition: test-stdio-over-pipes.c:41
exepath_size
static size_t exepath_size
Definition: test-stdio-over-pipes.c:30


grpc
Author(s):
autogenerated on Fri May 16 2025 03:00:27