foolio 0.0.3
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/.gitignore +22 -0
- data/Gemfile +4 -0
- data/LICENSE +22 -0
- data/README.md +29 -0
- data/Rakefile +21 -0
- data/examples/timer.rb +20 -0
- data/ext/foolio/extconf.rb +34 -0
- data/ext/foolio/foolio_ext.c +921 -0
- data/ext/foolio/gen.rb +50 -0
- data/ext/foolio/make_table.rb +12 -0
- data/ext/foolio/templ +243 -0
- data/ext/libuv/.gitignore +33 -0
- data/ext/libuv/.mailmap +13 -0
- data/ext/libuv/.travis.yml +9 -0
- data/ext/libuv/AUTHORS +61 -0
- data/ext/libuv/LICENSE +44 -0
- data/ext/libuv/Makefile +71 -0
- data/ext/libuv/README.md +90 -0
- data/ext/libuv/common.gypi +178 -0
- data/ext/libuv/gyp_uv +73 -0
- data/ext/libuv/include/uv-private/eio.h +403 -0
- data/ext/libuv/include/uv-private/ev.h +838 -0
- data/ext/libuv/include/uv-private/ngx-queue.h +108 -0
- data/ext/libuv/include/uv-private/tree.h +768 -0
- data/ext/libuv/include/uv-private/uv-unix.h +324 -0
- data/ext/libuv/include/uv-private/uv-win.h +517 -0
- data/ext/libuv/include/uv.h +1838 -0
- data/ext/libuv/src/fs-poll.c +235 -0
- data/ext/libuv/src/inet.c +293 -0
- data/ext/libuv/src/unix/async.c +148 -0
- data/ext/libuv/src/unix/core.c +696 -0
- data/ext/libuv/src/unix/cygwin.c +83 -0
- data/ext/libuv/src/unix/darwin.c +342 -0
- data/ext/libuv/src/unix/dl.c +83 -0
- data/ext/libuv/src/unix/eio/Changes +63 -0
- data/ext/libuv/src/unix/eio/LICENSE +36 -0
- data/ext/libuv/src/unix/eio/Makefile.am +15 -0
- data/ext/libuv/src/unix/eio/aclocal.m4 +8957 -0
- data/ext/libuv/src/unix/eio/autogen.sh +3 -0
- data/ext/libuv/src/unix/eio/config.h.in +86 -0
- data/ext/libuv/src/unix/eio/config_cygwin.h +80 -0
- data/ext/libuv/src/unix/eio/config_darwin.h +141 -0
- data/ext/libuv/src/unix/eio/config_freebsd.h +81 -0
- data/ext/libuv/src/unix/eio/config_linux.h +94 -0
- data/ext/libuv/src/unix/eio/config_netbsd.h +81 -0
- data/ext/libuv/src/unix/eio/config_openbsd.h +137 -0
- data/ext/libuv/src/unix/eio/config_sunos.h +84 -0
- data/ext/libuv/src/unix/eio/configure.ac +22 -0
- data/ext/libuv/src/unix/eio/demo.c +194 -0
- data/ext/libuv/src/unix/eio/ecb.h +370 -0
- data/ext/libuv/src/unix/eio/eio.3 +3428 -0
- data/ext/libuv/src/unix/eio/eio.c +2593 -0
- data/ext/libuv/src/unix/eio/eio.pod +969 -0
- data/ext/libuv/src/unix/eio/libeio.m4 +195 -0
- data/ext/libuv/src/unix/eio/xthread.h +164 -0
- data/ext/libuv/src/unix/error.c +105 -0
- data/ext/libuv/src/unix/ev/Changes +388 -0
- data/ext/libuv/src/unix/ev/LICENSE +36 -0
- data/ext/libuv/src/unix/ev/Makefile.am +18 -0
- data/ext/libuv/src/unix/ev/Makefile.in +771 -0
- data/ext/libuv/src/unix/ev/README +58 -0
- data/ext/libuv/src/unix/ev/aclocal.m4 +8957 -0
- data/ext/libuv/src/unix/ev/autogen.sh +6 -0
- data/ext/libuv/src/unix/ev/config.guess +1526 -0
- data/ext/libuv/src/unix/ev/config.h.in +125 -0
- data/ext/libuv/src/unix/ev/config.sub +1658 -0
- data/ext/libuv/src/unix/ev/config_cygwin.h +123 -0
- data/ext/libuv/src/unix/ev/config_darwin.h +122 -0
- data/ext/libuv/src/unix/ev/config_freebsd.h +120 -0
- data/ext/libuv/src/unix/ev/config_linux.h +141 -0
- data/ext/libuv/src/unix/ev/config_netbsd.h +120 -0
- data/ext/libuv/src/unix/ev/config_openbsd.h +126 -0
- data/ext/libuv/src/unix/ev/config_sunos.h +122 -0
- data/ext/libuv/src/unix/ev/configure +13037 -0
- data/ext/libuv/src/unix/ev/configure.ac +18 -0
- data/ext/libuv/src/unix/ev/depcomp +630 -0
- data/ext/libuv/src/unix/ev/ev++.h +816 -0
- data/ext/libuv/src/unix/ev/ev.3 +5311 -0
- data/ext/libuv/src/unix/ev/ev.c +3925 -0
- data/ext/libuv/src/unix/ev/ev.pod +5243 -0
- data/ext/libuv/src/unix/ev/ev_epoll.c +266 -0
- data/ext/libuv/src/unix/ev/ev_kqueue.c +235 -0
- data/ext/libuv/src/unix/ev/ev_poll.c +148 -0
- data/ext/libuv/src/unix/ev/ev_port.c +179 -0
- data/ext/libuv/src/unix/ev/ev_select.c +310 -0
- data/ext/libuv/src/unix/ev/ev_vars.h +203 -0
- data/ext/libuv/src/unix/ev/ev_win32.c +153 -0
- data/ext/libuv/src/unix/ev/ev_wrap.h +196 -0
- data/ext/libuv/src/unix/ev/event.c +402 -0
- data/ext/libuv/src/unix/ev/event.h +170 -0
- data/ext/libuv/src/unix/ev/install-sh +294 -0
- data/ext/libuv/src/unix/ev/libev.m4 +39 -0
- data/ext/libuv/src/unix/ev/ltmain.sh +8413 -0
- data/ext/libuv/src/unix/ev/missing +336 -0
- data/ext/libuv/src/unix/ev/mkinstalldirs +111 -0
- data/ext/libuv/src/unix/freebsd.c +326 -0
- data/ext/libuv/src/unix/fs.c +739 -0
- data/ext/libuv/src/unix/internal.h +188 -0
- data/ext/libuv/src/unix/kqueue.c +120 -0
- data/ext/libuv/src/unix/linux/inotify.c +239 -0
- data/ext/libuv/src/unix/linux/linux-core.c +557 -0
- data/ext/libuv/src/unix/linux/syscalls.c +388 -0
- data/ext/libuv/src/unix/linux/syscalls.h +124 -0
- data/ext/libuv/src/unix/loop-watcher.c +62 -0
- data/ext/libuv/src/unix/loop.c +94 -0
- data/ext/libuv/src/unix/netbsd.c +108 -0
- data/ext/libuv/src/unix/openbsd.c +295 -0
- data/ext/libuv/src/unix/pipe.c +259 -0
- data/ext/libuv/src/unix/poll.c +114 -0
- data/ext/libuv/src/unix/process.c +495 -0
- data/ext/libuv/src/unix/signal.c +269 -0
- data/ext/libuv/src/unix/stream.c +990 -0
- data/ext/libuv/src/unix/sunos.c +481 -0
- data/ext/libuv/src/unix/tcp.c +393 -0
- data/ext/libuv/src/unix/thread.c +251 -0
- data/ext/libuv/src/unix/timer.c +136 -0
- data/ext/libuv/src/unix/tty.c +145 -0
- data/ext/libuv/src/unix/udp.c +659 -0
- data/ext/libuv/src/unix/uv-eio.c +107 -0
- data/ext/libuv/src/unix/uv-eio.h +13 -0
- data/ext/libuv/src/uv-common.c +380 -0
- data/ext/libuv/src/uv-common.h +170 -0
- data/ext/libuv/src/win/async.c +100 -0
- data/ext/libuv/src/win/atomicops-inl.h +56 -0
- data/ext/libuv/src/win/core.c +278 -0
- data/ext/libuv/src/win/dl.c +86 -0
- data/ext/libuv/src/win/error.c +155 -0
- data/ext/libuv/src/win/fs-event.c +510 -0
- data/ext/libuv/src/win/fs.c +1948 -0
- data/ext/libuv/src/win/getaddrinfo.c +365 -0
- data/ext/libuv/src/win/handle-inl.h +149 -0
- data/ext/libuv/src/win/handle.c +154 -0
- data/ext/libuv/src/win/internal.h +343 -0
- data/ext/libuv/src/win/loop-watcher.c +122 -0
- data/ext/libuv/src/win/pipe.c +1672 -0
- data/ext/libuv/src/win/poll.c +616 -0
- data/ext/libuv/src/win/process-stdio.c +500 -0
- data/ext/libuv/src/win/process.c +1013 -0
- data/ext/libuv/src/win/req-inl.h +220 -0
- data/ext/libuv/src/win/req.c +25 -0
- data/ext/libuv/src/win/signal.c +57 -0
- data/ext/libuv/src/win/stream-inl.h +67 -0
- data/ext/libuv/src/win/stream.c +167 -0
- data/ext/libuv/src/win/tcp.c +1394 -0
- data/ext/libuv/src/win/thread.c +372 -0
- data/ext/libuv/src/win/threadpool.c +74 -0
- data/ext/libuv/src/win/timer.c +224 -0
- data/ext/libuv/src/win/tty.c +1799 -0
- data/ext/libuv/src/win/udp.c +716 -0
- data/ext/libuv/src/win/util.c +864 -0
- data/ext/libuv/src/win/winapi.c +132 -0
- data/ext/libuv/src/win/winapi.h +4452 -0
- data/ext/libuv/src/win/winsock.c +557 -0
- data/ext/libuv/src/win/winsock.h +171 -0
- data/ext/libuv/test/benchmark-async-pummel.c +97 -0
- data/ext/libuv/test/benchmark-async.c +137 -0
- data/ext/libuv/test/benchmark-fs-stat.c +135 -0
- data/ext/libuv/test/benchmark-getaddrinfo.c +94 -0
- data/ext/libuv/test/benchmark-list.h +127 -0
- data/ext/libuv/test/benchmark-loop-count.c +88 -0
- data/ext/libuv/test/benchmark-million-timers.c +65 -0
- data/ext/libuv/test/benchmark-ping-pongs.c +213 -0
- data/ext/libuv/test/benchmark-pound.c +324 -0
- data/ext/libuv/test/benchmark-pump.c +462 -0
- data/ext/libuv/test/benchmark-sizes.c +44 -0
- data/ext/libuv/test/benchmark-spawn.c +162 -0
- data/ext/libuv/test/benchmark-tcp-write-batch.c +140 -0
- data/ext/libuv/test/benchmark-thread.c +64 -0
- data/ext/libuv/test/benchmark-udp-packet-storm.c +247 -0
- data/ext/libuv/test/blackhole-server.c +118 -0
- data/ext/libuv/test/dns-server.c +321 -0
- data/ext/libuv/test/echo-server.c +378 -0
- data/ext/libuv/test/fixtures/empty_file +0 -0
- data/ext/libuv/test/fixtures/load_error.node +1 -0
- data/ext/libuv/test/run-benchmarks.c +64 -0
- data/ext/libuv/test/run-tests.c +138 -0
- data/ext/libuv/test/runner-unix.c +295 -0
- data/ext/libuv/test/runner-unix.h +36 -0
- data/ext/libuv/test/runner-win.c +285 -0
- data/ext/libuv/test/runner-win.h +42 -0
- data/ext/libuv/test/runner.c +355 -0
- data/ext/libuv/test/runner.h +159 -0
- data/ext/libuv/test/task.h +112 -0
- data/ext/libuv/test/test-async.c +118 -0
- data/ext/libuv/test/test-callback-order.c +76 -0
- data/ext/libuv/test/test-callback-stack.c +203 -0
- data/ext/libuv/test/test-connection-fail.c +148 -0
- data/ext/libuv/test/test-cwd-and-chdir.c +64 -0
- data/ext/libuv/test/test-delayed-accept.c +188 -0
- data/ext/libuv/test/test-dlerror.c +58 -0
- data/ext/libuv/test/test-error.c +59 -0
- data/ext/libuv/test/test-fail-always.c +29 -0
- data/ext/libuv/test/test-fs-event.c +474 -0
- data/ext/libuv/test/test-fs-poll.c +146 -0
- data/ext/libuv/test/test-fs.c +1843 -0
- data/ext/libuv/test/test-get-currentexe.c +63 -0
- data/ext/libuv/test/test-get-loadavg.c +36 -0
- data/ext/libuv/test/test-get-memory.c +38 -0
- data/ext/libuv/test/test-getaddrinfo.c +122 -0
- data/ext/libuv/test/test-getsockname.c +342 -0
- data/ext/libuv/test/test-hrtime.c +54 -0
- data/ext/libuv/test/test-idle.c +81 -0
- data/ext/libuv/test/test-ipc-send-recv.c +209 -0
- data/ext/libuv/test/test-ipc.c +620 -0
- data/ext/libuv/test/test-list.h +427 -0
- data/ext/libuv/test/test-loop-handles.c +336 -0
- data/ext/libuv/test/test-multiple-listen.c +102 -0
- data/ext/libuv/test/test-mutexes.c +63 -0
- data/ext/libuv/test/test-pass-always.c +28 -0
- data/ext/libuv/test/test-ping-pong.c +253 -0
- data/ext/libuv/test/test-pipe-bind-error.c +140 -0
- data/ext/libuv/test/test-pipe-connect-error.c +96 -0
- data/ext/libuv/test/test-platform-output.c +87 -0
- data/ext/libuv/test/test-poll-close.c +72 -0
- data/ext/libuv/test/test-poll.c +573 -0
- data/ext/libuv/test/test-process-title.c +49 -0
- data/ext/libuv/test/test-ref.c +338 -0
- data/ext/libuv/test/test-run-once.c +48 -0
- data/ext/libuv/test/test-semaphore.c +111 -0
- data/ext/libuv/test/test-shutdown-close.c +103 -0
- data/ext/libuv/test/test-shutdown-eof.c +183 -0
- data/ext/libuv/test/test-signal.c +162 -0
- data/ext/libuv/test/test-spawn.c +863 -0
- data/ext/libuv/test/test-stdio-over-pipes.c +246 -0
- data/ext/libuv/test/test-tcp-bind-error.c +191 -0
- data/ext/libuv/test/test-tcp-bind6-error.c +154 -0
- data/ext/libuv/test/test-tcp-close-while-connecting.c +80 -0
- data/ext/libuv/test/test-tcp-close.c +129 -0
- data/ext/libuv/test/test-tcp-connect-error-after-write.c +95 -0
- data/ext/libuv/test/test-tcp-connect-error.c +70 -0
- data/ext/libuv/test/test-tcp-connect-timeout.c +85 -0
- data/ext/libuv/test/test-tcp-connect6-error.c +68 -0
- data/ext/libuv/test/test-tcp-flags.c +51 -0
- data/ext/libuv/test/test-tcp-shutdown-after-write.c +131 -0
- data/ext/libuv/test/test-tcp-unexpected-read.c +113 -0
- data/ext/libuv/test/test-tcp-write-error.c +168 -0
- data/ext/libuv/test/test-tcp-write-to-half-open-connection.c +135 -0
- data/ext/libuv/test/test-tcp-writealot.c +170 -0
- data/ext/libuv/test/test-thread.c +183 -0
- data/ext/libuv/test/test-threadpool.c +57 -0
- data/ext/libuv/test/test-timer-again.c +141 -0
- data/ext/libuv/test/test-timer.c +152 -0
- data/ext/libuv/test/test-tty.c +110 -0
- data/ext/libuv/test/test-udp-dgram-too-big.c +86 -0
- data/ext/libuv/test/test-udp-ipv6.c +156 -0
- data/ext/libuv/test/test-udp-multicast-join.c +139 -0
- data/ext/libuv/test/test-udp-multicast-ttl.c +86 -0
- data/ext/libuv/test/test-udp-options.c +86 -0
- data/ext/libuv/test/test-udp-send-and-recv.c +208 -0
- data/ext/libuv/test/test-util.c +97 -0
- data/ext/libuv/test/test-walk-handles.c +77 -0
- data/ext/libuv/uv.gyp +375 -0
- data/ext/libuv/vcbuild.bat +105 -0
- data/foolio.gemspec +18 -0
- data/lib/foolio.rb +9 -0
- data/lib/foolio/handle.rb +27 -0
- data/lib/foolio/listener.rb +26 -0
- data/lib/foolio/loop.rb +79 -0
- data/lib/foolio/stream.rb +109 -0
- data/lib/foolio/version.rb +3 -0
- metadata +309 -0
|
@@ -0,0 +1,500 @@
|
|
|
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 <assert.h>
|
|
23
|
+
#include <io.h>
|
|
24
|
+
#include <stdio.h>
|
|
25
|
+
#include <stdlib.h>
|
|
26
|
+
|
|
27
|
+
#include "uv.h"
|
|
28
|
+
#include "internal.h"
|
|
29
|
+
|
|
30
|
+
|
|
31
|
+
/*
|
|
32
|
+
* The `child_stdio_buffer` buffer has the following layout:
|
|
33
|
+
* int number_of_fds
|
|
34
|
+
* unsigned char crt_flags[number_of_fds]
|
|
35
|
+
* HANDLE os_handle[number_of_fds]
|
|
36
|
+
*/
|
|
37
|
+
#define CHILD_STDIO_SIZE(count) \
|
|
38
|
+
(sizeof(int) + \
|
|
39
|
+
sizeof(unsigned char) * (count) + \
|
|
40
|
+
sizeof(uintptr_t) * (count))
|
|
41
|
+
|
|
42
|
+
#define CHILD_STDIO_COUNT(buffer) \
|
|
43
|
+
*((unsigned int*) (buffer))
|
|
44
|
+
|
|
45
|
+
#define CHILD_STDIO_CRT_FLAGS(buffer, fd) \
|
|
46
|
+
*((unsigned char*) (buffer) + sizeof(int) + fd)
|
|
47
|
+
|
|
48
|
+
#define CHILD_STDIO_HANDLE(buffer, fd) \
|
|
49
|
+
*((HANDLE*) ((unsigned char*) (buffer) + \
|
|
50
|
+
sizeof(int) + \
|
|
51
|
+
sizeof(unsigned char) * \
|
|
52
|
+
CHILD_STDIO_COUNT((buffer)) + \
|
|
53
|
+
sizeof(HANDLE) * (fd)))
|
|
54
|
+
|
|
55
|
+
|
|
56
|
+
/* CRT file descriptor mode flags */
|
|
57
|
+
#define FOPEN 0x01
|
|
58
|
+
#define FEOFLAG 0x02
|
|
59
|
+
#define FCRLF 0x04
|
|
60
|
+
#define FPIPE 0x08
|
|
61
|
+
#define FNOINHERIT 0x10
|
|
62
|
+
#define FAPPEND 0x20
|
|
63
|
+
#define FDEV 0x40
|
|
64
|
+
#define FTEXT 0x80
|
|
65
|
+
|
|
66
|
+
|
|
67
|
+
/*
|
|
68
|
+
* Clear the HANDLE_FLAG_INHERIT flag from all HANDLEs that were inherited
|
|
69
|
+
* the parent process. Don't check for errors - the stdio handles may not be
|
|
70
|
+
* valid, or may be closed already. There is no guarantee that this function
|
|
71
|
+
* does a perfect job.
|
|
72
|
+
*/
|
|
73
|
+
void uv_disable_stdio_inheritance(void) {
|
|
74
|
+
HANDLE handle;
|
|
75
|
+
STARTUPINFOW si;
|
|
76
|
+
|
|
77
|
+
/* Make the windows stdio handles non-inheritable. */
|
|
78
|
+
handle = GetStdHandle(STD_INPUT_HANDLE);
|
|
79
|
+
if (handle != NULL && handle != INVALID_HANDLE_VALUE)
|
|
80
|
+
SetHandleInformation(handle, HANDLE_FLAG_INHERIT, 0);
|
|
81
|
+
|
|
82
|
+
handle = GetStdHandle(STD_OUTPUT_HANDLE);
|
|
83
|
+
if (handle != NULL && handle != INVALID_HANDLE_VALUE)
|
|
84
|
+
SetHandleInformation(handle, HANDLE_FLAG_INHERIT, 0);
|
|
85
|
+
|
|
86
|
+
handle = GetStdHandle(STD_ERROR_HANDLE);
|
|
87
|
+
if (handle != NULL && handle != INVALID_HANDLE_VALUE)
|
|
88
|
+
SetHandleInformation(handle, HANDLE_FLAG_INHERIT, 0);
|
|
89
|
+
|
|
90
|
+
/* Make inherited CRT FDs non-inheritable. */
|
|
91
|
+
GetStartupInfoW(&si);
|
|
92
|
+
if (uv__stdio_verify(si.lpReserved2, si.cbReserved2))
|
|
93
|
+
uv__stdio_noinherit(si.lpReserved2);
|
|
94
|
+
}
|
|
95
|
+
|
|
96
|
+
|
|
97
|
+
static uv_err_t uv__create_stdio_pipe_pair(uv_loop_t* loop,
|
|
98
|
+
uv_pipe_t* server_pipe, HANDLE* child_pipe_ptr, unsigned int flags) {
|
|
99
|
+
char pipe_name[64];
|
|
100
|
+
SECURITY_ATTRIBUTES sa;
|
|
101
|
+
DWORD server_access = 0;
|
|
102
|
+
DWORD client_access = 0;
|
|
103
|
+
HANDLE child_pipe = INVALID_HANDLE_VALUE;
|
|
104
|
+
uv_err_t err;
|
|
105
|
+
|
|
106
|
+
if (flags & UV_READABLE_PIPE) {
|
|
107
|
+
server_access |= PIPE_ACCESS_OUTBOUND;
|
|
108
|
+
client_access |= GENERIC_READ | FILE_WRITE_ATTRIBUTES;
|
|
109
|
+
}
|
|
110
|
+
if (flags & UV_WRITABLE_PIPE) {
|
|
111
|
+
server_access |= PIPE_ACCESS_INBOUND;
|
|
112
|
+
client_access |= GENERIC_WRITE;
|
|
113
|
+
}
|
|
114
|
+
|
|
115
|
+
/* Create server pipe handle. */
|
|
116
|
+
err = uv_stdio_pipe_server(loop,
|
|
117
|
+
server_pipe,
|
|
118
|
+
server_access,
|
|
119
|
+
pipe_name,
|
|
120
|
+
sizeof(pipe_name));
|
|
121
|
+
if (err.code != UV_OK)
|
|
122
|
+
goto error;
|
|
123
|
+
|
|
124
|
+
/* Create child pipe handle. */
|
|
125
|
+
sa.nLength = sizeof sa;
|
|
126
|
+
sa.lpSecurityDescriptor = NULL;
|
|
127
|
+
sa.bInheritHandle = TRUE;
|
|
128
|
+
|
|
129
|
+
child_pipe = CreateFileA(pipe_name,
|
|
130
|
+
client_access,
|
|
131
|
+
0,
|
|
132
|
+
&sa,
|
|
133
|
+
OPEN_EXISTING,
|
|
134
|
+
server_pipe->ipc ? FILE_FLAG_OVERLAPPED : 0,
|
|
135
|
+
NULL);
|
|
136
|
+
if (child_pipe == INVALID_HANDLE_VALUE) {
|
|
137
|
+
err = uv__new_sys_error(GetLastError());
|
|
138
|
+
goto error;
|
|
139
|
+
}
|
|
140
|
+
|
|
141
|
+
#ifndef NDEBUG
|
|
142
|
+
/* Validate that the pipe was opened in the right mode. */
|
|
143
|
+
{
|
|
144
|
+
DWORD mode;
|
|
145
|
+
BOOL r = GetNamedPipeHandleState(child_pipe,
|
|
146
|
+
&mode,
|
|
147
|
+
NULL,
|
|
148
|
+
NULL,
|
|
149
|
+
NULL,
|
|
150
|
+
NULL,
|
|
151
|
+
0);
|
|
152
|
+
assert(r == TRUE);
|
|
153
|
+
assert(mode == (PIPE_READMODE_BYTE | PIPE_WAIT));
|
|
154
|
+
}
|
|
155
|
+
#endif
|
|
156
|
+
|
|
157
|
+
/* Do a blocking ConnectNamedPipe. This should not block because we have */
|
|
158
|
+
/* both ends of the pipe created. */
|
|
159
|
+
if (!ConnectNamedPipe(server_pipe->handle, NULL)) {
|
|
160
|
+
if (GetLastError() != ERROR_PIPE_CONNECTED) {
|
|
161
|
+
err = uv__new_sys_error(GetLastError());
|
|
162
|
+
goto error;
|
|
163
|
+
}
|
|
164
|
+
}
|
|
165
|
+
|
|
166
|
+
*child_pipe_ptr = child_pipe;
|
|
167
|
+
return uv_ok_;
|
|
168
|
+
|
|
169
|
+
error:
|
|
170
|
+
if (server_pipe->handle != INVALID_HANDLE_VALUE) {
|
|
171
|
+
uv_pipe_cleanup(loop, server_pipe);
|
|
172
|
+
}
|
|
173
|
+
|
|
174
|
+
if (child_pipe != INVALID_HANDLE_VALUE) {
|
|
175
|
+
CloseHandle(child_pipe);
|
|
176
|
+
}
|
|
177
|
+
|
|
178
|
+
return err;
|
|
179
|
+
}
|
|
180
|
+
|
|
181
|
+
|
|
182
|
+
static int uv__duplicate_handle(uv_loop_t* loop, HANDLE handle, HANDLE* dup) {
|
|
183
|
+
HANDLE current_process;
|
|
184
|
+
|
|
185
|
+
|
|
186
|
+
/* _get_osfhandle will sometimes return -2 in case of an error. This seems */
|
|
187
|
+
/* to happen when fd <= 2 and the process' corresponding stdio handle is */
|
|
188
|
+
/* set to NULL. Unfortunately DuplicateHandle will happily duplicate /*
|
|
189
|
+
/* (HANDLE) -2, so this situation goes unnoticed until someone tries to */
|
|
190
|
+
/* use the duplicate. Therefore we filter out known-invalid handles here. */
|
|
191
|
+
if (handle == INVALID_HANDLE_VALUE ||
|
|
192
|
+
handle == NULL ||
|
|
193
|
+
handle == (HANDLE) -2) {
|
|
194
|
+
*dup = INVALID_HANDLE_VALUE;
|
|
195
|
+
uv__set_artificial_error(loop, UV_EBADF);
|
|
196
|
+
return -1;
|
|
197
|
+
}
|
|
198
|
+
|
|
199
|
+
current_process = GetCurrentProcess();
|
|
200
|
+
|
|
201
|
+
if (!DuplicateHandle(current_process,
|
|
202
|
+
handle,
|
|
203
|
+
current_process,
|
|
204
|
+
dup,
|
|
205
|
+
0,
|
|
206
|
+
TRUE,
|
|
207
|
+
DUPLICATE_SAME_ACCESS)) {
|
|
208
|
+
*dup = INVALID_HANDLE_VALUE;
|
|
209
|
+
uv__set_sys_error(loop, GetLastError());
|
|
210
|
+
return -1;
|
|
211
|
+
}
|
|
212
|
+
|
|
213
|
+
return 0;
|
|
214
|
+
}
|
|
215
|
+
|
|
216
|
+
|
|
217
|
+
static int uv__duplicate_fd(uv_loop_t* loop, int fd, HANDLE* dup) {
|
|
218
|
+
HANDLE handle;
|
|
219
|
+
|
|
220
|
+
if (fd == -1) {
|
|
221
|
+
*dup = INVALID_HANDLE_VALUE;
|
|
222
|
+
uv__set_artificial_error(loop, UV_EBADF);
|
|
223
|
+
return -1;
|
|
224
|
+
}
|
|
225
|
+
|
|
226
|
+
handle = (HANDLE) _get_osfhandle(fd);
|
|
227
|
+
return uv__duplicate_handle(loop, handle, dup);
|
|
228
|
+
}
|
|
229
|
+
|
|
230
|
+
|
|
231
|
+
uv_err_t uv__create_nul_handle(HANDLE* handle_ptr,
|
|
232
|
+
DWORD access) {
|
|
233
|
+
HANDLE handle;
|
|
234
|
+
SECURITY_ATTRIBUTES sa;
|
|
235
|
+
|
|
236
|
+
sa.nLength = sizeof sa;
|
|
237
|
+
sa.lpSecurityDescriptor = NULL;
|
|
238
|
+
sa.bInheritHandle = TRUE;
|
|
239
|
+
|
|
240
|
+
handle = CreateFileW(L"NUL",
|
|
241
|
+
access,
|
|
242
|
+
FILE_SHARE_READ | FILE_SHARE_WRITE,
|
|
243
|
+
&sa,
|
|
244
|
+
OPEN_EXISTING,
|
|
245
|
+
0,
|
|
246
|
+
NULL);
|
|
247
|
+
if (handle == INVALID_HANDLE_VALUE) {
|
|
248
|
+
return uv__new_sys_error(GetLastError());
|
|
249
|
+
}
|
|
250
|
+
|
|
251
|
+
*handle_ptr = handle;
|
|
252
|
+
return uv_ok_;
|
|
253
|
+
}
|
|
254
|
+
|
|
255
|
+
|
|
256
|
+
uv_err_t uv__stdio_create(uv_loop_t* loop, uv_process_options_t* options,
|
|
257
|
+
BYTE** buffer_ptr) {
|
|
258
|
+
BYTE* buffer;
|
|
259
|
+
int count, i;
|
|
260
|
+
uv_err_t err;
|
|
261
|
+
|
|
262
|
+
count = options->stdio_count;
|
|
263
|
+
|
|
264
|
+
if (count < 0 || count > 255) {
|
|
265
|
+
/* Only support FDs 0-255 */
|
|
266
|
+
return uv__new_artificial_error(UV_ENOTSUP);
|
|
267
|
+
} else if (count < 3) {
|
|
268
|
+
/* There should always be at least 3 stdio handles. */
|
|
269
|
+
count = 3;
|
|
270
|
+
}
|
|
271
|
+
|
|
272
|
+
/* Allocate the child stdio buffer */
|
|
273
|
+
buffer = (BYTE*) malloc(CHILD_STDIO_SIZE(count));
|
|
274
|
+
if (buffer == NULL) {
|
|
275
|
+
return uv__new_artificial_error(UV_ENOMEM);
|
|
276
|
+
}
|
|
277
|
+
|
|
278
|
+
/* Prepopulate the buffer with INVALID_HANDLE_VALUE handles so we can */
|
|
279
|
+
/* clean up on failure. */
|
|
280
|
+
CHILD_STDIO_COUNT(buffer) = count;
|
|
281
|
+
for (i = 0; i < count; i++) {
|
|
282
|
+
CHILD_STDIO_CRT_FLAGS(buffer, i) = 0;
|
|
283
|
+
CHILD_STDIO_HANDLE(buffer, i) = INVALID_HANDLE_VALUE;
|
|
284
|
+
}
|
|
285
|
+
|
|
286
|
+
for (i = 0; i < count; i++) {
|
|
287
|
+
uv_stdio_container_t fdopt;
|
|
288
|
+
if (i < options->stdio_count) {
|
|
289
|
+
fdopt = options->stdio[i];
|
|
290
|
+
} else {
|
|
291
|
+
fdopt.flags = UV_IGNORE;
|
|
292
|
+
}
|
|
293
|
+
|
|
294
|
+
switch (fdopt.flags & (UV_IGNORE | UV_CREATE_PIPE | UV_INHERIT_FD |
|
|
295
|
+
UV_INHERIT_STREAM)) {
|
|
296
|
+
case UV_IGNORE:
|
|
297
|
+
/* Starting a process with no stdin/stout/stderr can confuse it. */
|
|
298
|
+
/* So no matter what the user specified, we make sure the first */
|
|
299
|
+
/* three FDs are always open in their typical modes, e.g. stdin */
|
|
300
|
+
/* be readable and stdout/err should be writable. For FDs > 2, don't */
|
|
301
|
+
/* do anything - all handles in the stdio buffer are initialized with */
|
|
302
|
+
/* INVALID_HANDLE_VALUE, which should be okay. */
|
|
303
|
+
if (i <= 2) {
|
|
304
|
+
DWORD access = (i == 0) ? FILE_GENERIC_READ :
|
|
305
|
+
FILE_GENERIC_WRITE | FILE_READ_ATTRIBUTES;
|
|
306
|
+
|
|
307
|
+
err = uv__create_nul_handle(&CHILD_STDIO_HANDLE(buffer, i),
|
|
308
|
+
access);
|
|
309
|
+
if (err.code != UV_OK)
|
|
310
|
+
goto error;
|
|
311
|
+
|
|
312
|
+
CHILD_STDIO_CRT_FLAGS(buffer, i) = FOPEN | FDEV;
|
|
313
|
+
}
|
|
314
|
+
break;
|
|
315
|
+
|
|
316
|
+
case UV_CREATE_PIPE: {
|
|
317
|
+
/* Create a pair of two connected pipe ends; one end is turned into */
|
|
318
|
+
/* an uv_pipe_t for use by the parent. The other one is given to */
|
|
319
|
+
/* the child. */
|
|
320
|
+
uv_pipe_t* parent_pipe = (uv_pipe_t*) fdopt.data.stream;
|
|
321
|
+
HANDLE child_pipe;
|
|
322
|
+
|
|
323
|
+
/* Create a new, connected pipe pair. stdio[i].stream should point */
|
|
324
|
+
/* to an uninitialized, but not connected pipe handle. */
|
|
325
|
+
assert(fdopt.data.stream->type == UV_NAMED_PIPE);
|
|
326
|
+
assert(!(fdopt.data.stream->flags & UV_HANDLE_CONNECTION));
|
|
327
|
+
assert(!(fdopt.data.stream->flags & UV_HANDLE_PIPESERVER));
|
|
328
|
+
|
|
329
|
+
err = uv__create_stdio_pipe_pair(loop,
|
|
330
|
+
parent_pipe,
|
|
331
|
+
&child_pipe,
|
|
332
|
+
fdopt.flags);
|
|
333
|
+
if (err.code != UV_OK)
|
|
334
|
+
goto error;
|
|
335
|
+
|
|
336
|
+
CHILD_STDIO_HANDLE(buffer, i) = child_pipe;
|
|
337
|
+
CHILD_STDIO_CRT_FLAGS(buffer, i) = FOPEN | FPIPE;
|
|
338
|
+
break;
|
|
339
|
+
}
|
|
340
|
+
|
|
341
|
+
case UV_INHERIT_FD: {
|
|
342
|
+
/* Inherit a raw FD. */
|
|
343
|
+
HANDLE child_handle;
|
|
344
|
+
|
|
345
|
+
/* Make an inheritable duplicate of the handle. */
|
|
346
|
+
if (uv__duplicate_fd(loop, fdopt.data.fd, &child_handle) < 0) {
|
|
347
|
+
/* If fdopt.data.fd is not valid and fd fd <= 2, then ignore the */
|
|
348
|
+
/* error. */
|
|
349
|
+
if (fdopt.data.fd <= 2 && loop->last_err.code == UV_EBADF) {
|
|
350
|
+
CHILD_STDIO_CRT_FLAGS(buffer, i) = 0;
|
|
351
|
+
CHILD_STDIO_HANDLE(buffer, i) = INVALID_HANDLE_VALUE;
|
|
352
|
+
break;
|
|
353
|
+
}
|
|
354
|
+
goto error;
|
|
355
|
+
}
|
|
356
|
+
|
|
357
|
+
/* Figure out what the type is. */
|
|
358
|
+
switch (GetFileType(child_handle)) {
|
|
359
|
+
case FILE_TYPE_DISK:
|
|
360
|
+
CHILD_STDIO_CRT_FLAGS(buffer, i) = FOPEN;
|
|
361
|
+
break;
|
|
362
|
+
|
|
363
|
+
case FILE_TYPE_PIPE:
|
|
364
|
+
CHILD_STDIO_CRT_FLAGS(buffer, i) = FOPEN | FPIPE;
|
|
365
|
+
|
|
366
|
+
case FILE_TYPE_CHAR:
|
|
367
|
+
case FILE_TYPE_REMOTE:
|
|
368
|
+
CHILD_STDIO_CRT_FLAGS(buffer, i) = FOPEN | FDEV;
|
|
369
|
+
break;
|
|
370
|
+
|
|
371
|
+
case FILE_TYPE_UNKNOWN:
|
|
372
|
+
if (GetLastError() != 0) {
|
|
373
|
+
uv__set_sys_error(loop, GetLastError());
|
|
374
|
+
CloseHandle(child_handle);
|
|
375
|
+
goto error;
|
|
376
|
+
}
|
|
377
|
+
CHILD_STDIO_CRT_FLAGS(buffer, i) = FOPEN | FDEV;
|
|
378
|
+
break;
|
|
379
|
+
|
|
380
|
+
default:
|
|
381
|
+
assert(0);
|
|
382
|
+
}
|
|
383
|
+
|
|
384
|
+
CHILD_STDIO_HANDLE(buffer, i) = child_handle;
|
|
385
|
+
break;
|
|
386
|
+
}
|
|
387
|
+
|
|
388
|
+
case UV_INHERIT_STREAM: {
|
|
389
|
+
/* Use an existing stream as the stdio handle for the child. */
|
|
390
|
+
HANDLE stream_handle, child_handle;
|
|
391
|
+
unsigned char crt_flags;
|
|
392
|
+
uv_stream_t* stream = fdopt.data.stream;
|
|
393
|
+
|
|
394
|
+
/* Leech the handle out of the stream. */
|
|
395
|
+
if (stream->type == UV_TTY) {
|
|
396
|
+
stream_handle = ((uv_tty_t*) stream)->handle;
|
|
397
|
+
crt_flags = FOPEN | FDEV;
|
|
398
|
+
} else if (stream->type == UV_NAMED_PIPE &&
|
|
399
|
+
stream->flags & UV_HANDLE_CONNECTED) {
|
|
400
|
+
stream_handle = ((uv_pipe_t*) stream)->handle;
|
|
401
|
+
crt_flags = FOPEN | FPIPE;
|
|
402
|
+
} else {
|
|
403
|
+
stream_handle = INVALID_HANDLE_VALUE;
|
|
404
|
+
crt_flags = 0;
|
|
405
|
+
}
|
|
406
|
+
|
|
407
|
+
if (stream_handle == NULL ||
|
|
408
|
+
stream_handle == INVALID_HANDLE_VALUE) {
|
|
409
|
+
/* The handle is already closed, or not yet created, or the */
|
|
410
|
+
/* stream type is not supported. */
|
|
411
|
+
uv__set_artificial_error(loop, UV_ENOTSUP);
|
|
412
|
+
goto error;
|
|
413
|
+
}
|
|
414
|
+
|
|
415
|
+
/* Make an inheritable copy of the handle. */
|
|
416
|
+
if (uv__duplicate_handle(loop,
|
|
417
|
+
stream_handle,
|
|
418
|
+
&child_handle) < 0) {
|
|
419
|
+
goto error;
|
|
420
|
+
}
|
|
421
|
+
|
|
422
|
+
CHILD_STDIO_HANDLE(buffer, i) = child_handle;
|
|
423
|
+
CHILD_STDIO_CRT_FLAGS(buffer, i) = crt_flags;
|
|
424
|
+
break;
|
|
425
|
+
}
|
|
426
|
+
|
|
427
|
+
default:
|
|
428
|
+
assert(0);
|
|
429
|
+
}
|
|
430
|
+
}
|
|
431
|
+
|
|
432
|
+
*buffer_ptr = buffer;
|
|
433
|
+
return uv_ok_;
|
|
434
|
+
|
|
435
|
+
error:
|
|
436
|
+
uv__stdio_destroy(buffer);
|
|
437
|
+
return err;
|
|
438
|
+
}
|
|
439
|
+
|
|
440
|
+
|
|
441
|
+
void uv__stdio_destroy(BYTE* buffer) {
|
|
442
|
+
int i, count;
|
|
443
|
+
|
|
444
|
+
count = CHILD_STDIO_COUNT(buffer);
|
|
445
|
+
for (i = 0; i < count; i++) {
|
|
446
|
+
HANDLE handle = CHILD_STDIO_HANDLE(buffer, i);
|
|
447
|
+
if (handle != INVALID_HANDLE_VALUE) {
|
|
448
|
+
CloseHandle(handle);
|
|
449
|
+
}
|
|
450
|
+
}
|
|
451
|
+
|
|
452
|
+
free(buffer);
|
|
453
|
+
}
|
|
454
|
+
|
|
455
|
+
|
|
456
|
+
void uv__stdio_noinherit(BYTE* buffer) {
|
|
457
|
+
int i, count;
|
|
458
|
+
|
|
459
|
+
count = CHILD_STDIO_COUNT(buffer);
|
|
460
|
+
for (i = 0; i < count; i++) {
|
|
461
|
+
HANDLE handle = CHILD_STDIO_HANDLE(buffer, i);
|
|
462
|
+
if (handle != INVALID_HANDLE_VALUE) {
|
|
463
|
+
SetHandleInformation(handle, HANDLE_FLAG_INHERIT, 0);
|
|
464
|
+
}
|
|
465
|
+
}
|
|
466
|
+
}
|
|
467
|
+
|
|
468
|
+
|
|
469
|
+
int uv__stdio_verify(BYTE* buffer, WORD size) {
|
|
470
|
+
unsigned int count;
|
|
471
|
+
|
|
472
|
+
/* Check the buffer pointer. */
|
|
473
|
+
if (buffer == NULL)
|
|
474
|
+
return 0;
|
|
475
|
+
|
|
476
|
+
/* Verify that the buffer is at least big enough to hold the count. */
|
|
477
|
+
if (size < CHILD_STDIO_SIZE(0))
|
|
478
|
+
return 0;
|
|
479
|
+
|
|
480
|
+
/* Verify if the count is within range. */
|
|
481
|
+
count = CHILD_STDIO_COUNT(buffer);
|
|
482
|
+
if (count > 256)
|
|
483
|
+
return 0;
|
|
484
|
+
|
|
485
|
+
/* Verify that the buffer size is big enough to hold info for N FDs. */
|
|
486
|
+
if (size < CHILD_STDIO_SIZE(count))
|
|
487
|
+
return 0;
|
|
488
|
+
|
|
489
|
+
return 1;
|
|
490
|
+
}
|
|
491
|
+
|
|
492
|
+
|
|
493
|
+
WORD uv__stdio_size(BYTE* buffer) {
|
|
494
|
+
return (WORD) CHILD_STDIO_SIZE(CHILD_STDIO_COUNT((buffer)));
|
|
495
|
+
}
|
|
496
|
+
|
|
497
|
+
|
|
498
|
+
HANDLE uv__stdio_handle(BYTE* buffer, int fd) {
|
|
499
|
+
return CHILD_STDIO_HANDLE(buffer, fd);
|
|
500
|
+
}
|