asyncengine 0.0.1.testing1 → 0.0.2.alpha1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- data/README.markdown +3 -0
- data/Rakefile +38 -0
- data/asyncengine.gemspec +8 -4
- data/ext/asyncengine/ae_call_from_other_thread.c +106 -0
- data/ext/asyncengine/ae_call_from_other_thread.h +12 -0
- data/ext/asyncengine/ae_handle_common.c +193 -48
- data/ext/asyncengine/ae_handle_common.h +40 -13
- data/ext/asyncengine/ae_ip_utils.c +246 -0
- data/ext/asyncengine/ae_ip_utils.h +25 -0
- data/ext/asyncengine/ae_next_tick.c +81 -21
- data/ext/asyncengine/ae_next_tick.h +4 -2
- data/ext/asyncengine/ae_resolver.c +156 -0
- data/ext/asyncengine/ae_resolver.h +10 -0
- data/ext/asyncengine/ae_tcp.c +908 -0
- data/ext/asyncengine/ae_tcp.h +20 -0
- data/ext/asyncengine/ae_timer.c +355 -81
- data/ext/asyncengine/ae_timer.h +11 -4
- data/ext/asyncengine/ae_udp.c +579 -13
- data/ext/asyncengine/ae_udp.h +15 -2
- data/ext/asyncengine/ae_utils.c +192 -0
- data/ext/asyncengine/ae_utils.h +16 -0
- data/ext/asyncengine/asyncengine_ruby.c +469 -26
- data/ext/asyncengine/asyncengine_ruby.h +49 -11
- data/ext/asyncengine/debug.h +68 -0
- data/ext/asyncengine/extconf.rb +26 -2
- data/ext/asyncengine/ip_parser.c +5954 -0
- data/ext/asyncengine/ip_parser.h +16 -0
- data/ext/asyncengine/libuv/AUTHORS +16 -0
- data/ext/asyncengine/libuv/common.gypi +4 -4
- data/ext/asyncengine/libuv/config-mingw.mk +6 -6
- data/ext/asyncengine/libuv/config-unix.mk +13 -13
- data/ext/asyncengine/libuv/gyp_uv +5 -1
- data/ext/asyncengine/libuv/ibc_tests/exec_test.sh +8 -0
- data/ext/asyncengine/libuv/ibc_tests/uv_shutdown_write_issue.c +171 -0
- data/ext/asyncengine/libuv/ibc_tests/uv_tcp_close_while_connecting.c +102 -0
- data/ext/asyncengine/libuv/include/uv-private/ngx-queue.h +3 -1
- data/ext/asyncengine/libuv/include/uv-private/uv-unix.h +103 -50
- data/ext/asyncengine/libuv/include/uv-private/uv-win.h +76 -24
- data/ext/asyncengine/libuv/include/uv.h +353 -88
- data/ext/asyncengine/libuv/src/ares/ares__close_sockets.o +0 -0
- data/ext/asyncengine/libuv/src/ares/ares__get_hostent.o +0 -0
- data/ext/asyncengine/libuv/src/ares/ares__read_line.o +0 -0
- data/ext/asyncengine/libuv/src/ares/ares__timeval.o +0 -0
- data/ext/asyncengine/libuv/src/ares/ares_cancel.o +0 -0
- data/ext/asyncengine/libuv/src/ares/ares_data.o +0 -0
- data/ext/asyncengine/libuv/src/ares/ares_destroy.o +0 -0
- data/ext/asyncengine/libuv/src/ares/ares_expand_name.o +0 -0
- data/ext/asyncengine/libuv/src/ares/ares_expand_string.o +0 -0
- data/ext/asyncengine/libuv/src/ares/ares_fds.o +0 -0
- data/ext/asyncengine/libuv/src/ares/ares_free_hostent.o +0 -0
- data/ext/asyncengine/libuv/src/ares/ares_free_string.o +0 -0
- data/ext/asyncengine/libuv/src/ares/ares_gethostbyaddr.o +0 -0
- data/ext/asyncengine/libuv/src/ares/ares_gethostbyname.o +0 -0
- data/ext/asyncengine/libuv/src/ares/ares_getnameinfo.o +0 -0
- data/ext/asyncengine/libuv/src/ares/ares_getopt.o +0 -0
- data/ext/asyncengine/libuv/src/ares/ares_getsock.o +0 -0
- data/ext/asyncengine/libuv/src/ares/ares_init.o +0 -0
- data/ext/asyncengine/libuv/src/ares/ares_library_init.o +0 -0
- data/ext/asyncengine/libuv/src/ares/ares_llist.o +0 -0
- data/ext/asyncengine/libuv/src/ares/ares_mkquery.o +0 -0
- data/ext/asyncengine/libuv/src/ares/ares_nowarn.o +0 -0
- data/ext/asyncengine/libuv/src/ares/ares_options.o +0 -0
- data/ext/asyncengine/libuv/src/ares/ares_parse_a_reply.o +0 -0
- data/ext/asyncengine/libuv/src/ares/ares_parse_aaaa_reply.o +0 -0
- data/ext/asyncengine/libuv/src/ares/ares_parse_mx_reply.o +0 -0
- data/ext/asyncengine/libuv/src/ares/ares_parse_ns_reply.o +0 -0
- data/ext/asyncengine/libuv/src/ares/ares_parse_ptr_reply.o +0 -0
- data/ext/asyncengine/libuv/src/ares/ares_parse_srv_reply.o +0 -0
- data/ext/asyncengine/libuv/src/ares/ares_parse_txt_reply.o +0 -0
- data/ext/asyncengine/libuv/src/ares/ares_process.o +0 -0
- data/ext/asyncengine/libuv/src/ares/ares_query.o +0 -0
- data/ext/asyncengine/libuv/src/ares/ares_search.o +0 -0
- data/ext/asyncengine/libuv/src/ares/ares_send.o +0 -0
- data/ext/asyncengine/libuv/src/ares/ares_strcasecmp.o +0 -0
- data/ext/asyncengine/libuv/src/ares/ares_strdup.o +0 -0
- data/ext/asyncengine/libuv/src/ares/ares_strerror.o +0 -0
- data/ext/asyncengine/libuv/src/ares/ares_timeout.o +0 -0
- data/ext/asyncengine/libuv/src/ares/ares_version.o +0 -0
- data/ext/asyncengine/libuv/src/ares/ares_writev.o +0 -0
- data/ext/asyncengine/libuv/src/ares/bitncmp.o +0 -0
- data/ext/asyncengine/libuv/src/ares/inet_net_pton.o +0 -0
- data/ext/asyncengine/libuv/src/ares/inet_ntop.o +0 -0
- data/ext/asyncengine/libuv/src/cares.c +225 -0
- data/ext/asyncengine/libuv/src/cares.o +0 -0
- data/ext/asyncengine/libuv/src/fs-poll.c +237 -0
- data/ext/asyncengine/libuv/src/fs-poll.o +0 -0
- data/ext/asyncengine/libuv/src/unix/async.c +78 -17
- data/ext/asyncengine/libuv/src/unix/async.o +0 -0
- data/ext/asyncengine/libuv/src/unix/core.c +305 -213
- data/ext/asyncengine/libuv/src/unix/core.o +0 -0
- data/ext/asyncengine/libuv/src/unix/cygwin.c +1 -1
- data/ext/asyncengine/libuv/src/unix/darwin.c +2 -1
- data/ext/asyncengine/libuv/src/unix/dl.c +36 -44
- data/ext/asyncengine/libuv/src/unix/dl.o +0 -0
- data/ext/asyncengine/libuv/src/unix/eio/eio.o +0 -0
- data/ext/asyncengine/libuv/src/unix/error.c +6 -0
- data/ext/asyncengine/libuv/src/unix/error.o +0 -0
- data/ext/asyncengine/libuv/src/unix/ev/ev.c +8 -4
- data/ext/asyncengine/libuv/src/unix/ev/ev.o +0 -0
- data/ext/asyncengine/libuv/src/unix/freebsd.c +1 -1
- data/ext/asyncengine/libuv/src/unix/fs.c +25 -33
- data/ext/asyncengine/libuv/src/unix/fs.o +0 -0
- data/ext/asyncengine/libuv/src/unix/internal.h +50 -31
- data/ext/asyncengine/libuv/src/unix/kqueue.c +2 -7
- data/ext/asyncengine/libuv/src/unix/linux/core.o +0 -0
- data/ext/asyncengine/libuv/src/unix/linux/inotify.c +12 -14
- data/ext/asyncengine/libuv/src/unix/linux/inotify.o +0 -0
- data/ext/asyncengine/libuv/src/unix/linux/{core.c → linux-core.c} +1 -1
- data/ext/asyncengine/libuv/src/unix/linux/linux-core.o +0 -0
- data/ext/asyncengine/libuv/src/unix/linux/syscalls.c +147 -1
- data/ext/asyncengine/libuv/src/unix/linux/syscalls.h +39 -2
- data/ext/asyncengine/libuv/src/unix/linux/syscalls.o +0 -0
- data/ext/asyncengine/libuv/src/unix/loop-watcher.c +63 -0
- data/ext/asyncengine/libuv/src/unix/loop-watcher.o +0 -0
- data/ext/asyncengine/libuv/src/unix/loop.c +29 -6
- data/ext/asyncengine/libuv/src/unix/loop.o +0 -0
- data/ext/asyncengine/libuv/src/unix/netbsd.c +1 -1
- data/ext/asyncengine/libuv/src/unix/openbsd.c +1 -1
- data/ext/asyncengine/libuv/src/unix/pipe.c +31 -36
- data/ext/asyncengine/libuv/src/unix/pipe.o +0 -0
- data/ext/asyncengine/libuv/src/unix/poll.c +116 -0
- data/ext/asyncengine/libuv/src/unix/poll.o +0 -0
- data/ext/asyncengine/libuv/src/unix/process.c +193 -115
- data/ext/asyncengine/libuv/src/unix/process.o +0 -0
- data/ext/asyncengine/libuv/src/unix/stream.c +146 -153
- data/ext/asyncengine/libuv/src/unix/stream.o +0 -0
- data/ext/asyncengine/libuv/src/unix/sunos.c +45 -36
- data/ext/asyncengine/libuv/src/unix/tcp.c +6 -5
- data/ext/asyncengine/libuv/src/unix/tcp.o +0 -0
- data/ext/asyncengine/libuv/src/unix/thread.c +82 -25
- data/ext/asyncengine/libuv/src/unix/thread.o +0 -0
- data/ext/asyncengine/libuv/src/unix/timer.c +69 -58
- data/ext/asyncengine/libuv/src/unix/timer.o +0 -0
- data/ext/asyncengine/libuv/src/unix/tty.c +3 -3
- data/ext/asyncengine/libuv/src/unix/tty.o +0 -0
- data/ext/asyncengine/libuv/src/unix/udp.c +57 -66
- data/ext/asyncengine/libuv/src/unix/udp.o +0 -0
- data/ext/asyncengine/libuv/src/unix/uv-eio.c +33 -50
- data/ext/asyncengine/libuv/src/unix/uv-eio.o +0 -0
- data/ext/asyncengine/libuv/src/uv-common.c +68 -38
- data/ext/asyncengine/libuv/src/uv-common.h +104 -20
- data/ext/asyncengine/libuv/src/uv-common.o +0 -0
- data/ext/asyncengine/libuv/src/win/async.c +20 -17
- data/ext/asyncengine/libuv/src/win/core.c +44 -31
- data/ext/asyncengine/libuv/src/win/dl.c +40 -36
- data/ext/asyncengine/libuv/src/win/error.c +21 -1
- data/ext/asyncengine/libuv/src/win/fs-event.c +19 -21
- data/ext/asyncengine/libuv/src/win/fs.c +541 -189
- data/ext/asyncengine/libuv/src/win/getaddrinfo.c +56 -63
- data/ext/asyncengine/libuv/src/win/handle-inl.h +145 -0
- data/ext/asyncengine/libuv/src/win/handle.c +26 -101
- data/ext/asyncengine/libuv/src/win/internal.h +92 -107
- data/ext/asyncengine/libuv/src/win/loop-watcher.c +6 -14
- data/ext/asyncengine/libuv/src/win/pipe.c +78 -64
- data/ext/asyncengine/libuv/src/win/poll.c +618 -0
- data/ext/asyncengine/libuv/src/win/process-stdio.c +479 -0
- data/ext/asyncengine/libuv/src/win/process.c +147 -274
- data/ext/asyncengine/libuv/src/win/req-inl.h +225 -0
- data/ext/asyncengine/libuv/src/win/req.c +0 -149
- data/ext/asyncengine/libuv/src/{unix/check.c → win/stream-inl.h} +31 -42
- data/ext/asyncengine/libuv/src/win/stream.c +9 -43
- data/ext/asyncengine/libuv/src/win/tcp.c +200 -82
- data/ext/asyncengine/libuv/src/win/thread.c +42 -2
- data/ext/asyncengine/libuv/src/win/threadpool.c +3 -2
- data/ext/asyncengine/libuv/src/win/timer.c +13 -63
- data/ext/asyncengine/libuv/src/win/tty.c +26 -20
- data/ext/asyncengine/libuv/src/win/udp.c +26 -17
- data/ext/asyncengine/libuv/src/win/util.c +312 -167
- data/ext/asyncengine/libuv/src/win/winapi.c +16 -1
- data/ext/asyncengine/libuv/src/win/winapi.h +33 -9
- data/ext/asyncengine/libuv/src/win/winsock.c +88 -1
- data/ext/asyncengine/libuv/src/win/winsock.h +36 -3
- data/ext/asyncengine/libuv/test/benchmark-ares.c +16 -17
- data/ext/asyncengine/libuv/test/benchmark-fs-stat.c +164 -0
- data/ext/asyncengine/libuv/test/benchmark-list.h +9 -0
- data/ext/asyncengine/libuv/{src/unix/prepare.c → test/benchmark-loop-count.c} +42 -33
- data/ext/asyncengine/libuv/test/benchmark-million-timers.c +65 -0
- data/ext/asyncengine/libuv/test/benchmark-pound.c +1 -1
- data/ext/asyncengine/libuv/test/benchmark-sizes.c +2 -0
- data/ext/asyncengine/libuv/test/benchmark-spawn.c +7 -1
- data/ext/asyncengine/libuv/test/benchmark-udp-packet-storm.c +1 -1
- data/ext/asyncengine/libuv/test/echo-server.c +8 -0
- data/ext/asyncengine/libuv/test/run-tests.c +30 -0
- data/ext/asyncengine/libuv/test/runner-unix.c +6 -26
- data/ext/asyncengine/libuv/test/runner-win.c +5 -63
- data/ext/asyncengine/libuv/test/runner.c +10 -1
- data/ext/asyncengine/libuv/test/task.h +0 -8
- data/ext/asyncengine/libuv/test/test-async.c +43 -141
- data/ext/asyncengine/libuv/test/test-callback-order.c +76 -0
- data/ext/asyncengine/libuv/test/test-counters-init.c +2 -3
- data/ext/asyncengine/libuv/test/test-dlerror.c +17 -8
- data/ext/asyncengine/libuv/test/test-fs-event.c +31 -39
- data/ext/asyncengine/libuv/test/test-fs-poll.c +146 -0
- data/ext/asyncengine/libuv/test/test-fs.c +114 -2
- data/ext/asyncengine/libuv/test/test-gethostbyname.c +8 -8
- data/ext/asyncengine/libuv/test/test-hrtime.c +18 -15
- data/ext/asyncengine/libuv/test/test-ipc.c +8 -2
- data/ext/asyncengine/libuv/test/test-list.h +59 -9
- data/ext/asyncengine/libuv/test/test-loop-handles.c +2 -25
- data/ext/asyncengine/libuv/{src/unix/idle.c → test/test-poll-close.c} +37 -39
- data/ext/asyncengine/libuv/test/test-poll.c +573 -0
- data/ext/asyncengine/libuv/test/test-ref.c +79 -63
- data/ext/asyncengine/libuv/test/test-run-once.c +15 -11
- data/ext/asyncengine/libuv/test/test-semaphore.c +111 -0
- data/ext/asyncengine/libuv/test/test-spawn.c +368 -20
- data/ext/asyncengine/libuv/test/test-stdio-over-pipes.c +25 -35
- data/ext/asyncengine/libuv/test/test-tcp-close-while-connecting.c +80 -0
- data/ext/asyncengine/libuv/test/test-tcp-close.c +1 -1
- data/ext/asyncengine/libuv/test/test-tcp-connect-error-after-write.c +95 -0
- data/ext/asyncengine/libuv/test/test-tcp-connect-timeout.c +85 -0
- data/ext/asyncengine/libuv/test/test-tcp-shutdown-after-write.c +131 -0
- data/ext/asyncengine/libuv/test/test-tcp-write-error.c +2 -2
- data/ext/asyncengine/libuv/test/test-tcp-writealot.c +29 -54
- data/ext/asyncengine/libuv/test/test-timer-again.c +1 -1
- data/ext/asyncengine/libuv/test/test-timer.c +23 -1
- data/ext/asyncengine/libuv/test/test-udp-options.c +1 -1
- data/ext/asyncengine/libuv/test/{test-eio-overflow.c → test-walk-handles.c} +31 -44
- data/ext/asyncengine/libuv/uv.gyp +26 -9
- data/ext/asyncengine/rb_utilities.c +54 -0
- data/ext/asyncengine/rb_utilities.h +63 -0
- data/lib/asyncengine.rb +45 -38
- data/lib/asyncengine/asyncengine_ext.so +0 -0
- data/lib/asyncengine/debug.rb +37 -0
- data/lib/asyncengine/handle.rb +9 -0
- data/lib/asyncengine/tcp.rb +28 -0
- data/lib/asyncengine/timer.rb +18 -28
- data/lib/asyncengine/udp.rb +29 -0
- data/lib/asyncengine/utils.rb +32 -0
- data/lib/asyncengine/uv_error.rb +17 -0
- data/lib/asyncengine/version.rb +9 -1
- data/test/ae_test_helper.rb +62 -0
- data/test/test_basic.rb +169 -0
- data/test/test_call_from_other_thread.rb +55 -0
- data/test/test_error.rb +92 -0
- data/test/test_ip_utils.rb +44 -0
- data/test/test_next_tick.rb +37 -0
- data/test/test_resolver.rb +51 -0
- data/test/test_threads.rb +69 -0
- data/test/test_timer.rb +95 -0
- data/test/test_udp.rb +216 -0
- data/test/test_utils.rb +49 -0
- metadata +84 -57
- data/ext/asyncengine/libuv/mkmf.log +0 -24
- data/ext/asyncengine/libuv/src/unix/cares.c +0 -194
- data/ext/asyncengine/libuv/src/unix/cares.o +0 -0
- data/ext/asyncengine/libuv/src/unix/check.o +0 -0
- data/ext/asyncengine/libuv/src/unix/idle.o +0 -0
- data/ext/asyncengine/libuv/src/unix/prepare.o +0 -0
- data/ext/asyncengine/libuv/src/win/cares.c +0 -290
- data/lib/asyncengine/errors.rb +0 -5
- data/lib/asyncengine/next_tick.rb +0 -24
|
Binary file
|
|
@@ -29,10 +29,14 @@
|
|
|
29
29
|
#include <unistd.h>
|
|
30
30
|
#include <stdlib.h>
|
|
31
31
|
|
|
32
|
+
static void uv__pipe_accept(uv_loop_t* loop, uv__io_t* w, int events);
|
|
33
|
+
|
|
32
34
|
|
|
33
35
|
int uv_pipe_init(uv_loop_t* loop, uv_pipe_t* handle, int ipc) {
|
|
34
36
|
uv__stream_init(loop, (uv_stream_t*)handle, UV_NAMED_PIPE);
|
|
35
37
|
loop->counters.pipe_init++;
|
|
38
|
+
handle->shutdown_req = NULL;
|
|
39
|
+
handle->connect_req = NULL;
|
|
36
40
|
handle->pipe_fname = NULL;
|
|
37
41
|
handle->ipc = ipc;
|
|
38
42
|
return 0;
|
|
@@ -77,22 +81,10 @@ int uv_pipe_bind(uv_pipe_t* handle, const char* name) {
|
|
|
77
81
|
uv_strlcpy(saddr.sun_path, pipe_fname, sizeof(saddr.sun_path));
|
|
78
82
|
saddr.sun_family = AF_UNIX;
|
|
79
83
|
|
|
80
|
-
if (bind(sockfd, (struct sockaddr*)&saddr, sizeof saddr)
|
|
81
|
-
/*
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
* on the socket. Ergo, it's stale - remove it.
|
|
85
|
-
*
|
|
86
|
-
* This assumes that the other process uses locking too
|
|
87
|
-
* but that's a good enough assumption for now.
|
|
88
|
-
*/
|
|
89
|
-
if (errno != EADDRINUSE
|
|
90
|
-
|| unlink(pipe_fname) == -1
|
|
91
|
-
|| bind(sockfd, (struct sockaddr*)&saddr, sizeof saddr) == -1) {
|
|
92
|
-
/* Convert ENOENT to EACCES for compatibility with Windows. */
|
|
93
|
-
uv__set_sys_error(handle->loop, (errno == ENOENT) ? EACCES : errno);
|
|
94
|
-
goto out;
|
|
95
|
-
}
|
|
84
|
+
if (bind(sockfd, (struct sockaddr*)&saddr, sizeof saddr)) {
|
|
85
|
+
/* Convert ENOENT to EACCES for compatibility with Windows. */
|
|
86
|
+
uv__set_sys_error(handle->loop, (errno == ENOENT) ? EACCES : errno);
|
|
87
|
+
goto out;
|
|
96
88
|
}
|
|
97
89
|
bound = 1;
|
|
98
90
|
|
|
@@ -136,8 +128,11 @@ int uv_pipe_listen(uv_pipe_t* handle, int backlog, uv_connection_cb cb) {
|
|
|
136
128
|
uv__set_sys_error(handle->loop, errno);
|
|
137
129
|
} else {
|
|
138
130
|
handle->connection_cb = cb;
|
|
139
|
-
|
|
140
|
-
|
|
131
|
+
uv__io_init(&handle->read_watcher,
|
|
132
|
+
uv__pipe_accept,
|
|
133
|
+
handle->fd,
|
|
134
|
+
UV__IO_READ);
|
|
135
|
+
uv__io_start(handle->loop, &handle->read_watcher);
|
|
141
136
|
}
|
|
142
137
|
|
|
143
138
|
out:
|
|
@@ -163,7 +158,9 @@ void uv__pipe_close(uv_pipe_t* handle) {
|
|
|
163
158
|
|
|
164
159
|
|
|
165
160
|
void uv_pipe_open(uv_pipe_t* handle, uv_file fd) {
|
|
166
|
-
uv__stream_open((uv_stream_t*)handle,
|
|
161
|
+
uv__stream_open((uv_stream_t*)handle,
|
|
162
|
+
fd,
|
|
163
|
+
UV_STREAM_READABLE | UV_STREAM_WRITABLE);
|
|
167
164
|
}
|
|
168
165
|
|
|
169
166
|
|
|
@@ -204,24 +201,24 @@ void uv_pipe_connect(uv_connect_t* req,
|
|
|
204
201
|
goto out;
|
|
205
202
|
}
|
|
206
203
|
|
|
207
|
-
uv__stream_open((uv_stream_t*)handle,
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
204
|
+
uv__stream_open((uv_stream_t*)handle,
|
|
205
|
+
sockfd,
|
|
206
|
+
UV_STREAM_READABLE | UV_STREAM_WRITABLE);
|
|
207
|
+
uv__io_start(handle->loop, &handle->read_watcher);
|
|
208
|
+
uv__io_start(handle->loop, &handle->write_watcher);
|
|
212
209
|
status = 0;
|
|
213
210
|
|
|
214
211
|
out:
|
|
215
212
|
handle->delayed_error = status; /* Passed to callback. */
|
|
216
213
|
handle->connect_req = req;
|
|
214
|
+
|
|
215
|
+
uv__req_init(handle->loop, req, UV_CONNECT);
|
|
217
216
|
req->handle = (uv_stream_t*)handle;
|
|
218
|
-
req->type = UV_CONNECT;
|
|
219
217
|
req->cb = cb;
|
|
220
218
|
ngx_queue_init(&req->queue);
|
|
221
219
|
|
|
222
220
|
/* Run callback on next tick. */
|
|
223
|
-
|
|
224
|
-
assert(ev_is_pending(&handle->read_watcher));
|
|
221
|
+
uv__io_feed(handle->loop, &handle->write_watcher, UV__IO_WRITE);
|
|
225
222
|
|
|
226
223
|
/* Mimic the Windows pipe implementation, always
|
|
227
224
|
* return 0 and let the callback handle errors.
|
|
@@ -231,30 +228,28 @@ out:
|
|
|
231
228
|
|
|
232
229
|
|
|
233
230
|
/* TODO merge with uv__server_io()? */
|
|
234
|
-
void uv__pipe_accept(
|
|
235
|
-
struct sockaddr_un saddr;
|
|
231
|
+
static void uv__pipe_accept(uv_loop_t* loop, uv__io_t* w, int events) {
|
|
236
232
|
uv_pipe_t* pipe;
|
|
237
233
|
int saved_errno;
|
|
238
234
|
int sockfd;
|
|
239
235
|
|
|
240
236
|
saved_errno = errno;
|
|
241
|
-
pipe =
|
|
237
|
+
pipe = container_of(w, uv_pipe_t, read_watcher);
|
|
242
238
|
|
|
243
239
|
assert(pipe->type == UV_NAMED_PIPE);
|
|
244
240
|
|
|
245
|
-
sockfd = uv__accept(pipe->fd
|
|
241
|
+
sockfd = uv__accept(pipe->fd);
|
|
246
242
|
if (sockfd == -1) {
|
|
247
|
-
if (errno
|
|
248
|
-
assert(0 && "EAGAIN on uv__accept(pipefd)");
|
|
249
|
-
} else {
|
|
243
|
+
if (errno != EAGAIN && errno != EWOULDBLOCK) {
|
|
250
244
|
uv__set_sys_error(pipe->loop, errno);
|
|
245
|
+
pipe->connection_cb((uv_stream_t*)pipe, -1);
|
|
251
246
|
}
|
|
252
247
|
} else {
|
|
253
248
|
pipe->accepted_fd = sockfd;
|
|
254
249
|
pipe->connection_cb((uv_stream_t*)pipe, 0);
|
|
255
250
|
if (pipe->accepted_fd == sockfd) {
|
|
256
|
-
/* The user hasn't
|
|
257
|
-
|
|
251
|
+
/* The user hasn't called uv_accept() yet */
|
|
252
|
+
uv__io_stop(pipe->loop, &pipe->read_watcher);
|
|
258
253
|
}
|
|
259
254
|
}
|
|
260
255
|
|
|
Binary file
|
|
@@ -0,0 +1,116 @@
|
|
|
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 "internal.h"
|
|
24
|
+
|
|
25
|
+
#include <unistd.h>
|
|
26
|
+
#include <assert.h>
|
|
27
|
+
#include <errno.h>
|
|
28
|
+
|
|
29
|
+
|
|
30
|
+
static void uv__poll_io(uv_loop_t* loop, uv__io_t* w, int events) {
|
|
31
|
+
uv_poll_t* handle;
|
|
32
|
+
int pevents;
|
|
33
|
+
|
|
34
|
+
handle = container_of(w, uv_poll_t, io_watcher);
|
|
35
|
+
|
|
36
|
+
if (events & UV__IO_ERROR) {
|
|
37
|
+
/* An error happened. Libev has implicitly stopped the watcher, but we */
|
|
38
|
+
/* need to fix the refcount. */
|
|
39
|
+
uv__handle_stop(handle);
|
|
40
|
+
uv__set_sys_error(handle->loop, EBADF);
|
|
41
|
+
handle->poll_cb(handle, -1, 0);
|
|
42
|
+
return;
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
pevents = 0;
|
|
46
|
+
if (events & UV__IO_READ)
|
|
47
|
+
pevents |= UV_READABLE;
|
|
48
|
+
if (events & UV__IO_WRITE)
|
|
49
|
+
pevents |= UV_WRITABLE;
|
|
50
|
+
|
|
51
|
+
handle->poll_cb(handle, 0, pevents);
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
|
|
55
|
+
int uv_poll_init(uv_loop_t* loop, uv_poll_t* handle, int fd) {
|
|
56
|
+
uv__handle_init(loop, (uv_handle_t*) handle, UV_POLL);
|
|
57
|
+
loop->counters.poll_init++;
|
|
58
|
+
|
|
59
|
+
handle->fd = fd;
|
|
60
|
+
handle->poll_cb = NULL;
|
|
61
|
+
uv__io_init(&handle->io_watcher, uv__poll_io, fd, 0);
|
|
62
|
+
|
|
63
|
+
return 0;
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
|
|
67
|
+
int uv_poll_init_socket(uv_loop_t* loop, uv_poll_t* handle,
|
|
68
|
+
uv_os_sock_t socket) {
|
|
69
|
+
return uv_poll_init(loop, handle, socket);
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
|
|
73
|
+
static void uv__poll_stop(uv_poll_t* handle) {
|
|
74
|
+
uv__io_stop(handle->loop, &handle->io_watcher);
|
|
75
|
+
uv__handle_stop(handle);
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
|
|
79
|
+
int uv_poll_stop(uv_poll_t* handle) {
|
|
80
|
+
assert(!(handle->flags & (UV_CLOSING | UV_CLOSED)));
|
|
81
|
+
uv__poll_stop(handle);
|
|
82
|
+
return 0;
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
|
|
86
|
+
int uv_poll_start(uv_poll_t* handle, int pevents, uv_poll_cb poll_cb) {
|
|
87
|
+
int events;
|
|
88
|
+
|
|
89
|
+
assert((pevents & ~(UV_READABLE | UV_WRITABLE)) == 0);
|
|
90
|
+
assert(!(handle->flags & (UV_CLOSING | UV_CLOSED)));
|
|
91
|
+
|
|
92
|
+
if (pevents == 0) {
|
|
93
|
+
uv__poll_stop(handle);
|
|
94
|
+
return 0;
|
|
95
|
+
}
|
|
96
|
+
|
|
97
|
+
events = 0;
|
|
98
|
+
if (pevents & UV_READABLE)
|
|
99
|
+
events |= UV__IO_READ;
|
|
100
|
+
if (pevents & UV_WRITABLE)
|
|
101
|
+
events |= UV__IO_WRITE;
|
|
102
|
+
|
|
103
|
+
uv__io_stop(handle->loop, &handle->io_watcher);
|
|
104
|
+
uv__io_set(&handle->io_watcher, uv__poll_io, handle->fd, events);
|
|
105
|
+
uv__io_start(handle->loop, &handle->io_watcher);
|
|
106
|
+
|
|
107
|
+
handle->poll_cb = poll_cb;
|
|
108
|
+
uv__handle_start(handle);
|
|
109
|
+
|
|
110
|
+
return 0;
|
|
111
|
+
}
|
|
112
|
+
|
|
113
|
+
|
|
114
|
+
void uv__poll_close(uv_poll_t* handle) {
|
|
115
|
+
uv__poll_stop(handle);
|
|
116
|
+
}
|
|
Binary file
|
|
@@ -25,10 +25,10 @@
|
|
|
25
25
|
#include <assert.h>
|
|
26
26
|
#include <errno.h>
|
|
27
27
|
#include <sys/wait.h>
|
|
28
|
-
#include <fcntl.h> /* O_CLOEXEC, O_NONBLOCK */
|
|
29
28
|
#include <poll.h>
|
|
30
29
|
#include <unistd.h>
|
|
31
30
|
#include <stdio.h>
|
|
31
|
+
#include <fcntl.h>
|
|
32
32
|
|
|
33
33
|
#ifdef __APPLE__
|
|
34
34
|
# include <TargetConditionals.h>
|
|
@@ -68,25 +68,15 @@ static void uv__chld(EV_P_ ev_child* watcher, int revents) {
|
|
|
68
68
|
|
|
69
69
|
|
|
70
70
|
int uv__make_socketpair(int fds[2], int flags) {
|
|
71
|
-
#
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
fl = SOCK_CLOEXEC;
|
|
75
|
-
|
|
76
|
-
if (flags & UV__F_NONBLOCK)
|
|
77
|
-
fl |= SOCK_NONBLOCK;
|
|
78
|
-
|
|
79
|
-
if (socketpair(AF_UNIX, SOCK_STREAM|fl, 0, fds) == 0)
|
|
71
|
+
#if __linux__
|
|
72
|
+
if (socketpair(AF_UNIX, SOCK_STREAM | UV__SOCK_CLOEXEC | flags, 0, fds) == 0)
|
|
80
73
|
return 0;
|
|
81
74
|
|
|
75
|
+
/* Retry on EINVAL, it means SOCK_CLOEXEC is not supported.
|
|
76
|
+
* Anything else is a genuine error.
|
|
77
|
+
*/
|
|
82
78
|
if (errno != EINVAL)
|
|
83
79
|
return -1;
|
|
84
|
-
|
|
85
|
-
/* errno == EINVAL so maybe the kernel headers lied about
|
|
86
|
-
* the availability of SOCK_NONBLOCK. This can happen if people
|
|
87
|
-
* build libuv against newer kernel headers than the kernel
|
|
88
|
-
* they actually run the software on.
|
|
89
|
-
*/
|
|
90
80
|
#endif
|
|
91
81
|
|
|
92
82
|
if (socketpair(AF_UNIX, SOCK_STREAM, 0, fds))
|
|
@@ -106,14 +96,7 @@ int uv__make_socketpair(int fds[2], int flags) {
|
|
|
106
96
|
|
|
107
97
|
int uv__make_pipe(int fds[2], int flags) {
|
|
108
98
|
#if __linux__
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
fl = O_CLOEXEC;
|
|
112
|
-
|
|
113
|
-
if (flags & UV__F_NONBLOCK)
|
|
114
|
-
fl |= O_NONBLOCK;
|
|
115
|
-
|
|
116
|
-
if (uv__pipe2(fds, fl) == 0)
|
|
99
|
+
if (uv__pipe2(fds, flags | UV__O_CLOEXEC) == 0)
|
|
117
100
|
return 0;
|
|
118
101
|
|
|
119
102
|
if (errno != ENOSYS)
|
|
@@ -139,16 +122,146 @@ int uv__make_pipe(int fds[2], int flags) {
|
|
|
139
122
|
* Used for initializing stdio streams like options.stdin_stream. Returns
|
|
140
123
|
* zero on success.
|
|
141
124
|
*/
|
|
142
|
-
static int
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
125
|
+
static int uv__process_init_stdio(uv_stdio_container_t* container, int fds[2],
|
|
126
|
+
int writable) {
|
|
127
|
+
int fd = -1;
|
|
128
|
+
switch (container->flags & (UV_IGNORE | UV_CREATE_PIPE | UV_INHERIT_FD |
|
|
129
|
+
UV_INHERIT_STREAM)) {
|
|
130
|
+
case UV_IGNORE:
|
|
131
|
+
return 0;
|
|
132
|
+
case UV_CREATE_PIPE:
|
|
133
|
+
assert(container->data.stream != NULL);
|
|
134
|
+
|
|
135
|
+
if (container->data.stream->type != UV_NAMED_PIPE) {
|
|
136
|
+
errno = EINVAL;
|
|
137
|
+
return -1;
|
|
138
|
+
}
|
|
139
|
+
|
|
140
|
+
return uv__make_socketpair(fds, 0);
|
|
141
|
+
case UV_INHERIT_FD:
|
|
142
|
+
case UV_INHERIT_STREAM:
|
|
143
|
+
if (container->flags & UV_INHERIT_FD) {
|
|
144
|
+
fd = container->data.fd;
|
|
145
|
+
} else {
|
|
146
|
+
fd = container->data.stream->fd;
|
|
147
|
+
}
|
|
148
|
+
|
|
149
|
+
if (fd == -1) {
|
|
150
|
+
errno = EINVAL;
|
|
151
|
+
return -1;
|
|
152
|
+
}
|
|
153
|
+
|
|
154
|
+
fds[writable ? 1 : 0] = fd;
|
|
155
|
+
|
|
156
|
+
return 0;
|
|
157
|
+
default:
|
|
158
|
+
assert(0 && "Unexpected flags");
|
|
159
|
+
return -1;
|
|
146
160
|
}
|
|
161
|
+
}
|
|
162
|
+
|
|
147
163
|
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
164
|
+
static int uv__process_stdio_flags(uv_stdio_container_t* container,
|
|
165
|
+
int writable) {
|
|
166
|
+
if (container->data.stream->type == UV_NAMED_PIPE &&
|
|
167
|
+
((uv_pipe_t*)container->data.stream)->ipc) {
|
|
168
|
+
return UV_STREAM_READABLE | UV_STREAM_WRITABLE;
|
|
169
|
+
} else if (writable) {
|
|
170
|
+
return UV_STREAM_WRITABLE;
|
|
171
|
+
} else {
|
|
172
|
+
return UV_STREAM_READABLE;
|
|
173
|
+
}
|
|
174
|
+
}
|
|
175
|
+
|
|
176
|
+
|
|
177
|
+
static int uv__process_open_stream(uv_stdio_container_t* container, int fds[2],
|
|
178
|
+
int writable) {
|
|
179
|
+
int fd = fds[writable ? 1 : 0];
|
|
180
|
+
int child_fd = fds[writable ? 0 : 1];
|
|
181
|
+
int flags;
|
|
182
|
+
|
|
183
|
+
/* No need to create stream */
|
|
184
|
+
if (!(container->flags & UV_CREATE_PIPE) || fd < 0) {
|
|
185
|
+
return 0;
|
|
186
|
+
}
|
|
187
|
+
|
|
188
|
+
assert(child_fd >= 0);
|
|
189
|
+
close(child_fd);
|
|
190
|
+
|
|
191
|
+
uv__nonblock(fd, 1);
|
|
192
|
+
flags = uv__process_stdio_flags(container, writable);
|
|
193
|
+
|
|
194
|
+
return uv__stream_open((uv_stream_t*)container->data.stream, fd, flags);
|
|
195
|
+
}
|
|
196
|
+
|
|
197
|
+
|
|
198
|
+
static void uv__process_close_stream(uv_stdio_container_t* container) {
|
|
199
|
+
if (!(container->flags & UV_CREATE_PIPE)) return;
|
|
200
|
+
|
|
201
|
+
uv__stream_close((uv_stream_t*)container->data.stream);
|
|
202
|
+
}
|
|
203
|
+
|
|
204
|
+
|
|
205
|
+
static void uv__process_child_init(uv_process_options_t options,
|
|
206
|
+
int stdio_count,
|
|
207
|
+
int* pipes) {
|
|
208
|
+
int i;
|
|
209
|
+
|
|
210
|
+
if (options.flags & UV_PROCESS_DETACHED) {
|
|
211
|
+
setsid();
|
|
212
|
+
}
|
|
213
|
+
|
|
214
|
+
/* Dup fds */
|
|
215
|
+
for (i = 0; i < stdio_count; i++) {
|
|
216
|
+
/*
|
|
217
|
+
* stdin has swapped ends of pipe
|
|
218
|
+
* (it's the only one readable stream)
|
|
219
|
+
*/
|
|
220
|
+
int close_fd = i == 0 ? pipes[i * 2 + 1] : pipes[i * 2];
|
|
221
|
+
int use_fd = i == 0 ? pipes[i * 2] : pipes[i * 2 + 1];
|
|
222
|
+
|
|
223
|
+
if (use_fd >= 0) {
|
|
224
|
+
close(close_fd);
|
|
225
|
+
} else if (i < 3) {
|
|
226
|
+
/* `/dev/null` stdin, stdout, stderr even if they've flag UV_IGNORE */
|
|
227
|
+
use_fd = open("/dev/null", i == 0 ? O_RDONLY : O_RDWR);
|
|
228
|
+
|
|
229
|
+
if (use_fd < 0) {
|
|
230
|
+
perror("failed to open stdio");
|
|
231
|
+
_exit(127);
|
|
232
|
+
}
|
|
233
|
+
} else {
|
|
234
|
+
continue;
|
|
235
|
+
}
|
|
236
|
+
|
|
237
|
+
if (i != use_fd) {
|
|
238
|
+
dup2(use_fd, i);
|
|
239
|
+
close(use_fd);
|
|
240
|
+
} else {
|
|
241
|
+
uv__cloexec(use_fd, 0);
|
|
242
|
+
}
|
|
243
|
+
}
|
|
244
|
+
|
|
245
|
+
if (options.cwd && chdir(options.cwd)) {
|
|
246
|
+
perror("chdir()");
|
|
247
|
+
_exit(127);
|
|
248
|
+
}
|
|
249
|
+
|
|
250
|
+
if ((options.flags & UV_PROCESS_SETGID) && setgid(options.gid)) {
|
|
251
|
+
perror("setgid()");
|
|
252
|
+
_exit(127);
|
|
253
|
+
}
|
|
254
|
+
|
|
255
|
+
if ((options.flags & UV_PROCESS_SETUID) && setuid(options.uid)) {
|
|
256
|
+
perror("setuid()");
|
|
257
|
+
_exit(127);
|
|
258
|
+
}
|
|
259
|
+
|
|
260
|
+
environ = options.env;
|
|
261
|
+
|
|
262
|
+
execvp(options.file, options.args);
|
|
263
|
+
perror("execvp()");
|
|
264
|
+
_exit(127);
|
|
152
265
|
}
|
|
153
266
|
|
|
154
267
|
|
|
@@ -163,35 +276,47 @@ int uv_spawn(uv_loop_t* loop, uv_process_t* process,
|
|
|
163
276
|
* by the child process.
|
|
164
277
|
*/
|
|
165
278
|
char** save_our_env = environ;
|
|
166
|
-
|
|
167
|
-
int
|
|
168
|
-
int
|
|
279
|
+
|
|
280
|
+
int stdio_count = options.stdio_count < 3 ? 3 : options.stdio_count;
|
|
281
|
+
int* pipes = malloc(2 * stdio_count * sizeof(int));
|
|
282
|
+
|
|
169
283
|
#if SPAWN_WAIT_EXEC
|
|
170
284
|
int signal_pipe[2] = { -1, -1 };
|
|
171
285
|
struct pollfd pfd;
|
|
172
286
|
#endif
|
|
173
287
|
int status;
|
|
174
288
|
pid_t pid;
|
|
175
|
-
int
|
|
289
|
+
int i;
|
|
290
|
+
|
|
291
|
+
if (pipes == NULL) {
|
|
292
|
+
errno = ENOMEM;
|
|
293
|
+
goto error;
|
|
294
|
+
}
|
|
295
|
+
|
|
296
|
+
assert(options.file != NULL);
|
|
297
|
+
assert(!(options.flags & ~(UV_PROCESS_WINDOWS_VERBATIM_ARGUMENTS |
|
|
298
|
+
UV_PROCESS_DETACHED |
|
|
299
|
+
UV_PROCESS_SETGID |
|
|
300
|
+
UV_PROCESS_SETUID)));
|
|
301
|
+
|
|
176
302
|
|
|
177
303
|
uv__handle_init(loop, (uv_handle_t*)process, UV_PROCESS);
|
|
178
304
|
loop->counters.process_init++;
|
|
305
|
+
uv__handle_start(process);
|
|
179
306
|
|
|
180
307
|
process->exit_cb = options.exit_cb;
|
|
181
308
|
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
if (options.stdout_stream &&
|
|
188
|
-
uv__process_init_pipe(options.stdout_stream, stdout_pipe, 0)) {
|
|
189
|
-
goto error;
|
|
309
|
+
/* Init pipe pairs */
|
|
310
|
+
for (i = 0; i < stdio_count; i++) {
|
|
311
|
+
pipes[i * 2] = -1;
|
|
312
|
+
pipes[i * 2 + 1] = -1;
|
|
190
313
|
}
|
|
191
314
|
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
315
|
+
/* Create socketpairs/pipes, or use raw fd */
|
|
316
|
+
for (i = 0; i < options.stdio_count; i++) {
|
|
317
|
+
if (uv__process_init_stdio(&options.stdio[i], pipes + i * 2, i != 0)) {
|
|
318
|
+
goto error;
|
|
319
|
+
}
|
|
195
320
|
}
|
|
196
321
|
|
|
197
322
|
/* This pipe is used by the parent to wait until
|
|
@@ -231,43 +356,9 @@ int uv_spawn(uv_loop_t* loop, uv_process_t* process,
|
|
|
231
356
|
}
|
|
232
357
|
|
|
233
358
|
if (pid == 0) {
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
dup2(stdin_pipe[0], STDIN_FILENO);
|
|
237
|
-
} else {
|
|
238
|
-
/* Reset flags that might be set by Node */
|
|
239
|
-
uv__cloexec(STDIN_FILENO, 0);
|
|
240
|
-
uv__nonblock(STDIN_FILENO, 0);
|
|
241
|
-
}
|
|
359
|
+
/* Child */
|
|
360
|
+
uv__process_child_init(options, stdio_count, pipes);
|
|
242
361
|
|
|
243
|
-
if (stdout_pipe[1] >= 0) {
|
|
244
|
-
close(stdout_pipe[0]);
|
|
245
|
-
dup2(stdout_pipe[1], STDOUT_FILENO);
|
|
246
|
-
} else {
|
|
247
|
-
/* Reset flags that might be set by Node */
|
|
248
|
-
uv__cloexec(STDOUT_FILENO, 0);
|
|
249
|
-
uv__nonblock(STDOUT_FILENO, 0);
|
|
250
|
-
}
|
|
251
|
-
|
|
252
|
-
if (stderr_pipe[1] >= 0) {
|
|
253
|
-
close(stderr_pipe[0]);
|
|
254
|
-
dup2(stderr_pipe[1], STDERR_FILENO);
|
|
255
|
-
} else {
|
|
256
|
-
/* Reset flags that might be set by Node */
|
|
257
|
-
uv__cloexec(STDERR_FILENO, 0);
|
|
258
|
-
uv__nonblock(STDERR_FILENO, 0);
|
|
259
|
-
}
|
|
260
|
-
|
|
261
|
-
if (options.cwd && chdir(options.cwd)) {
|
|
262
|
-
perror("chdir()");
|
|
263
|
-
_exit(127);
|
|
264
|
-
}
|
|
265
|
-
|
|
266
|
-
environ = options.env;
|
|
267
|
-
|
|
268
|
-
execvp(options.file, options.args);
|
|
269
|
-
perror("execvp()");
|
|
270
|
-
_exit(127);
|
|
271
362
|
/* Execution never reaches here. */
|
|
272
363
|
}
|
|
273
364
|
|
|
@@ -297,46 +388,32 @@ int uv_spawn(uv_loop_t* loop, uv_process_t* process,
|
|
|
297
388
|
ev_child_start(process->loop->ev, &process->child_watcher);
|
|
298
389
|
process->child_watcher.data = process;
|
|
299
390
|
|
|
300
|
-
|
|
301
|
-
|
|
302
|
-
|
|
303
|
-
|
|
304
|
-
|
|
305
|
-
|
|
306
|
-
|
|
307
|
-
flags);
|
|
308
|
-
}
|
|
391
|
+
for (i = 0; i < options.stdio_count; i++) {
|
|
392
|
+
if (uv__process_open_stream(&options.stdio[i], pipes + i * 2, i == 0)) {
|
|
393
|
+
int j;
|
|
394
|
+
/* Close all opened streams */
|
|
395
|
+
for (j = 0; j < i; j++) {
|
|
396
|
+
uv__process_close_stream(&options.stdio[j]);
|
|
397
|
+
}
|
|
309
398
|
|
|
310
|
-
|
|
311
|
-
|
|
312
|
-
assert(stdout_pipe[1] >= 0);
|
|
313
|
-
close(stdout_pipe[1]);
|
|
314
|
-
uv__nonblock(stdout_pipe[0], 1);
|
|
315
|
-
flags = UV_READABLE | (options.stdout_stream->ipc ? UV_WRITABLE : 0);
|
|
316
|
-
uv__stream_open((uv_stream_t*)options.stdout_stream, stdout_pipe[0],
|
|
317
|
-
flags);
|
|
399
|
+
goto error;
|
|
400
|
+
}
|
|
318
401
|
}
|
|
319
402
|
|
|
320
|
-
|
|
321
|
-
assert(options.stderr_stream);
|
|
322
|
-
assert(stderr_pipe[1] >= 0);
|
|
323
|
-
close(stderr_pipe[1]);
|
|
324
|
-
uv__nonblock(stderr_pipe[0], 1);
|
|
325
|
-
flags = UV_READABLE | (options.stderr_stream->ipc ? UV_WRITABLE : 0);
|
|
326
|
-
uv__stream_open((uv_stream_t*)options.stderr_stream, stderr_pipe[0],
|
|
327
|
-
flags);
|
|
328
|
-
}
|
|
403
|
+
free(pipes);
|
|
329
404
|
|
|
330
405
|
return 0;
|
|
331
406
|
|
|
332
407
|
error:
|
|
333
408
|
uv__set_sys_error(process->loop, errno);
|
|
334
|
-
|
|
335
|
-
|
|
336
|
-
|
|
337
|
-
|
|
338
|
-
|
|
339
|
-
|
|
409
|
+
|
|
410
|
+
for (i = 0; i < stdio_count; i++) {
|
|
411
|
+
close(pipes[i * 2]);
|
|
412
|
+
close(pipes[i * 2 + 1]);
|
|
413
|
+
}
|
|
414
|
+
|
|
415
|
+
free(pipes);
|
|
416
|
+
|
|
340
417
|
return -1;
|
|
341
418
|
}
|
|
342
419
|
|
|
@@ -366,4 +443,5 @@ uv_err_t uv_kill(int pid, int signum) {
|
|
|
366
443
|
|
|
367
444
|
void uv__process_close(uv_process_t* handle) {
|
|
368
445
|
ev_child_stop(handle->loop->ev, &handle->child_watcher);
|
|
446
|
+
uv__handle_stop(handle);
|
|
369
447
|
}
|