rbuv 0.0.1 → 0.0.2

Sign up to get free protection for your applications and to get access to all the features.
Files changed (233) hide show
  1. checksums.yaml +4 -4
  2. data/.gitignore +5 -0
  3. data/.rspec +2 -0
  4. data/.travis.yml +5 -0
  5. data/Gemfile +0 -1
  6. data/README.md +6 -1
  7. data/Rakefile +42 -0
  8. data/deps/libuv/.gitignore +34 -0
  9. data/deps/libuv/.mailmap +16 -0
  10. data/deps/libuv/AUTHORS +81 -0
  11. data/deps/libuv/ChangeLog +45 -0
  12. data/deps/libuv/LICENSE +41 -0
  13. data/deps/libuv/Makefile +53 -0
  14. data/deps/libuv/README.md +118 -0
  15. data/deps/libuv/build.mk +164 -0
  16. data/deps/libuv/checksparse.sh +230 -0
  17. data/deps/libuv/common.gypi +197 -0
  18. data/deps/libuv/config-mingw.mk +48 -0
  19. data/deps/libuv/config-unix.mk +167 -0
  20. data/deps/libuv/gyp_uv +98 -0
  21. data/deps/libuv/include/uv-private/ngx-queue.h +129 -0
  22. data/deps/libuv/include/uv-private/stdint-msvc2008.h +247 -0
  23. data/deps/libuv/include/uv-private/tree.h +768 -0
  24. data/deps/libuv/include/uv-private/uv-bsd.h +34 -0
  25. data/deps/libuv/include/uv-private/uv-darwin.h +61 -0
  26. data/deps/libuv/include/uv-private/uv-linux.h +34 -0
  27. data/deps/libuv/include/uv-private/uv-sunos.h +44 -0
  28. data/deps/libuv/include/uv-private/uv-unix.h +332 -0
  29. data/deps/libuv/include/uv-private/uv-win.h +585 -0
  30. data/deps/libuv/include/uv.h +1987 -0
  31. data/deps/libuv/src/fs-poll.c +248 -0
  32. data/deps/libuv/src/inet.c +298 -0
  33. data/deps/libuv/src/unix/aix.c +393 -0
  34. data/deps/libuv/src/unix/async.c +281 -0
  35. data/deps/libuv/src/unix/core.c +714 -0
  36. data/deps/libuv/src/unix/cygwin.c +93 -0
  37. data/deps/libuv/src/unix/darwin-proctitle.m +78 -0
  38. data/deps/libuv/src/unix/darwin.c +431 -0
  39. data/deps/libuv/src/unix/dl.c +83 -0
  40. data/deps/libuv/src/unix/error.c +109 -0
  41. data/deps/libuv/src/unix/freebsd.c +343 -0
  42. data/deps/libuv/src/unix/fs.c +869 -0
  43. data/deps/libuv/src/unix/fsevents.c +299 -0
  44. data/deps/libuv/src/unix/getaddrinfo.c +159 -0
  45. data/deps/libuv/src/unix/internal.h +259 -0
  46. data/deps/libuv/src/unix/kqueue.c +347 -0
  47. data/deps/libuv/src/unix/linux-core.c +724 -0
  48. data/deps/libuv/src/unix/linux-inotify.c +236 -0
  49. data/deps/libuv/src/unix/linux-syscalls.c +388 -0
  50. data/deps/libuv/src/unix/linux-syscalls.h +150 -0
  51. data/deps/libuv/src/unix/loop-watcher.c +64 -0
  52. data/deps/libuv/src/unix/loop.c +114 -0
  53. data/deps/libuv/src/unix/netbsd.c +353 -0
  54. data/deps/libuv/src/unix/openbsd.c +304 -0
  55. data/deps/libuv/src/unix/pipe.c +261 -0
  56. data/deps/libuv/src/unix/poll.c +108 -0
  57. data/deps/libuv/src/unix/process.c +501 -0
  58. data/deps/libuv/src/unix/proctitle.c +103 -0
  59. data/deps/libuv/src/unix/signal.c +455 -0
  60. data/deps/libuv/src/unix/stream.c +1380 -0
  61. data/deps/libuv/src/unix/sunos.c +647 -0
  62. data/deps/libuv/src/unix/tcp.c +357 -0
  63. data/deps/libuv/src/unix/thread.c +431 -0
  64. data/deps/libuv/src/unix/threadpool.c +286 -0
  65. data/deps/libuv/src/unix/timer.c +153 -0
  66. data/deps/libuv/src/unix/tty.c +179 -0
  67. data/deps/libuv/src/unix/udp.c +715 -0
  68. data/deps/libuv/src/uv-common.c +431 -0
  69. data/deps/libuv/src/uv-common.h +204 -0
  70. data/deps/libuv/src/version.c +60 -0
  71. data/deps/libuv/src/win/async.c +99 -0
  72. data/deps/libuv/src/win/atomicops-inl.h +56 -0
  73. data/deps/libuv/src/win/core.c +310 -0
  74. data/deps/libuv/src/win/dl.c +86 -0
  75. data/deps/libuv/src/win/error.c +164 -0
  76. data/deps/libuv/src/win/fs-event.c +506 -0
  77. data/deps/libuv/src/win/fs.c +1951 -0
  78. data/deps/libuv/src/win/getaddrinfo.c +365 -0
  79. data/deps/libuv/src/win/handle-inl.h +164 -0
  80. data/deps/libuv/src/win/handle.c +153 -0
  81. data/deps/libuv/src/win/internal.h +346 -0
  82. data/deps/libuv/src/win/loop-watcher.c +124 -0
  83. data/deps/libuv/src/win/pipe.c +1656 -0
  84. data/deps/libuv/src/win/poll.c +615 -0
  85. data/deps/libuv/src/win/process-stdio.c +503 -0
  86. data/deps/libuv/src/win/process.c +1048 -0
  87. data/deps/libuv/src/win/req-inl.h +224 -0
  88. data/deps/libuv/src/win/req.c +25 -0
  89. data/deps/libuv/src/win/signal.c +354 -0
  90. data/deps/libuv/src/win/stream-inl.h +67 -0
  91. data/deps/libuv/src/win/stream.c +198 -0
  92. data/deps/libuv/src/win/tcp.c +1422 -0
  93. data/deps/libuv/src/win/thread.c +666 -0
  94. data/deps/libuv/src/win/threadpool.c +82 -0
  95. data/deps/libuv/src/win/timer.c +230 -0
  96. data/deps/libuv/src/win/tty.c +1857 -0
  97. data/deps/libuv/src/win/udp.c +744 -0
  98. data/deps/libuv/src/win/util.c +946 -0
  99. data/deps/libuv/src/win/winapi.c +152 -0
  100. data/deps/libuv/src/win/winapi.h +4476 -0
  101. data/deps/libuv/src/win/winsock.c +560 -0
  102. data/deps/libuv/src/win/winsock.h +171 -0
  103. data/deps/libuv/test/benchmark-async-pummel.c +119 -0
  104. data/deps/libuv/test/benchmark-async.c +139 -0
  105. data/deps/libuv/test/benchmark-fs-stat.c +136 -0
  106. data/deps/libuv/test/benchmark-getaddrinfo.c +91 -0
  107. data/deps/libuv/test/benchmark-list.h +163 -0
  108. data/deps/libuv/test/benchmark-loop-count.c +90 -0
  109. data/deps/libuv/test/benchmark-million-async.c +112 -0
  110. data/deps/libuv/test/benchmark-million-timers.c +77 -0
  111. data/deps/libuv/test/benchmark-multi-accept.c +432 -0
  112. data/deps/libuv/test/benchmark-ping-pongs.c +212 -0
  113. data/deps/libuv/test/benchmark-pound.c +325 -0
  114. data/deps/libuv/test/benchmark-pump.c +459 -0
  115. data/deps/libuv/test/benchmark-sizes.c +45 -0
  116. data/deps/libuv/test/benchmark-spawn.c +163 -0
  117. data/deps/libuv/test/benchmark-tcp-write-batch.c +141 -0
  118. data/deps/libuv/test/benchmark-thread.c +64 -0
  119. data/deps/libuv/test/benchmark-udp-pummel.c +238 -0
  120. data/deps/libuv/test/blackhole-server.c +118 -0
  121. data/deps/libuv/test/dns-server.c +329 -0
  122. data/deps/libuv/test/echo-server.c +384 -0
  123. data/deps/libuv/test/fixtures/empty_file +0 -0
  124. data/deps/libuv/test/fixtures/load_error.node +1 -0
  125. data/deps/libuv/test/run-benchmarks.c +64 -0
  126. data/deps/libuv/test/run-tests.c +159 -0
  127. data/deps/libuv/test/runner-unix.c +328 -0
  128. data/deps/libuv/test/runner-unix.h +36 -0
  129. data/deps/libuv/test/runner-win.c +318 -0
  130. data/deps/libuv/test/runner-win.h +43 -0
  131. data/deps/libuv/test/runner.c +394 -0
  132. data/deps/libuv/test/runner.h +165 -0
  133. data/deps/libuv/test/task.h +122 -0
  134. data/deps/libuv/test/test-active.c +83 -0
  135. data/deps/libuv/test/test-async.c +136 -0
  136. data/deps/libuv/test/test-barrier.c +98 -0
  137. data/deps/libuv/test/test-callback-order.c +77 -0
  138. data/deps/libuv/test/test-callback-stack.c +204 -0
  139. data/deps/libuv/test/test-condvar.c +173 -0
  140. data/deps/libuv/test/test-connection-fail.c +150 -0
  141. data/deps/libuv/test/test-cwd-and-chdir.c +64 -0
  142. data/deps/libuv/test/test-delayed-accept.c +189 -0
  143. data/deps/libuv/test/test-dlerror.c +58 -0
  144. data/deps/libuv/test/test-embed.c +136 -0
  145. data/deps/libuv/test/test-error.c +59 -0
  146. data/deps/libuv/test/test-fail-always.c +29 -0
  147. data/deps/libuv/test/test-fs-event.c +504 -0
  148. data/deps/libuv/test/test-fs-poll.c +148 -0
  149. data/deps/libuv/test/test-fs.c +1899 -0
  150. data/deps/libuv/test/test-get-currentexe.c +63 -0
  151. data/deps/libuv/test/test-get-loadavg.c +36 -0
  152. data/deps/libuv/test/test-get-memory.c +38 -0
  153. data/deps/libuv/test/test-getaddrinfo.c +120 -0
  154. data/deps/libuv/test/test-getsockname.c +344 -0
  155. data/deps/libuv/test/test-hrtime.c +54 -0
  156. data/deps/libuv/test/test-idle.c +82 -0
  157. data/deps/libuv/test/test-ipc-send-recv.c +218 -0
  158. data/deps/libuv/test/test-ipc.c +625 -0
  159. data/deps/libuv/test/test-list.h +492 -0
  160. data/deps/libuv/test/test-loop-handles.c +337 -0
  161. data/deps/libuv/test/test-loop-stop.c +73 -0
  162. data/deps/libuv/test/test-multiple-listen.c +103 -0
  163. data/deps/libuv/test/test-mutexes.c +63 -0
  164. data/deps/libuv/test/test-pass-always.c +28 -0
  165. data/deps/libuv/test/test-ping-pong.c +250 -0
  166. data/deps/libuv/test/test-pipe-bind-error.c +144 -0
  167. data/deps/libuv/test/test-pipe-connect-error.c +98 -0
  168. data/deps/libuv/test/test-platform-output.c +87 -0
  169. data/deps/libuv/test/test-poll-close.c +73 -0
  170. data/deps/libuv/test/test-poll.c +575 -0
  171. data/deps/libuv/test/test-process-title.c +49 -0
  172. data/deps/libuv/test/test-ref.c +415 -0
  173. data/deps/libuv/test/test-run-nowait.c +46 -0
  174. data/deps/libuv/test/test-run-once.c +49 -0
  175. data/deps/libuv/test/test-semaphore.c +111 -0
  176. data/deps/libuv/test/test-shutdown-close.c +105 -0
  177. data/deps/libuv/test/test-shutdown-eof.c +184 -0
  178. data/deps/libuv/test/test-signal-multiple-loops.c +270 -0
  179. data/deps/libuv/test/test-signal.c +152 -0
  180. data/deps/libuv/test/test-spawn.c +938 -0
  181. data/deps/libuv/test/test-stdio-over-pipes.c +250 -0
  182. data/deps/libuv/test/test-tcp-bind-error.c +198 -0
  183. data/deps/libuv/test/test-tcp-bind6-error.c +159 -0
  184. data/deps/libuv/test/test-tcp-close-while-connecting.c +81 -0
  185. data/deps/libuv/test/test-tcp-close.c +130 -0
  186. data/deps/libuv/test/test-tcp-connect-error-after-write.c +96 -0
  187. data/deps/libuv/test/test-tcp-connect-error.c +71 -0
  188. data/deps/libuv/test/test-tcp-connect-timeout.c +86 -0
  189. data/deps/libuv/test/test-tcp-connect6-error.c +69 -0
  190. data/deps/libuv/test/test-tcp-flags.c +52 -0
  191. data/deps/libuv/test/test-tcp-open.c +175 -0
  192. data/deps/libuv/test/test-tcp-read-stop.c +73 -0
  193. data/deps/libuv/test/test-tcp-shutdown-after-write.c +132 -0
  194. data/deps/libuv/test/test-tcp-unexpected-read.c +114 -0
  195. data/deps/libuv/test/test-tcp-write-to-half-open-connection.c +136 -0
  196. data/deps/libuv/test/test-tcp-writealot.c +171 -0
  197. data/deps/libuv/test/test-thread.c +183 -0
  198. data/deps/libuv/test/test-threadpool-cancel.c +311 -0
  199. data/deps/libuv/test/test-threadpool.c +77 -0
  200. data/deps/libuv/test/test-timer-again.c +142 -0
  201. data/deps/libuv/test/test-timer.c +266 -0
  202. data/deps/libuv/test/test-tty.c +111 -0
  203. data/deps/libuv/test/test-udp-dgram-too-big.c +87 -0
  204. data/deps/libuv/test/test-udp-ipv6.c +158 -0
  205. data/deps/libuv/test/test-udp-multicast-join.c +140 -0
  206. data/deps/libuv/test/test-udp-multicast-ttl.c +87 -0
  207. data/deps/libuv/test/test-udp-open.c +154 -0
  208. data/deps/libuv/test/test-udp-options.c +87 -0
  209. data/deps/libuv/test/test-udp-send-and-recv.c +210 -0
  210. data/deps/libuv/test/test-util.c +97 -0
  211. data/deps/libuv/test/test-walk-handles.c +78 -0
  212. data/deps/libuv/uv.gyp +431 -0
  213. data/deps/libuv/vcbuild.bat +128 -0
  214. data/ext/rbuv/debug.h +27 -0
  215. data/ext/rbuv/error.c +7 -0
  216. data/ext/rbuv/error.h +10 -0
  217. data/ext/rbuv/extconf.rb +35 -0
  218. data/ext/rbuv/handle.c +40 -0
  219. data/ext/rbuv/handle.h +14 -0
  220. data/ext/rbuv/libuv.mk +12 -0
  221. data/ext/rbuv/loop.c +50 -0
  222. data/ext/rbuv/loop.h +13 -0
  223. data/ext/rbuv/rbuv.c +15 -0
  224. data/ext/rbuv/rbuv.h +27 -0
  225. data/ext/rbuv/timer.c +133 -0
  226. data/ext/rbuv/timer.h +13 -0
  227. data/lib/rbuv/timer.rb +7 -0
  228. data/lib/rbuv/version.rb +1 -1
  229. data/lib/rbuv.rb +24 -2
  230. data/rbuv.gemspec +5 -1
  231. data/spec/spec_helper.rb +22 -0
  232. data/spec/timer_spec.rb +144 -0
  233. metadata +278 -9
@@ -0,0 +1,938 @@
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
+ #include <fcntl.h>
25
+ #include <stdio.h>
26
+ #include <stdlib.h>
27
+ #include <string.h>
28
+
29
+ #ifndef _WIN32
30
+ #include <unistd.h>
31
+ #endif
32
+
33
+
34
+ static int close_cb_called;
35
+ static int exit_cb_called;
36
+ static uv_process_t process;
37
+ static uv_timer_t timer;
38
+ static uv_process_options_t options;
39
+ static char exepath[1024];
40
+ static size_t exepath_size = 1024;
41
+ static char* args[3];
42
+ static int no_term_signal;
43
+
44
+ #define OUTPUT_SIZE 1024
45
+ static char output[OUTPUT_SIZE];
46
+ static int output_used;
47
+
48
+
49
+ static void close_cb(uv_handle_t* handle) {
50
+ printf("close_cb\n");
51
+ close_cb_called++;
52
+ }
53
+
54
+
55
+ static void exit_cb(uv_process_t* process, int exit_status, int term_signal) {
56
+ printf("exit_cb\n");
57
+ exit_cb_called++;
58
+ ASSERT(exit_status == 1);
59
+ ASSERT(term_signal == 0);
60
+ uv_close((uv_handle_t*)process, close_cb);
61
+ }
62
+
63
+
64
+ static void exit_cb_failure_expected(uv_process_t* process, int exit_status,
65
+ int term_signal) {
66
+ printf("exit_cb\n");
67
+ exit_cb_called++;
68
+ ASSERT(exit_status == -1);
69
+ ASSERT(term_signal == 0);
70
+ uv_close((uv_handle_t*)process, close_cb);
71
+ }
72
+
73
+
74
+ static void kill_cb(uv_process_t* process, int exit_status, int term_signal) {
75
+ uv_err_t err;
76
+
77
+ printf("exit_cb\n");
78
+ exit_cb_called++;
79
+ #ifdef _WIN32
80
+ ASSERT(exit_status == 1);
81
+ #else
82
+ ASSERT(exit_status == 0);
83
+ #endif
84
+ ASSERT(no_term_signal || term_signal == 15);
85
+ uv_close((uv_handle_t*)process, close_cb);
86
+
87
+ /*
88
+ * Sending signum == 0 should check if the
89
+ * child process is still alive, not kill it.
90
+ * This process should be dead.
91
+ */
92
+ err = uv_kill(process->pid, 0);
93
+ ASSERT(err.code == UV_ESRCH);
94
+ }
95
+
96
+ static void detach_failure_cb(uv_process_t* process, int exit_status, int term_signal) {
97
+ printf("detach_cb\n");
98
+ exit_cb_called++;
99
+ }
100
+
101
+ static uv_buf_t on_alloc(uv_handle_t* handle, size_t suggested_size) {
102
+ uv_buf_t buf;
103
+ buf.base = output + output_used;
104
+ buf.len = OUTPUT_SIZE - output_used;
105
+ return buf;
106
+ }
107
+
108
+
109
+ static void on_read(uv_stream_t* tcp, ssize_t nread, uv_buf_t buf) {
110
+ uv_err_t err = uv_last_error(uv_default_loop());
111
+
112
+ if (nread > 0) {
113
+ output_used += nread;
114
+ } else if (nread < 0) {
115
+ ASSERT(err.code == UV_EOF);
116
+ uv_close((uv_handle_t*)tcp, close_cb);
117
+ }
118
+ }
119
+
120
+
121
+ static void write_cb(uv_write_t* req, int status) {
122
+ ASSERT(status == 0);
123
+ uv_close((uv_handle_t*)req->handle, close_cb);
124
+ }
125
+
126
+
127
+ static void init_process_options(char* test, uv_exit_cb exit_cb) {
128
+ /* Note spawn_helper1 defined in test/run-tests.c */
129
+ int r = uv_exepath(exepath, &exepath_size);
130
+ ASSERT(r == 0);
131
+ exepath[exepath_size] = '\0';
132
+ args[0] = exepath;
133
+ args[1] = test;
134
+ args[2] = NULL;
135
+ options.file = exepath;
136
+ options.args = args;
137
+ options.exit_cb = exit_cb;
138
+ options.flags = 0;
139
+ }
140
+
141
+
142
+ static void timer_cb(uv_timer_t* handle, int status) {
143
+ uv_process_kill(&process, /* SIGTERM */ 15);
144
+ uv_close((uv_handle_t*)handle, close_cb);
145
+ }
146
+
147
+
148
+ TEST_IMPL(spawn_fails) {
149
+ init_process_options("", exit_cb_failure_expected);
150
+ options.file = options.args[0] = "program-that-had-better-not-exist";
151
+ ASSERT(0 == uv_spawn(uv_default_loop(), &process, options));
152
+ ASSERT(0 != uv_is_active((uv_handle_t*)&process));
153
+ ASSERT(0 == uv_run(uv_default_loop(), UV_RUN_DEFAULT));
154
+ ASSERT(uv_last_error(uv_default_loop()).code == UV_ENOENT);
155
+
156
+ MAKE_VALGRIND_HAPPY();
157
+ return 0;
158
+ }
159
+
160
+
161
+ TEST_IMPL(spawn_exit_code) {
162
+ int r;
163
+
164
+ init_process_options("spawn_helper1", exit_cb);
165
+
166
+ r = uv_spawn(uv_default_loop(), &process, options);
167
+ ASSERT(r == 0);
168
+
169
+ r = uv_run(uv_default_loop(), UV_RUN_DEFAULT);
170
+ ASSERT(r == 0);
171
+
172
+ ASSERT(exit_cb_called == 1);
173
+ ASSERT(close_cb_called == 1);
174
+
175
+ MAKE_VALGRIND_HAPPY();
176
+ return 0;
177
+ }
178
+
179
+
180
+ TEST_IMPL(spawn_stdout) {
181
+ int r;
182
+ uv_pipe_t out;
183
+ uv_stdio_container_t stdio[2];
184
+
185
+ init_process_options("spawn_helper2", exit_cb);
186
+
187
+ uv_pipe_init(uv_default_loop(), &out, 0);
188
+ options.stdio = stdio;
189
+ options.stdio[0].flags = UV_IGNORE;
190
+ options.stdio[1].flags = UV_CREATE_PIPE | UV_WRITABLE_PIPE;
191
+ options.stdio[1].data.stream = (uv_stream_t*)&out;
192
+ options.stdio_count = 2;
193
+
194
+ r = uv_spawn(uv_default_loop(), &process, options);
195
+ ASSERT(r == 0);
196
+
197
+ r = uv_read_start((uv_stream_t*) &out, on_alloc, on_read);
198
+ ASSERT(r == 0);
199
+
200
+ r = uv_run(uv_default_loop(), UV_RUN_DEFAULT);
201
+ ASSERT(r == 0);
202
+
203
+ ASSERT(exit_cb_called == 1);
204
+ ASSERT(close_cb_called == 2); /* Once for process once for the pipe. */
205
+ printf("output is: %s", output);
206
+ ASSERT(strcmp("hello world\n", output) == 0);
207
+
208
+ MAKE_VALGRIND_HAPPY();
209
+ return 0;
210
+ }
211
+
212
+
213
+ TEST_IMPL(spawn_stdout_to_file) {
214
+ int r;
215
+ uv_file file;
216
+ uv_fs_t fs_req;
217
+ uv_stdio_container_t stdio[2];
218
+
219
+ /* Setup. */
220
+ unlink("stdout_file");
221
+
222
+ init_process_options("spawn_helper2", exit_cb);
223
+
224
+ r = uv_fs_open(uv_default_loop(), &fs_req, "stdout_file", O_CREAT | O_RDWR,
225
+ S_IREAD | S_IWRITE, NULL);
226
+ ASSERT(r != -1);
227
+ uv_fs_req_cleanup(&fs_req);
228
+
229
+ file = r;
230
+
231
+ options.stdio = stdio;
232
+ options.stdio[0].flags = UV_IGNORE;
233
+ options.stdio[1].flags = UV_INHERIT_FD;
234
+ options.stdio[1].data.fd = file;
235
+ options.stdio_count = 2;
236
+
237
+ r = uv_spawn(uv_default_loop(), &process, options);
238
+ ASSERT(r == 0);
239
+
240
+ r = uv_run(uv_default_loop(), UV_RUN_DEFAULT);
241
+ ASSERT(r == 0);
242
+
243
+ ASSERT(exit_cb_called == 1);
244
+ ASSERT(close_cb_called == 1);
245
+
246
+ r = uv_fs_read(uv_default_loop(), &fs_req, file, output, sizeof(output),
247
+ 0, NULL);
248
+ ASSERT(r == 12);
249
+ uv_fs_req_cleanup(&fs_req);
250
+
251
+ r = uv_fs_close(uv_default_loop(), &fs_req, file, NULL);
252
+ ASSERT(r == 0);
253
+ uv_fs_req_cleanup(&fs_req);
254
+
255
+ printf("output is: %s", output);
256
+ ASSERT(strcmp("hello world\n", output) == 0);
257
+
258
+ /* Cleanup. */
259
+ unlink("stdout_file");
260
+
261
+ MAKE_VALGRIND_HAPPY();
262
+ return 0;
263
+ }
264
+
265
+
266
+ TEST_IMPL(spawn_stdin) {
267
+ int r;
268
+ uv_pipe_t out;
269
+ uv_pipe_t in;
270
+ uv_write_t write_req;
271
+ uv_buf_t buf;
272
+ uv_stdio_container_t stdio[2];
273
+ char buffer[] = "hello-from-spawn_stdin";
274
+
275
+ init_process_options("spawn_helper3", exit_cb);
276
+
277
+ uv_pipe_init(uv_default_loop(), &out, 0);
278
+ uv_pipe_init(uv_default_loop(), &in, 0);
279
+ options.stdio = stdio;
280
+ options.stdio[0].flags = UV_CREATE_PIPE | UV_READABLE_PIPE;
281
+ options.stdio[0].data.stream = (uv_stream_t*)&in;
282
+ options.stdio[1].flags = UV_CREATE_PIPE | UV_WRITABLE_PIPE;
283
+ options.stdio[1].data.stream = (uv_stream_t*)&out;
284
+ options.stdio_count = 2;
285
+
286
+ r = uv_spawn(uv_default_loop(), &process, options);
287
+ ASSERT(r == 0);
288
+
289
+ buf.base = buffer;
290
+ buf.len = sizeof(buffer);
291
+ r = uv_write(&write_req, (uv_stream_t*)&in, &buf, 1, write_cb);
292
+ ASSERT(r == 0);
293
+
294
+ r = uv_read_start((uv_stream_t*) &out, on_alloc, on_read);
295
+ ASSERT(r == 0);
296
+
297
+ r = uv_run(uv_default_loop(), UV_RUN_DEFAULT);
298
+ ASSERT(r == 0);
299
+
300
+ ASSERT(exit_cb_called == 1);
301
+ ASSERT(close_cb_called == 3); /* Once for process twice for the pipe. */
302
+ ASSERT(strcmp(buffer, output) == 0);
303
+
304
+ MAKE_VALGRIND_HAPPY();
305
+ return 0;
306
+ }
307
+
308
+
309
+ TEST_IMPL(spawn_stdio_greater_than_3) {
310
+ int r;
311
+ uv_pipe_t pipe;
312
+ uv_stdio_container_t stdio[4];
313
+
314
+ init_process_options("spawn_helper5", exit_cb);
315
+
316
+ uv_pipe_init(uv_default_loop(), &pipe, 0);
317
+ options.stdio = stdio;
318
+ options.stdio[0].flags = UV_IGNORE;
319
+ options.stdio[1].flags = UV_IGNORE;
320
+ options.stdio[2].flags = UV_IGNORE;
321
+ options.stdio[3].flags = UV_CREATE_PIPE | UV_WRITABLE_PIPE;
322
+ options.stdio[3].data.stream = (uv_stream_t*)&pipe;
323
+ options.stdio_count = 4;
324
+
325
+ r = uv_spawn(uv_default_loop(), &process, options);
326
+ ASSERT(r == 0);
327
+
328
+ r = uv_read_start((uv_stream_t*) &pipe, on_alloc, on_read);
329
+ ASSERT(r == 0);
330
+
331
+ r = uv_run(uv_default_loop(), UV_RUN_DEFAULT);
332
+ ASSERT(r == 0);
333
+
334
+ ASSERT(exit_cb_called == 1);
335
+ ASSERT(close_cb_called == 2); /* Once for process once for the pipe. */
336
+ printf("output from stdio[3] is: %s", output);
337
+ ASSERT(strcmp("fourth stdio!\n", output) == 0);
338
+
339
+ MAKE_VALGRIND_HAPPY();
340
+ return 0;
341
+ }
342
+
343
+
344
+ TEST_IMPL(spawn_ignored_stdio) {
345
+ int r;
346
+
347
+ init_process_options("spawn_helper6", exit_cb);
348
+
349
+ options.stdio = NULL;
350
+ options.stdio_count = 0;
351
+
352
+ r = uv_spawn(uv_default_loop(), &process, options);
353
+ ASSERT(r == 0);
354
+
355
+ r = uv_run(uv_default_loop(), UV_RUN_DEFAULT);
356
+ ASSERT(r == 0);
357
+
358
+ ASSERT(exit_cb_called == 1);
359
+ ASSERT(close_cb_called == 1);
360
+
361
+ MAKE_VALGRIND_HAPPY();
362
+ return 0;
363
+ }
364
+
365
+
366
+ TEST_IMPL(spawn_and_kill) {
367
+ int r;
368
+
369
+ init_process_options("spawn_helper4", kill_cb);
370
+
371
+ r = uv_spawn(uv_default_loop(), &process, options);
372
+ ASSERT(r == 0);
373
+
374
+ r = uv_timer_init(uv_default_loop(), &timer);
375
+ ASSERT(r == 0);
376
+
377
+ r = uv_timer_start(&timer, timer_cb, 500, 0);
378
+ ASSERT(r == 0);
379
+
380
+ r = uv_run(uv_default_loop(), UV_RUN_DEFAULT);
381
+ ASSERT(r == 0);
382
+
383
+ ASSERT(exit_cb_called == 1);
384
+ ASSERT(close_cb_called == 2); /* Once for process and once for timer. */
385
+
386
+ MAKE_VALGRIND_HAPPY();
387
+ return 0;
388
+ }
389
+
390
+
391
+ TEST_IMPL(spawn_preserve_env) {
392
+ int r;
393
+ uv_pipe_t out;
394
+ uv_stdio_container_t stdio[2];
395
+
396
+ init_process_options("spawn_helper7", exit_cb);
397
+
398
+ uv_pipe_init(uv_default_loop(), &out, 0);
399
+ options.stdio = stdio;
400
+ options.stdio[0].flags = UV_IGNORE;
401
+ options.stdio[1].flags = UV_CREATE_PIPE | UV_WRITABLE_PIPE;
402
+ options.stdio[1].data.stream = (uv_stream_t*) &out;
403
+ options.stdio_count = 2;
404
+
405
+ r = putenv("ENV_TEST=testval");
406
+ ASSERT(r == 0);
407
+
408
+ /* Explicitly set options.env to NULL to test for env clobbering. */
409
+ options.env = NULL;
410
+
411
+ r = uv_spawn(uv_default_loop(), &process, options);
412
+ ASSERT(r == 0);
413
+
414
+ r = uv_read_start((uv_stream_t*) &out, on_alloc, on_read);
415
+ ASSERT(r == 0);
416
+
417
+ r = uv_run(uv_default_loop(), UV_RUN_DEFAULT);
418
+ ASSERT(r == 0);
419
+
420
+ ASSERT(exit_cb_called == 1);
421
+ ASSERT(close_cb_called == 2);
422
+
423
+ printf("output is: %s", output);
424
+ ASSERT(strcmp("testval", output) == 0);
425
+
426
+ MAKE_VALGRIND_HAPPY();
427
+ return 0;
428
+ }
429
+
430
+
431
+ TEST_IMPL(spawn_detached) {
432
+ int r;
433
+ uv_err_t err;
434
+
435
+ init_process_options("spawn_helper4", detach_failure_cb);
436
+
437
+ options.flags |= UV_PROCESS_DETACHED;
438
+
439
+ r = uv_spawn(uv_default_loop(), &process, options);
440
+ ASSERT(r == 0);
441
+
442
+ uv_unref((uv_handle_t*)&process);
443
+
444
+ r = uv_run(uv_default_loop(), UV_RUN_DEFAULT);
445
+ ASSERT(r == 0);
446
+
447
+ ASSERT(exit_cb_called == 0);
448
+
449
+ err = uv_kill(process.pid, 0);
450
+ ASSERT(err.code == 0);
451
+
452
+ err = uv_kill(process.pid, 15);
453
+ ASSERT(err.code == 0);
454
+
455
+ MAKE_VALGRIND_HAPPY();
456
+ return 0;
457
+ }
458
+
459
+ TEST_IMPL(spawn_and_kill_with_std) {
460
+ int r;
461
+ uv_pipe_t in, out, err;
462
+ uv_write_t write;
463
+ char message[] = "Nancy's joining me because the message this evening is "
464
+ "not my message but ours.";
465
+ uv_buf_t buf;
466
+ uv_stdio_container_t stdio[3];
467
+
468
+ init_process_options("spawn_helper4", kill_cb);
469
+
470
+ r = uv_pipe_init(uv_default_loop(), &in, 0);
471
+ ASSERT(r == 0);
472
+
473
+ r = uv_pipe_init(uv_default_loop(), &out, 0);
474
+ ASSERT(r == 0);
475
+
476
+ r = uv_pipe_init(uv_default_loop(), &err, 0);
477
+ ASSERT(r == 0);
478
+
479
+ options.stdio = stdio;
480
+ options.stdio[0].flags = UV_CREATE_PIPE | UV_READABLE_PIPE;
481
+ options.stdio[0].data.stream = (uv_stream_t*)&in;
482
+ options.stdio[1].flags = UV_CREATE_PIPE | UV_WRITABLE_PIPE;
483
+ options.stdio[1].data.stream = (uv_stream_t*)&out;
484
+ options.stdio[2].flags = UV_CREATE_PIPE | UV_WRITABLE_PIPE;
485
+ options.stdio[2].data.stream = (uv_stream_t*)&err;
486
+ options.stdio_count = 3;
487
+
488
+ r = uv_spawn(uv_default_loop(), &process, options);
489
+ ASSERT(r == 0);
490
+
491
+ buf = uv_buf_init(message, sizeof message);
492
+ r = uv_write(&write, (uv_stream_t*) &in, &buf, 1, write_cb);
493
+ ASSERT(r == 0);
494
+
495
+ r = uv_read_start((uv_stream_t*) &out, on_alloc, on_read);
496
+ ASSERT(r == 0);
497
+
498
+ r = uv_read_start((uv_stream_t*) &err, on_alloc, on_read);
499
+ ASSERT(r == 0);
500
+
501
+ r = uv_timer_init(uv_default_loop(), &timer);
502
+ ASSERT(r == 0);
503
+
504
+ r = uv_timer_start(&timer, timer_cb, 500, 0);
505
+ ASSERT(r == 0);
506
+
507
+ r = uv_run(uv_default_loop(), UV_RUN_DEFAULT);
508
+ ASSERT(r == 0);
509
+
510
+ ASSERT(exit_cb_called == 1);
511
+ ASSERT(close_cb_called == 5); /* process x 1, timer x 1, stdio x 3. */
512
+
513
+ MAKE_VALGRIND_HAPPY();
514
+ return 0;
515
+ }
516
+
517
+
518
+ TEST_IMPL(spawn_and_ping) {
519
+ uv_write_t write_req;
520
+ uv_pipe_t in, out;
521
+ uv_buf_t buf;
522
+ uv_stdio_container_t stdio[2];
523
+ int r;
524
+
525
+ init_process_options("spawn_helper3", exit_cb);
526
+ buf = uv_buf_init("TEST", 4);
527
+
528
+ uv_pipe_init(uv_default_loop(), &out, 0);
529
+ uv_pipe_init(uv_default_loop(), &in, 0);
530
+ options.stdio = stdio;
531
+ options.stdio[0].flags = UV_CREATE_PIPE | UV_READABLE_PIPE;
532
+ options.stdio[0].data.stream = (uv_stream_t*)&in;
533
+ options.stdio[1].flags = UV_CREATE_PIPE | UV_WRITABLE_PIPE;
534
+ options.stdio[1].data.stream = (uv_stream_t*)&out;
535
+ options.stdio_count = 2;
536
+
537
+ r = uv_spawn(uv_default_loop(), &process, options);
538
+ ASSERT(r == 0);
539
+
540
+ /* Sending signum == 0 should check if the
541
+ * child process is still alive, not kill it.
542
+ */
543
+ r = uv_process_kill(&process, 0);
544
+ ASSERT(r == 0);
545
+
546
+ r = uv_write(&write_req, (uv_stream_t*)&in, &buf, 1, write_cb);
547
+ ASSERT(r == 0);
548
+
549
+ r = uv_read_start((uv_stream_t*)&out, on_alloc, on_read);
550
+ ASSERT(r == 0);
551
+
552
+ ASSERT(exit_cb_called == 0);
553
+
554
+ r = uv_run(uv_default_loop(), UV_RUN_DEFAULT);
555
+ ASSERT(r == 0);
556
+
557
+ ASSERT(exit_cb_called == 1);
558
+ ASSERT(strcmp(output, "TEST") == 0);
559
+
560
+ MAKE_VALGRIND_HAPPY();
561
+ return 0;
562
+ }
563
+
564
+
565
+ TEST_IMPL(kill) {
566
+ int r;
567
+ uv_err_t err;
568
+
569
+ #ifdef _WIN32
570
+ no_term_signal = 1;
571
+ #endif
572
+
573
+ init_process_options("spawn_helper4", kill_cb);
574
+
575
+ r = uv_spawn(uv_default_loop(), &process, options);
576
+ ASSERT(r == 0);
577
+
578
+ /* Sending signum == 0 should check if the
579
+ * child process is still alive, not kill it.
580
+ */
581
+ err = uv_kill(process.pid, 0);
582
+ ASSERT(err.code == UV_OK);
583
+
584
+ /* Kill the process. */
585
+ err = uv_kill(process.pid, /* SIGTERM */ 15);
586
+ ASSERT(err.code == UV_OK);
587
+
588
+ r = uv_run(uv_default_loop(), UV_RUN_DEFAULT);
589
+ ASSERT(r == 0);
590
+
591
+ ASSERT(exit_cb_called == 1);
592
+ ASSERT(close_cb_called == 1);
593
+
594
+ MAKE_VALGRIND_HAPPY();
595
+ return 0;
596
+ }
597
+
598
+
599
+ #ifdef _WIN32
600
+ TEST_IMPL(spawn_detect_pipe_name_collisions_on_windows) {
601
+ int r;
602
+ uv_pipe_t out;
603
+ char name[64];
604
+ HANDLE pipe_handle;
605
+ uv_stdio_container_t stdio[2];
606
+
607
+ init_process_options("spawn_helper2", exit_cb);
608
+
609
+ uv_pipe_init(uv_default_loop(), &out, 0);
610
+ options.stdio = stdio;
611
+ options.stdio[0].flags = UV_IGNORE;
612
+ options.stdio[1].flags = UV_CREATE_PIPE | UV_WRITABLE_PIPE;
613
+ options.stdio[1].data.stream = (uv_stream_t*)&out;
614
+ options.stdio_count = 2;
615
+
616
+ /* Create a pipe that'll cause a collision. */
617
+ _snprintf(name, sizeof(name), "\\\\.\\pipe\\uv\\%p-%d", &out, GetCurrentProcessId());
618
+ pipe_handle = CreateNamedPipeA(name,
619
+ PIPE_ACCESS_INBOUND | FILE_FLAG_OVERLAPPED,
620
+ PIPE_TYPE_BYTE | PIPE_READMODE_BYTE | PIPE_WAIT,
621
+ 10,
622
+ 65536,
623
+ 65536,
624
+ 0,
625
+ NULL);
626
+ ASSERT(pipe_handle != INVALID_HANDLE_VALUE);
627
+
628
+ r = uv_spawn(uv_default_loop(), &process, options);
629
+ ASSERT(r == 0);
630
+
631
+ r = uv_read_start((uv_stream_t*) &out, on_alloc, on_read);
632
+ ASSERT(r == 0);
633
+
634
+ r = uv_run(uv_default_loop(), UV_RUN_DEFAULT);
635
+ ASSERT(r == 0);
636
+
637
+ ASSERT(exit_cb_called == 1);
638
+ ASSERT(close_cb_called == 2); /* Once for process once for the pipe. */
639
+ printf("output is: %s", output);
640
+ ASSERT(strcmp("hello world\n", output) == 0);
641
+
642
+ MAKE_VALGRIND_HAPPY();
643
+ return 0;
644
+ }
645
+
646
+
647
+ uv_err_t make_program_args(char** args, int verbatim_arguments, WCHAR** dst_ptr);
648
+ WCHAR* quote_cmd_arg(const WCHAR *source, WCHAR *target);
649
+
650
+ TEST_IMPL(argument_escaping) {
651
+ const WCHAR* test_str[] = {
652
+ L"HelloWorld",
653
+ L"Hello World",
654
+ L"Hello\"World",
655
+ L"Hello World\\",
656
+ L"Hello\\\"World",
657
+ L"Hello\\World",
658
+ L"Hello\\\\World",
659
+ L"Hello World\\",
660
+ L"c:\\path\\to\\node.exe --eval \"require('c:\\\\path\\\\to\\\\test.js')\""
661
+ };
662
+ const int count = sizeof(test_str) / sizeof(*test_str);
663
+ WCHAR** test_output;
664
+ WCHAR* command_line;
665
+ WCHAR** cracked;
666
+ size_t total_size = 0;
667
+ int i;
668
+ int num_args;
669
+ uv_err_t result;
670
+
671
+ char* verbatim[] = {
672
+ "cmd.exe",
673
+ "/c",
674
+ "c:\\path\\to\\node.exe --eval \"require('c:\\\\path\\\\to\\\\test.js')\"",
675
+ NULL
676
+ };
677
+ WCHAR* verbatim_output;
678
+ WCHAR* non_verbatim_output;
679
+
680
+ test_output = calloc(count, sizeof(WCHAR*));
681
+ for (i = 0; i < count; ++i) {
682
+ test_output[i] = calloc(2 * (wcslen(test_str[i]) + 2), sizeof(WCHAR));
683
+ quote_cmd_arg(test_str[i], test_output[i]);
684
+ wprintf(L"input : %s\n", test_str[i]);
685
+ wprintf(L"output: %s\n", test_output[i]);
686
+ total_size += wcslen(test_output[i]) + 1;
687
+ }
688
+ command_line = calloc(total_size + 1, sizeof(WCHAR));
689
+ for (i = 0; i < count; ++i) {
690
+ wcscat(command_line, test_output[i]);
691
+ wcscat(command_line, L" ");
692
+ }
693
+ command_line[total_size - 1] = L'\0';
694
+
695
+ wprintf(L"command_line: %s\n", command_line);
696
+
697
+ cracked = CommandLineToArgvW(command_line, &num_args);
698
+ for (i = 0; i < num_args; ++i) {
699
+ wprintf(L"%d: %s\t%s\n", i, test_str[i], cracked[i]);
700
+ ASSERT(wcscmp(test_str[i], cracked[i]) == 0);
701
+ }
702
+
703
+ LocalFree(cracked);
704
+ for (i = 0; i < count; ++i) {
705
+ free(test_output[i]);
706
+ }
707
+
708
+ result = make_program_args(verbatim, 1, &verbatim_output);
709
+ ASSERT(result.code == UV_OK);
710
+ result = make_program_args(verbatim, 0, &non_verbatim_output);
711
+ ASSERT(result.code == UV_OK);
712
+
713
+ wprintf(L" verbatim_output: %s\n", verbatim_output);
714
+ wprintf(L"non_verbatim_output: %s\n", non_verbatim_output);
715
+
716
+ ASSERT(wcscmp(verbatim_output, L"cmd.exe /c c:\\path\\to\\node.exe --eval \"require('c:\\\\path\\\\to\\\\test.js')\"") == 0);
717
+ ASSERT(wcscmp(non_verbatim_output, L"cmd.exe /c \"c:\\path\\to\\node.exe --eval \\\"require('c:\\\\path\\\\to\\\\test.js')\\\"\"") == 0);
718
+
719
+ free(verbatim_output);
720
+ free(non_verbatim_output);
721
+
722
+ return 0;
723
+ }
724
+
725
+ uv_err_t make_program_env(char** env_block, WCHAR** dst_ptr);
726
+
727
+ TEST_IMPL(environment_creation) {
728
+ int i;
729
+ char* environment[] = {
730
+ "FOO=BAR",
731
+ "SYSTEM=ROOT", /* substring of a supplied var name */
732
+ "SYSTEMROOTED=OMG", /* supplied var name is a substring */
733
+ "TEMP=C:\\Temp",
734
+ "BAZ=QUX",
735
+ NULL
736
+ };
737
+
738
+ WCHAR expected[512];
739
+ WCHAR* ptr = expected;
740
+ uv_err_t result;
741
+ WCHAR* str;
742
+ WCHAR* env;
743
+
744
+ for (i = 0; i < sizeof(environment) / sizeof(environment[0]) - 1; i++) {
745
+ ptr += uv_utf8_to_utf16(environment[i], ptr, expected + sizeof(expected) - ptr);
746
+ }
747
+
748
+ memcpy(ptr, L"SYSTEMROOT=", sizeof(L"SYSTEMROOT="));
749
+ ptr += sizeof(L"SYSTEMROOT=")/sizeof(WCHAR) - 1;
750
+ ptr += GetEnvironmentVariableW(L"SYSTEMROOT", ptr, expected + sizeof(expected) - ptr);
751
+ ++ptr;
752
+
753
+ memcpy(ptr, L"SYSTEMDRIVE=", sizeof(L"SYSTEMDRIVE="));
754
+ ptr += sizeof(L"SYSTEMDRIVE=")/sizeof(WCHAR) - 1;
755
+ ptr += GetEnvironmentVariableW(L"SYSTEMDRIVE", ptr, expected + sizeof(expected) - ptr);
756
+ ++ptr;
757
+ *ptr = '\0';
758
+
759
+ result = make_program_env(environment, &env);
760
+ ASSERT(result.code == UV_OK);
761
+
762
+ for (str = env; *str; str += wcslen(str) + 1) {
763
+ wprintf(L"%s\n", str);
764
+ }
765
+
766
+ ASSERT(wcscmp(expected, env) == 0);
767
+
768
+ return 0;
769
+ }
770
+ #endif
771
+
772
+ #ifndef _WIN32
773
+ TEST_IMPL(spawn_setuid_setgid) {
774
+ int r;
775
+
776
+ /* if not root, then this will fail. */
777
+ uv_uid_t uid = getuid();
778
+ if (uid != 0) {
779
+ fprintf(stderr, "spawn_setuid_setgid skipped: not root\n");
780
+ return 0;
781
+ }
782
+
783
+ init_process_options("spawn_helper1", exit_cb);
784
+
785
+ /* become the "nobody" user. */
786
+ struct passwd* pw;
787
+ pw = getpwnam("nobody");
788
+ ASSERT(pw != NULL);
789
+ options.uid = pw->pw_uid;
790
+ options.gid = pw->pw_gid;
791
+ options.flags = UV_PROCESS_SETUID | UV_PROCESS_SETGID;
792
+
793
+ r = uv_spawn(uv_default_loop(), &process, options);
794
+ ASSERT(r == 0);
795
+
796
+ r = uv_run(uv_default_loop(), UV_RUN_DEFAULT);
797
+ ASSERT(r == 0);
798
+
799
+ ASSERT(exit_cb_called == 1);
800
+ ASSERT(close_cb_called == 1);
801
+
802
+ MAKE_VALGRIND_HAPPY();
803
+ return 0;
804
+ }
805
+ #endif
806
+
807
+
808
+ #ifndef _WIN32
809
+ TEST_IMPL(spawn_setuid_fails) {
810
+ int r;
811
+
812
+ /* if root, become nobody. */
813
+ uv_uid_t uid = getuid();
814
+ if (uid == 0) {
815
+ struct passwd* pw;
816
+ pw = getpwnam("nobody");
817
+ ASSERT(pw != NULL);
818
+ r = setuid(pw->pw_uid);
819
+ ASSERT(r == 0);
820
+ }
821
+
822
+ init_process_options("spawn_helper1", exit_cb_failure_expected);
823
+
824
+ options.flags |= UV_PROCESS_SETUID;
825
+ options.uid = (uv_uid_t) -42424242;
826
+
827
+ r = uv_spawn(uv_default_loop(), &process, options);
828
+ ASSERT(r == 0);
829
+
830
+ r = uv_run(uv_default_loop(), UV_RUN_DEFAULT);
831
+ ASSERT(r == 0);
832
+
833
+ ASSERT(exit_cb_called == 1);
834
+ ASSERT(close_cb_called == 1);
835
+
836
+ MAKE_VALGRIND_HAPPY();
837
+ return 0;
838
+ }
839
+
840
+
841
+ TEST_IMPL(spawn_setgid_fails) {
842
+ int r;
843
+
844
+ /* if root, become nobody. */
845
+ uv_uid_t uid = getuid();
846
+ if (uid == 0) {
847
+ struct passwd* pw;
848
+ pw = getpwnam("nobody");
849
+ ASSERT(pw != NULL);
850
+ r = setuid(pw->pw_uid);
851
+ ASSERT(r == 0);
852
+ }
853
+
854
+ init_process_options("spawn_helper1", exit_cb_failure_expected);
855
+
856
+ options.flags |= UV_PROCESS_SETGID;
857
+ options.gid = (uv_gid_t) -42424242;
858
+
859
+ r = uv_spawn(uv_default_loop(), &process, options);
860
+ ASSERT(r == 0);
861
+
862
+ r = uv_run(uv_default_loop(), UV_RUN_DEFAULT);
863
+ ASSERT(r == 0);
864
+
865
+ ASSERT(exit_cb_called == 1);
866
+ ASSERT(close_cb_called == 1);
867
+
868
+ MAKE_VALGRIND_HAPPY();
869
+ return 0;
870
+ }
871
+ #endif
872
+
873
+
874
+ #ifdef _WIN32
875
+
876
+ static void exit_cb_unexpected(uv_process_t* process,
877
+ int exit_status,
878
+ int term_signal) {
879
+ ASSERT(0 && "should not have been called");
880
+ }
881
+
882
+
883
+ TEST_IMPL(spawn_setuid_fails) {
884
+ int r;
885
+
886
+ init_process_options("spawn_helper1", exit_cb_unexpected);
887
+
888
+ options.flags |= UV_PROCESS_SETUID;
889
+ options.uid = (uv_uid_t) -42424242;
890
+
891
+ r = uv_spawn(uv_default_loop(), &process, options);
892
+ ASSERT(r == -1);
893
+ ASSERT(uv_last_error(uv_default_loop()).code == UV_ENOTSUP);
894
+
895
+ r = uv_run(uv_default_loop(), UV_RUN_DEFAULT);
896
+ ASSERT(r == 0);
897
+
898
+ ASSERT(close_cb_called == 0);
899
+
900
+ MAKE_VALGRIND_HAPPY();
901
+ return 0;
902
+ }
903
+
904
+
905
+ TEST_IMPL(spawn_setgid_fails) {
906
+ int r;
907
+
908
+ init_process_options("spawn_helper1", exit_cb_unexpected);
909
+
910
+ options.flags |= UV_PROCESS_SETGID;
911
+ options.gid = (uv_gid_t) -42424242;
912
+
913
+ r = uv_spawn(uv_default_loop(), &process, options);
914
+ ASSERT(r == -1);
915
+ ASSERT(uv_last_error(uv_default_loop()).code == UV_ENOTSUP);
916
+
917
+ r = uv_run(uv_default_loop(), UV_RUN_DEFAULT);
918
+ ASSERT(r == 0);
919
+
920
+ ASSERT(close_cb_called == 0);
921
+
922
+ MAKE_VALGRIND_HAPPY();
923
+ return 0;
924
+ }
925
+ #endif
926
+
927
+
928
+ TEST_IMPL(spawn_auto_unref) {
929
+ init_process_options("spawn_helper1", NULL);
930
+ ASSERT(0 == uv_spawn(uv_default_loop(), &process, options));
931
+ ASSERT(0 == uv_run(uv_default_loop(), UV_RUN_DEFAULT));
932
+ ASSERT(0 == uv_is_closing((uv_handle_t*) &process));
933
+ uv_close((uv_handle_t*) &process, NULL);
934
+ ASSERT(0 == uv_run(uv_default_loop(), UV_RUN_DEFAULT));
935
+ ASSERT(0 != uv_is_closing((uv_handle_t*) &process));
936
+ MAKE_VALGRIND_HAPPY();
937
+ return 0;
938
+ }