Home | History | Annotate | Line # | Download | only in test
      1 
      2 /* Copyright Joyent, Inc. and other Node contributors. All rights reserved.
      3  *
      4  * Permission is hereby granted, free of charge, to any person obtaining a copy
      5  * of this software and associated documentation files (the "Software"), to
      6  * deal in the Software without restriction, including without limitation the
      7  * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
      8  * sell copies of the Software, and to permit persons to whom the Software is
      9  * furnished to do so, subject to the following conditions:
     10  *
     11  * The above copyright notice and this permission notice shall be included in
     12  * all copies or substantial portions of the Software.
     13  *
     14  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
     15  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
     16  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
     17  * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
     18  * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
     19  * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
     20  * IN THE SOFTWARE.
     21  */
     22 
     23 #include "uv.h"
     24 #include "task.h"
     25 #include <errno.h>
     26 #include <fcntl.h>
     27 #include <stdio.h>
     28 #include <stdlib.h>
     29 #include <string.h>
     30 
     31 #ifdef _WIN32
     32 # include <shellapi.h>
     33 # include <wchar.h>
     34   typedef BOOL (WINAPI *sCompareObjectHandles)(_In_ HANDLE, _In_ HANDLE);
     35 # define unlink _unlink
     36 # define putenv _putenv
     37 # define close _close
     38 #else
     39 # include <unistd.h>
     40 # include <sys/wait.h>
     41 #endif
     42 
     43 
     44 static int close_cb_called;
     45 static int exit_cb_called;
     46 static uv_process_t process;
     47 static uv_timer_t timer;
     48 static uv_process_options_t options;
     49 static char exepath[1024];
     50 static size_t exepath_size = 1024;
     51 static char* args[5];
     52 static int no_term_signal;
     53 static int timer_counter;
     54 static uv_tcp_t tcp_server;
     55 
     56 #define OUTPUT_SIZE 1024
     57 static char output[OUTPUT_SIZE];
     58 static int output_used;
     59 
     60 
     61 static void close_cb(uv_handle_t* handle) {
     62   printf("close_cb\n");
     63   close_cb_called++;
     64 }
     65 
     66 static void exit_cb(uv_process_t* process,
     67                     int64_t exit_status,
     68                     int term_signal) {
     69   printf("exit_cb\n");
     70   exit_cb_called++;
     71   ASSERT_EQ(1, exit_status);
     72   ASSERT_OK(term_signal);
     73   uv_close((uv_handle_t*) process, close_cb);
     74 }
     75 
     76 
     77 static void fail_cb(uv_process_t* process,
     78                     int64_t exit_status,
     79                     int term_signal) {
     80   ASSERT(0 && "fail_cb called");
     81 }
     82 
     83 
     84 static void kill_cb(uv_process_t* process,
     85                     int64_t exit_status,
     86                     int term_signal) {
     87   int err;
     88 
     89   printf("exit_cb\n");
     90   exit_cb_called++;
     91 #ifdef _WIN32
     92   ASSERT_EQ(1, exit_status);
     93 #else
     94   ASSERT_OK(exit_status);
     95 #endif
     96 #if defined(__APPLE__) || defined(__MVS__)
     97   /*
     98    * At least starting with Darwin Kernel Version 16.4.0, sending a SIGTERM to a
     99    * process that is still starting up kills it with SIGKILL instead of SIGTERM.
    100    * See: https://github.com/libuv/libuv/issues/1226
    101    */
    102   ASSERT(no_term_signal || term_signal == SIGTERM || term_signal == SIGKILL);
    103 #else
    104   ASSERT(no_term_signal || term_signal == SIGTERM);
    105 #endif
    106   uv_close((uv_handle_t*) process, close_cb);
    107 
    108   /*
    109    * Sending signum == 0 should check if the
    110    * child process is still alive, not kill it.
    111    * This process should be dead.
    112    */
    113   err = uv_kill(process->pid, 0);
    114   ASSERT_EQ(err, UV_ESRCH);
    115 }
    116 
    117 static void detach_failure_cb(uv_process_t* process,
    118                               int64_t exit_status,
    119                               int term_signal) {
    120   printf("detach_cb\n");
    121   exit_cb_called++;
    122 }
    123 
    124 static void on_alloc(uv_handle_t* handle,
    125                      size_t suggested_size,
    126                      uv_buf_t* buf) {
    127   buf->base = output + output_used;
    128   buf->len = OUTPUT_SIZE - output_used;
    129 }
    130 
    131 
    132 static void on_read(uv_stream_t* tcp, ssize_t nread, const uv_buf_t* buf) {
    133   if (nread > 0) {
    134     output_used += nread;
    135   } else if (nread < 0) {
    136     ASSERT_EQ(nread, UV_EOF);
    137     uv_close((uv_handle_t*) tcp, close_cb);
    138   }
    139 }
    140 
    141 
    142 static void on_read_once(uv_stream_t* tcp, ssize_t nread, const uv_buf_t* buf) {
    143   uv_read_stop(tcp);
    144   on_read(tcp, nread, buf);
    145 }
    146 
    147 
    148 static void write_cb(uv_write_t* req, int status) {
    149   ASSERT_OK(status);
    150   uv_close((uv_handle_t*) req->handle, close_cb);
    151 }
    152 
    153 
    154 static void write_null_cb(uv_write_t* req, int status) {
    155   ASSERT_OK(status);
    156 }
    157 
    158 
    159 static void init_process_options(char* test, uv_exit_cb exit_cb) {
    160   /* Note spawn_helper1 defined in test/run-tests.c */
    161   int r = uv_exepath(exepath, &exepath_size);
    162   ASSERT_OK(r);
    163   exepath[exepath_size] = '\0';
    164   args[0] = exepath;
    165   args[1] = test;
    166   args[2] = NULL;
    167   args[3] = NULL;
    168   args[4] = NULL;
    169   options.file = exepath;
    170   options.args = args;
    171   options.exit_cb = exit_cb;
    172   options.flags = 0;
    173 }
    174 
    175 
    176 static void timer_cb(uv_timer_t* handle) {
    177   uv_process_kill(&process, SIGTERM);
    178   uv_close((uv_handle_t*) handle, close_cb);
    179 }
    180 
    181 
    182 static void timer_counter_cb(uv_timer_t* handle) {
    183   ++timer_counter;
    184 }
    185 
    186 
    187 TEST_IMPL(spawn_fails) {
    188   int r;
    189 
    190   init_process_options("", fail_cb);
    191   options.file = options.args[0] = "program-that-had-better-not-exist";
    192 
    193   r = uv_spawn(uv_default_loop(), &process, &options);
    194   ASSERT(r == UV_ENOENT || r == UV_EACCES);
    195   ASSERT_OK(uv_is_active((uv_handle_t*) &process));
    196   uv_close((uv_handle_t*) &process, NULL);
    197   ASSERT_OK(uv_run(uv_default_loop(), UV_RUN_DEFAULT));
    198 
    199   MAKE_VALGRIND_HAPPY(uv_default_loop());
    200   return 0;
    201 }
    202 
    203 
    204 #ifndef _WIN32
    205 TEST_IMPL(spawn_fails_check_for_waitpid_cleanup) {
    206   int r;
    207   int status;
    208   int err;
    209 
    210   init_process_options("", fail_cb);
    211   options.file = options.args[0] = "program-that-had-better-not-exist";
    212 
    213   r = uv_spawn(uv_default_loop(), &process, &options);
    214   ASSERT(r == UV_ENOENT || r == UV_EACCES);
    215   ASSERT_OK(uv_is_active((uv_handle_t*) &process));
    216   ASSERT_OK(uv_run(uv_default_loop(), UV_RUN_DEFAULT));
    217 
    218   /* verify the child is successfully cleaned up within libuv */
    219   do
    220     err = waitpid(process.pid, &status, 0);
    221   while (err == -1 && errno == EINTR);
    222 
    223   ASSERT_EQ(err, -1);
    224   ASSERT_EQ(errno, ECHILD);
    225 
    226   uv_close((uv_handle_t*) &process, NULL);
    227   ASSERT_OK(uv_run(uv_default_loop(), UV_RUN_DEFAULT));
    228 
    229   MAKE_VALGRIND_HAPPY(uv_default_loop());
    230   return 0;
    231 }
    232 #endif
    233 
    234 
    235 TEST_IMPL(spawn_empty_env) {
    236   char* env[1];
    237 
    238   /* The autotools dynamic library build requires the presence of
    239    * DYLD_LIBARY_PATH (macOS) or LD_LIBRARY_PATH/LIBPATH (other Unices)
    240    * in the environment, but of course that doesn't work with
    241    * the empty environment that we're testing here.
    242    */
    243   if (NULL != getenv("DYLD_LIBRARY_PATH") ||
    244       NULL != getenv("LD_LIBRARY_PATH") ||
    245       NULL != getenv("LIBPATH")) {
    246     RETURN_SKIP("doesn't work with DYLD_LIBRARY_PATH/LD_LIBRARY_PATH/LIBPATH");
    247   }
    248 
    249   init_process_options("spawn_helper1", exit_cb);
    250   options.env = env;
    251   env[0] = NULL;
    252 
    253   ASSERT_OK(uv_spawn(uv_default_loop(), &process, &options));
    254   ASSERT_OK(uv_run(uv_default_loop(), UV_RUN_DEFAULT));
    255 
    256   ASSERT_EQ(1, exit_cb_called);
    257   ASSERT_EQ(1, close_cb_called);
    258 
    259   MAKE_VALGRIND_HAPPY(uv_default_loop());
    260   return 0;
    261 }
    262 
    263 
    264 TEST_IMPL(spawn_exit_code) {
    265   int r;
    266 
    267   init_process_options("spawn_helper1", exit_cb);
    268 
    269   r = uv_spawn(uv_default_loop(), &process, &options);
    270   ASSERT_OK(r);
    271 
    272   r = uv_run(uv_default_loop(), UV_RUN_DEFAULT);
    273   ASSERT_OK(r);
    274 
    275   ASSERT_EQ(1, exit_cb_called);
    276   ASSERT_EQ(1, close_cb_called);
    277 
    278   MAKE_VALGRIND_HAPPY(uv_default_loop());
    279   return 0;
    280 }
    281 
    282 
    283 TEST_IMPL(spawn_stdout) {
    284   int r;
    285   uv_pipe_t out;
    286   uv_stdio_container_t stdio[2];
    287 
    288   init_process_options("spawn_helper2", exit_cb);
    289 
    290   uv_pipe_init(uv_default_loop(), &out, 0);
    291   options.stdio = stdio;
    292   options.stdio[0].flags = UV_IGNORE;
    293   options.stdio[1].flags = UV_CREATE_PIPE | UV_WRITABLE_PIPE;
    294   options.stdio[1].data.stream = (uv_stream_t*) &out;
    295   options.stdio_count = 2;
    296 
    297   r = uv_spawn(uv_default_loop(), &process, &options);
    298   ASSERT_OK(r);
    299 
    300   r = uv_read_start((uv_stream_t*) &out, on_alloc, on_read);
    301   ASSERT_OK(r);
    302 
    303   r = uv_run(uv_default_loop(), UV_RUN_DEFAULT);
    304   ASSERT_OK(r);
    305 
    306   ASSERT_EQ(1, exit_cb_called);
    307   ASSERT_EQ(2, close_cb_called); /* Once for process once for the pipe. */
    308   printf("output is: %s", output);
    309   ASSERT_OK(strcmp("hello world\n", output));
    310 
    311   MAKE_VALGRIND_HAPPY(uv_default_loop());
    312   return 0;
    313 }
    314 
    315 
    316 TEST_IMPL(spawn_stdout_to_file) {
    317   int r;
    318   uv_file file;
    319   uv_fs_t fs_req;
    320   uv_stdio_container_t stdio[2];
    321   uv_buf_t buf;
    322 
    323   /* Setup. */
    324   unlink("stdout_file");
    325 
    326   init_process_options("spawn_helper2", exit_cb);
    327 
    328   r = uv_fs_open(NULL, &fs_req, "stdout_file", UV_FS_O_CREAT | UV_FS_O_RDWR,
    329       S_IRUSR | S_IWUSR, NULL);
    330   ASSERT_NE(r, -1);
    331   uv_fs_req_cleanup(&fs_req);
    332 
    333   file = r;
    334 
    335   options.stdio = stdio;
    336   options.stdio[0].flags = UV_IGNORE;
    337   options.stdio[1].flags = UV_INHERIT_FD;
    338   options.stdio[1].data.fd = file;
    339   options.stdio_count = 2;
    340 
    341   r = uv_spawn(uv_default_loop(), &process, &options);
    342   ASSERT_OK(r);
    343 
    344   r = uv_run(uv_default_loop(), UV_RUN_DEFAULT);
    345   ASSERT_OK(r);
    346 
    347   ASSERT_EQ(1, exit_cb_called);
    348   ASSERT_EQ(1, close_cb_called);
    349 
    350   buf = uv_buf_init(output, sizeof(output));
    351   r = uv_fs_read(NULL, &fs_req, file, &buf, 1, 0, NULL);
    352   ASSERT_EQ(12, r);
    353   uv_fs_req_cleanup(&fs_req);
    354 
    355   r = uv_fs_close(NULL, &fs_req, file, NULL);
    356   ASSERT_OK(r);
    357   uv_fs_req_cleanup(&fs_req);
    358 
    359   printf("output is: %s", output);
    360   ASSERT_OK(strcmp("hello world\n", output));
    361 
    362   /* Cleanup. */
    363   unlink("stdout_file");
    364 
    365   MAKE_VALGRIND_HAPPY(uv_default_loop());
    366   return 0;
    367 }
    368 
    369 
    370 TEST_IMPL(spawn_stdout_and_stderr_to_file) {
    371   int r;
    372   uv_file file;
    373   uv_fs_t fs_req;
    374   uv_stdio_container_t stdio[3];
    375   uv_buf_t buf;
    376 
    377   /* Setup. */
    378   unlink("stdout_file");
    379 
    380   init_process_options("spawn_helper6", exit_cb);
    381 
    382   r = uv_fs_open(NULL, &fs_req, "stdout_file", UV_FS_O_CREAT | UV_FS_O_RDWR,
    383       S_IRUSR | S_IWUSR, NULL);
    384   ASSERT_NE(r, -1);
    385   uv_fs_req_cleanup(&fs_req);
    386 
    387   file = r;
    388 
    389   options.stdio = stdio;
    390   options.stdio[0].flags = UV_IGNORE;
    391   options.stdio[1].flags = UV_INHERIT_FD;
    392   options.stdio[1].data.fd = file;
    393   options.stdio[2].flags = UV_INHERIT_FD;
    394   options.stdio[2].data.fd = file;
    395   options.stdio_count = 3;
    396 
    397   r = uv_spawn(uv_default_loop(), &process, &options);
    398   ASSERT_OK(r);
    399 
    400   r = uv_run(uv_default_loop(), UV_RUN_DEFAULT);
    401   ASSERT_OK(r);
    402 
    403   ASSERT_EQ(1, exit_cb_called);
    404   ASSERT_EQ(1, close_cb_called);
    405 
    406   buf = uv_buf_init(output, sizeof(output));
    407   r = uv_fs_read(NULL, &fs_req, file, &buf, 1, 0, NULL);
    408   ASSERT_EQ(27, r);
    409   uv_fs_req_cleanup(&fs_req);
    410 
    411   r = uv_fs_close(NULL, &fs_req, file, NULL);
    412   ASSERT_OK(r);
    413   uv_fs_req_cleanup(&fs_req);
    414 
    415   printf("output is: %s", output);
    416   ASSERT_OK(strcmp("hello world\nhello errworld\n", output));
    417 
    418   /* Cleanup. */
    419   unlink("stdout_file");
    420 
    421   MAKE_VALGRIND_HAPPY(uv_default_loop());
    422   return 0;
    423 }
    424 
    425 
    426 TEST_IMPL(spawn_stdout_and_stderr_to_file2) {
    427 #ifndef _WIN32
    428   int r;
    429   uv_file file;
    430   uv_fs_t fs_req;
    431   uv_stdio_container_t stdio[3];
    432   uv_buf_t buf;
    433 
    434   /* Setup. */
    435   unlink("stdout_file");
    436 
    437   init_process_options("spawn_helper6", exit_cb);
    438 
    439   /* Replace stderr with our file */
    440   r = uv_fs_open(NULL,
    441                  &fs_req,
    442                  "stdout_file",
    443                  O_CREAT | O_RDWR,
    444                  S_IRUSR | S_IWUSR,
    445                  NULL);
    446   ASSERT_NE(r, -1);
    447   uv_fs_req_cleanup(&fs_req);
    448   file = dup2(r, STDERR_FILENO);
    449   ASSERT_NE(file, -1);
    450 
    451   options.stdio = stdio;
    452   options.stdio[0].flags = UV_IGNORE;
    453   options.stdio[1].flags = UV_INHERIT_FD;
    454   options.stdio[1].data.fd = file;
    455   options.stdio[2].flags = UV_INHERIT_FD;
    456   options.stdio[2].data.fd = file;
    457   options.stdio_count = 3;
    458 
    459   r = uv_spawn(uv_default_loop(), &process, &options);
    460   ASSERT_OK(r);
    461 
    462   r = uv_run(uv_default_loop(), UV_RUN_DEFAULT);
    463   ASSERT_OK(r);
    464 
    465   ASSERT_EQ(1, exit_cb_called);
    466   ASSERT_EQ(1, close_cb_called);
    467 
    468   buf = uv_buf_init(output, sizeof(output));
    469   r = uv_fs_read(NULL, &fs_req, file, &buf, 1, 0, NULL);
    470   ASSERT_EQ(27, r);
    471   uv_fs_req_cleanup(&fs_req);
    472 
    473   r = uv_fs_close(NULL, &fs_req, file, NULL);
    474   ASSERT_OK(r);
    475   uv_fs_req_cleanup(&fs_req);
    476 
    477   printf("output is: %s", output);
    478   ASSERT_OK(strcmp("hello world\nhello errworld\n", output));
    479 
    480   /* Cleanup. */
    481   unlink("stdout_file");
    482 
    483   MAKE_VALGRIND_HAPPY(uv_default_loop());
    484   return 0;
    485 #else
    486   RETURN_SKIP("Unix only test");
    487 #endif
    488 }
    489 
    490 
    491 TEST_IMPL(spawn_stdout_and_stderr_to_file_swap) {
    492 #ifndef _WIN32
    493   int r;
    494   uv_file stdout_file;
    495   uv_file stderr_file;
    496   uv_fs_t fs_req;
    497   uv_stdio_container_t stdio[3];
    498   uv_buf_t buf;
    499 
    500   /* Setup. */
    501   unlink("stdout_file");
    502   unlink("stderr_file");
    503 
    504   init_process_options("spawn_helper6", exit_cb);
    505 
    506   /* open 'stdout_file' and replace STDOUT_FILENO with it */
    507   r = uv_fs_open(NULL,
    508                  &fs_req,
    509                  "stdout_file",
    510                  O_CREAT | O_RDWR,
    511                  S_IRUSR | S_IWUSR,
    512                  NULL);
    513   ASSERT_NE(r, -1);
    514   uv_fs_req_cleanup(&fs_req);
    515   stdout_file = dup2(r, STDOUT_FILENO);
    516   ASSERT_NE(stdout_file, -1);
    517 
    518   /* open 'stderr_file' and replace STDERR_FILENO with it */
    519   r = uv_fs_open(NULL, &fs_req, "stderr_file", O_CREAT | O_RDWR,
    520       S_IRUSR | S_IWUSR, NULL);
    521   ASSERT_NE(r, -1);
    522   uv_fs_req_cleanup(&fs_req);
    523   stderr_file = dup2(r, STDERR_FILENO);
    524   ASSERT_NE(stderr_file, -1);
    525 
    526   /* now we're going to swap them: the child process' stdout will be our
    527    * stderr_file and vice versa */
    528   options.stdio = stdio;
    529   options.stdio[0].flags = UV_IGNORE;
    530   options.stdio[1].flags = UV_INHERIT_FD;
    531   options.stdio[1].data.fd = stderr_file;
    532   options.stdio[2].flags = UV_INHERIT_FD;
    533   options.stdio[2].data.fd = stdout_file;
    534   options.stdio_count = 3;
    535 
    536   r = uv_spawn(uv_default_loop(), &process, &options);
    537   ASSERT_OK(r);
    538 
    539   r = uv_run(uv_default_loop(), UV_RUN_DEFAULT);
    540   ASSERT_OK(r);
    541 
    542   ASSERT_EQ(1, exit_cb_called);
    543   ASSERT_EQ(1, close_cb_called);
    544 
    545   buf = uv_buf_init(output, sizeof(output));
    546 
    547   /* check the content of stdout_file */
    548   r = uv_fs_read(NULL, &fs_req, stdout_file, &buf, 1, 0, NULL);
    549   ASSERT_GE(r, 15);
    550   uv_fs_req_cleanup(&fs_req);
    551 
    552   r = uv_fs_close(NULL, &fs_req, stdout_file, NULL);
    553   ASSERT_OK(r);
    554   uv_fs_req_cleanup(&fs_req);
    555 
    556   printf("output is: %s", output);
    557   ASSERT_OK(strncmp("hello errworld\n", output, 15));
    558 
    559   /* check the content of stderr_file */
    560   r = uv_fs_read(NULL, &fs_req, stderr_file, &buf, 1, 0, NULL);
    561   ASSERT_GE(r, 12);
    562   uv_fs_req_cleanup(&fs_req);
    563 
    564   r = uv_fs_close(NULL, &fs_req, stderr_file, NULL);
    565   ASSERT_OK(r);
    566   uv_fs_req_cleanup(&fs_req);
    567 
    568   printf("output is: %s", output);
    569   ASSERT_OK(strncmp("hello world\n", output, 12));
    570 
    571   /* Cleanup. */
    572   unlink("stdout_file");
    573   unlink("stderr_file");
    574 
    575   MAKE_VALGRIND_HAPPY(uv_default_loop());
    576   return 0;
    577 #else
    578   RETURN_SKIP("Unix only test");
    579 #endif
    580 }
    581 
    582 
    583 TEST_IMPL(spawn_stdin) {
    584   int r;
    585   uv_pipe_t out;
    586   uv_pipe_t in;
    587   uv_write_t write_req;
    588   uv_buf_t buf;
    589   uv_stdio_container_t stdio[2];
    590   char buffer[] = "hello-from-spawn_stdin";
    591 
    592   init_process_options("spawn_helper3", exit_cb);
    593 
    594   uv_pipe_init(uv_default_loop(), &out, 0);
    595   uv_pipe_init(uv_default_loop(), &in, 0);
    596   options.stdio = stdio;
    597   options.stdio[0].flags = UV_CREATE_PIPE | UV_READABLE_PIPE;
    598   options.stdio[0].data.stream = (uv_stream_t*) &in;
    599   options.stdio[1].flags = UV_CREATE_PIPE | UV_WRITABLE_PIPE;
    600   options.stdio[1].data.stream = (uv_stream_t*) &out;
    601   options.stdio_count = 2;
    602 
    603   r = uv_spawn(uv_default_loop(), &process, &options);
    604   ASSERT_OK(r);
    605 
    606   buf.base = buffer;
    607   buf.len = sizeof(buffer);
    608   r = uv_write(&write_req, (uv_stream_t*) &in, &buf, 1, write_cb);
    609   ASSERT_OK(r);
    610 
    611   r = uv_read_start((uv_stream_t*) &out, on_alloc, on_read);
    612   ASSERT_OK(r);
    613 
    614   r = uv_run(uv_default_loop(), UV_RUN_DEFAULT);
    615   ASSERT_OK(r);
    616 
    617   ASSERT_EQ(1, exit_cb_called);
    618   ASSERT_EQ(3, close_cb_called); /* Once for process twice for the pipe. */
    619   ASSERT_OK(strcmp(buffer, output));
    620 
    621   MAKE_VALGRIND_HAPPY(uv_default_loop());
    622   return 0;
    623 }
    624 
    625 
    626 TEST_IMPL(spawn_stdio_greater_than_3) {
    627   int r;
    628   uv_pipe_t pipe;
    629   uv_stdio_container_t stdio[4];
    630 
    631   init_process_options("spawn_helper5", exit_cb);
    632 
    633   uv_pipe_init(uv_default_loop(), &pipe, 0);
    634   options.stdio = stdio;
    635   options.stdio[0].flags = UV_IGNORE;
    636   options.stdio[1].flags = UV_IGNORE;
    637   options.stdio[2].flags = UV_IGNORE;
    638   options.stdio[3].flags = UV_CREATE_PIPE | UV_WRITABLE_PIPE;
    639   options.stdio[3].data.stream = (uv_stream_t*) &pipe;
    640   options.stdio_count = 4;
    641 
    642   r = uv_spawn(uv_default_loop(), &process, &options);
    643   ASSERT_OK(r);
    644 
    645   r = uv_read_start((uv_stream_t*) &pipe, on_alloc, on_read);
    646   ASSERT_OK(r);
    647 
    648   r = uv_run(uv_default_loop(), UV_RUN_DEFAULT);
    649   ASSERT_OK(r);
    650 
    651   ASSERT_EQ(1, exit_cb_called);
    652   ASSERT_EQ(2, close_cb_called); /* Once for process once for the pipe. */
    653   printf("output from stdio[3] is: %s", output);
    654   ASSERT_OK(strcmp("fourth stdio!\n", output));
    655 
    656   MAKE_VALGRIND_HAPPY(uv_default_loop());
    657   return 0;
    658 }
    659 
    660 
    661 int spawn_tcp_server_helper(void) {
    662   uv_tcp_t tcp;
    663   uv_os_sock_t handle;
    664   int r;
    665 
    666   r = uv_tcp_init(uv_default_loop(), &tcp);
    667   ASSERT_OK(r);
    668 
    669 #ifdef _WIN32
    670   handle = _get_osfhandle(3);
    671 #else
    672   handle = 3;
    673 #endif
    674   r = uv_tcp_open(&tcp, handle);
    675   ASSERT_OK(r);
    676 
    677   /* Make sure that we can listen on a socket that was
    678    * passed down from the parent process
    679    */
    680   r = uv_listen((uv_stream_t*) &tcp, SOMAXCONN, NULL);
    681   ASSERT_OK(r);
    682 
    683   return 1;
    684 }
    685 
    686 
    687 TEST_IMPL(spawn_tcp_server) {
    688   uv_stdio_container_t stdio[4];
    689   struct sockaddr_in addr;
    690   int fd;
    691   int r;
    692 #ifdef _WIN32
    693   uv_os_fd_t handle;
    694 #endif
    695 
    696   init_process_options("spawn_tcp_server_helper", exit_cb);
    697 
    698   ASSERT_OK(uv_ip4_addr("127.0.0.1", TEST_PORT, &addr));
    699 
    700   fd = -1;
    701   r = uv_tcp_init_ex(uv_default_loop(), &tcp_server, AF_INET);
    702   ASSERT_OK(r);
    703   r = uv_tcp_bind(&tcp_server, (const struct sockaddr*) &addr, 0);
    704   ASSERT_OK(r);
    705 #ifdef _WIN32
    706   r = uv_fileno((uv_handle_t*) &tcp_server, &handle);
    707   fd = _open_osfhandle((intptr_t) handle, 0);
    708 #else
    709   r = uv_fileno((uv_handle_t*) &tcp_server, &fd);
    710  #endif
    711   ASSERT_OK(r);
    712   ASSERT_GT(fd, 0);
    713 
    714   options.stdio = stdio;
    715   options.stdio[0].flags = UV_INHERIT_FD;
    716   options.stdio[0].data.fd = 0;
    717   options.stdio[1].flags = UV_INHERIT_FD;
    718   options.stdio[1].data.fd = 1;
    719   options.stdio[2].flags = UV_INHERIT_FD;
    720   options.stdio[2].data.fd = 2;
    721   options.stdio[3].flags = UV_INHERIT_FD;
    722   options.stdio[3].data.fd = fd;
    723   options.stdio_count = 4;
    724 
    725   r = uv_spawn(uv_default_loop(), &process, &options);
    726   ASSERT_OK(r);
    727 
    728   r = uv_run(uv_default_loop(), UV_RUN_DEFAULT);
    729   ASSERT_OK(r);
    730 
    731   ASSERT_EQ(1, exit_cb_called);
    732   ASSERT_EQ(1, close_cb_called);
    733 
    734   MAKE_VALGRIND_HAPPY(uv_default_loop());
    735   return 0;
    736 }
    737 
    738 
    739 TEST_IMPL(spawn_ignored_stdio) {
    740   int r;
    741 
    742   init_process_options("spawn_helper6", exit_cb);
    743 
    744   options.stdio = NULL;
    745   options.stdio_count = 0;
    746 
    747   r = uv_spawn(uv_default_loop(), &process, &options);
    748   ASSERT_OK(r);
    749 
    750   r = uv_run(uv_default_loop(), UV_RUN_DEFAULT);
    751   ASSERT_OK(r);
    752 
    753   ASSERT_EQ(1, exit_cb_called);
    754   ASSERT_EQ(1, close_cb_called);
    755 
    756   MAKE_VALGRIND_HAPPY(uv_default_loop());
    757   return 0;
    758 }
    759 
    760 
    761 TEST_IMPL(spawn_and_kill) {
    762   int r;
    763 
    764   init_process_options("spawn_helper4", kill_cb);
    765 
    766   r = uv_spawn(uv_default_loop(), &process, &options);
    767   ASSERT_OK(r);
    768 
    769   r = uv_timer_init(uv_default_loop(), &timer);
    770   ASSERT_OK(r);
    771 
    772   r = uv_timer_start(&timer, timer_cb, 500, 0);
    773   ASSERT_OK(r);
    774 
    775   r = uv_run(uv_default_loop(), UV_RUN_DEFAULT);
    776   ASSERT_OK(r);
    777 
    778   ASSERT_EQ(1, exit_cb_called);
    779   ASSERT_EQ(2, close_cb_called); /* Once for process and once for timer. */
    780 
    781   MAKE_VALGRIND_HAPPY(uv_default_loop());
    782   return 0;
    783 }
    784 
    785 
    786 TEST_IMPL(spawn_preserve_env) {
    787   int r;
    788   uv_pipe_t out;
    789   uv_stdio_container_t stdio[2];
    790 
    791   init_process_options("spawn_helper7", exit_cb);
    792 
    793   uv_pipe_init(uv_default_loop(), &out, 0);
    794   options.stdio = stdio;
    795   options.stdio[0].flags = UV_IGNORE;
    796   options.stdio[1].flags = UV_CREATE_PIPE | UV_WRITABLE_PIPE;
    797   options.stdio[1].data.stream = (uv_stream_t*) &out;
    798   options.stdio_count = 2;
    799 
    800   r = putenv("ENV_TEST=testval");
    801   ASSERT_OK(r);
    802 
    803   /* Explicitly set options.env to NULL to test for env clobbering. */
    804   options.env = NULL;
    805 
    806   r = uv_spawn(uv_default_loop(), &process, &options);
    807   ASSERT_OK(r);
    808 
    809   r = uv_read_start((uv_stream_t*) &out, on_alloc, on_read);
    810   ASSERT_OK(r);
    811 
    812   r = uv_run(uv_default_loop(), UV_RUN_DEFAULT);
    813   ASSERT_OK(r);
    814 
    815   ASSERT_EQ(1, exit_cb_called);
    816   ASSERT_EQ(2, close_cb_called);
    817 
    818   printf("output is: %s", output);
    819   ASSERT_OK(strcmp("testval", output));
    820 
    821   MAKE_VALGRIND_HAPPY(uv_default_loop());
    822   return 0;
    823 }
    824 
    825 
    826 TEST_IMPL(spawn_detached) {
    827   int r;
    828 
    829   init_process_options("spawn_helper4", detach_failure_cb);
    830 
    831   options.flags |= UV_PROCESS_DETACHED;
    832 
    833   r = uv_spawn(uv_default_loop(), &process, &options);
    834   ASSERT_OK(r);
    835 
    836   uv_unref((uv_handle_t*) &process);
    837 
    838   r = uv_run(uv_default_loop(), UV_RUN_DEFAULT);
    839   ASSERT_OK(r);
    840 
    841   ASSERT_OK(exit_cb_called);
    842 
    843   ASSERT_EQ(process.pid, uv_process_get_pid(&process));
    844 
    845   r = uv_kill(process.pid, 0);
    846   ASSERT_OK(r);
    847 
    848   r = uv_kill(process.pid, SIGTERM);
    849   ASSERT_OK(r);
    850 
    851   MAKE_VALGRIND_HAPPY(uv_default_loop());
    852   return 0;
    853 }
    854 
    855 TEST_IMPL(spawn_and_kill_with_std) {
    856   int r;
    857   uv_pipe_t in, out, err;
    858   uv_write_t write;
    859   char message[] = "Nancy's joining me because the message this evening is "
    860                    "not my message but ours.";
    861   uv_buf_t buf;
    862   uv_stdio_container_t stdio[3];
    863 
    864   init_process_options("spawn_helper4", kill_cb);
    865 
    866   r = uv_pipe_init(uv_default_loop(), &in, 0);
    867   ASSERT_OK(r);
    868 
    869   r = uv_pipe_init(uv_default_loop(), &out, 0);
    870   ASSERT_OK(r);
    871 
    872   r = uv_pipe_init(uv_default_loop(), &err, 0);
    873   ASSERT_OK(r);
    874 
    875   options.stdio = stdio;
    876   options.stdio[0].flags = UV_CREATE_PIPE | UV_READABLE_PIPE;
    877   options.stdio[0].data.stream = (uv_stream_t*) &in;
    878   options.stdio[1].flags = UV_CREATE_PIPE | UV_WRITABLE_PIPE;
    879   options.stdio[1].data.stream = (uv_stream_t*) &out;
    880   options.stdio[2].flags = UV_CREATE_PIPE | UV_WRITABLE_PIPE;
    881   options.stdio[2].data.stream = (uv_stream_t*) &err;
    882   options.stdio_count = 3;
    883 
    884   r = uv_spawn(uv_default_loop(), &process, &options);
    885   ASSERT_OK(r);
    886 
    887   buf = uv_buf_init(message, sizeof message);
    888   r = uv_write(&write, (uv_stream_t*) &in, &buf, 1, write_cb);
    889   ASSERT_OK(r);
    890 
    891   r = uv_read_start((uv_stream_t*) &out, on_alloc, on_read);
    892   ASSERT_OK(r);
    893 
    894   r = uv_read_start((uv_stream_t*) &err, on_alloc, on_read);
    895   ASSERT_OK(r);
    896 
    897   r = uv_timer_init(uv_default_loop(), &timer);
    898   ASSERT_OK(r);
    899 
    900   r = uv_timer_start(&timer, timer_cb, 500, 0);
    901   ASSERT_OK(r);
    902 
    903   r = uv_run(uv_default_loop(), UV_RUN_DEFAULT);
    904   ASSERT_OK(r);
    905 
    906   ASSERT_EQ(1, exit_cb_called);
    907   ASSERT_EQ(5, close_cb_called); /* process x 1, timer x 1, stdio x 3. */
    908 
    909   MAKE_VALGRIND_HAPPY(uv_default_loop());
    910   return 0;
    911 }
    912 
    913 
    914 TEST_IMPL(spawn_and_ping) {
    915   uv_write_t write_req;
    916   uv_pipe_t in, out;
    917   uv_buf_t buf;
    918   uv_stdio_container_t stdio[2];
    919   int r;
    920 
    921   init_process_options("spawn_helper3", exit_cb);
    922   buf = uv_buf_init("TEST", 4);
    923 
    924   uv_pipe_init(uv_default_loop(), &out, 0);
    925   uv_pipe_init(uv_default_loop(), &in, 0);
    926   options.stdio = stdio;
    927   options.stdio[0].flags = UV_CREATE_PIPE | UV_READABLE_PIPE;
    928   options.stdio[0].data.stream = (uv_stream_t*) &in;
    929   options.stdio[1].flags = UV_CREATE_PIPE | UV_WRITABLE_PIPE;
    930   options.stdio[1].data.stream = (uv_stream_t*) &out;
    931   options.stdio_count = 2;
    932 
    933   r = uv_spawn(uv_default_loop(), &process, &options);
    934   ASSERT_OK(r);
    935 
    936   /* Sending signum == 0 should check if the
    937    * child process is still alive, not kill it.
    938    */
    939   r = uv_process_kill(&process, 0);
    940   ASSERT_OK(r);
    941 
    942   r = uv_write(&write_req, (uv_stream_t*) &in, &buf, 1, write_cb);
    943   ASSERT_OK(r);
    944 
    945   r = uv_read_start((uv_stream_t*) &out, on_alloc, on_read);
    946   ASSERT_OK(r);
    947 
    948   ASSERT_OK(exit_cb_called);
    949 
    950   r = uv_run(uv_default_loop(), UV_RUN_DEFAULT);
    951   ASSERT_OK(r);
    952 
    953   ASSERT_EQ(1, exit_cb_called);
    954   ASSERT_OK(strcmp(output, "TEST"));
    955 
    956   MAKE_VALGRIND_HAPPY(uv_default_loop());
    957   return 0;
    958 }
    959 
    960 
    961 TEST_IMPL(spawn_same_stdout_stderr) {
    962   uv_write_t write_req;
    963   uv_pipe_t in, out;
    964   uv_buf_t buf;
    965   uv_stdio_container_t stdio[3];
    966   int r;
    967 
    968   init_process_options("spawn_helper3", exit_cb);
    969   buf = uv_buf_init("TEST", 4);
    970 
    971   uv_pipe_init(uv_default_loop(), &out, 0);
    972   uv_pipe_init(uv_default_loop(), &in, 0);
    973   options.stdio = stdio;
    974   options.stdio[0].flags = UV_CREATE_PIPE | UV_READABLE_PIPE;
    975   options.stdio[0].data.stream = (uv_stream_t*) &in;
    976   options.stdio[1].flags = UV_CREATE_PIPE | UV_WRITABLE_PIPE;
    977   options.stdio[1].data.stream = (uv_stream_t*) &out;
    978   options.stdio_count = 2;
    979 
    980   r = uv_spawn(uv_default_loop(), &process, &options);
    981   ASSERT_OK(r);
    982 
    983   /* Sending signum == 0 should check if the
    984    * child process is still alive, not kill it.
    985    */
    986   r = uv_process_kill(&process, 0);
    987   ASSERT_OK(r);
    988 
    989   r = uv_write(&write_req, (uv_stream_t*) &in, &buf, 1, write_cb);
    990   ASSERT_OK(r);
    991 
    992   r = uv_read_start((uv_stream_t*) &out, on_alloc, on_read);
    993   ASSERT_OK(r);
    994 
    995   ASSERT_OK(exit_cb_called);
    996 
    997   r = uv_run(uv_default_loop(), UV_RUN_DEFAULT);
    998   ASSERT_OK(r);
    999 
   1000   ASSERT_EQ(1, exit_cb_called);
   1001   ASSERT_OK(strcmp(output, "TEST"));
   1002 
   1003   MAKE_VALGRIND_HAPPY(uv_default_loop());
   1004   return 0;
   1005 }
   1006 
   1007 
   1008 TEST_IMPL(spawn_closed_process_io) {
   1009   uv_pipe_t in;
   1010   uv_write_t write_req;
   1011   uv_buf_t buf;
   1012   uv_stdio_container_t stdio[2];
   1013   static char buffer[] = "hello-from-spawn_stdin\n";
   1014 
   1015   init_process_options("spawn_helper3", exit_cb);
   1016 
   1017   uv_pipe_init(uv_default_loop(), &in, 0);
   1018   options.stdio = stdio;
   1019   options.stdio[0].flags = UV_CREATE_PIPE | UV_READABLE_PIPE;
   1020   options.stdio[0].data.stream = (uv_stream_t*) &in;
   1021   options.stdio_count = 1;
   1022 
   1023   close(0); /* Close process stdin. */
   1024 
   1025   ASSERT_OK(uv_spawn(uv_default_loop(), &process, &options));
   1026 
   1027   buf = uv_buf_init(buffer, sizeof(buffer));
   1028   ASSERT_OK(uv_write(&write_req, (uv_stream_t*) &in, &buf, 1, write_cb));
   1029 
   1030   ASSERT_OK(uv_run(uv_default_loop(), UV_RUN_DEFAULT));
   1031 
   1032   ASSERT_EQ(1, exit_cb_called);
   1033   ASSERT_EQ(2, close_cb_called); /* process, child stdin */
   1034 
   1035   MAKE_VALGRIND_HAPPY(uv_default_loop());
   1036   return 0;
   1037 }
   1038 
   1039 
   1040 TEST_IMPL(kill) {
   1041   int r;
   1042 
   1043 #ifdef _WIN32
   1044   no_term_signal = 1;
   1045 #endif
   1046 
   1047   init_process_options("spawn_helper4", kill_cb);
   1048 
   1049   /* Verify that uv_spawn() resets the signal disposition. */
   1050 #ifndef _WIN32
   1051   {
   1052     sigset_t set;
   1053     sigemptyset(&set);
   1054     sigaddset(&set, SIGTERM);
   1055     ASSERT_OK(pthread_sigmask(SIG_BLOCK, &set, NULL));
   1056   }
   1057   ASSERT_PTR_NE(SIG_ERR, signal(SIGTERM, SIG_IGN));
   1058 #endif
   1059 
   1060   r = uv_spawn(uv_default_loop(), &process, &options);
   1061   ASSERT_OK(r);
   1062 
   1063 #ifndef _WIN32
   1064   {
   1065     sigset_t set;
   1066     sigemptyset(&set);
   1067     sigaddset(&set, SIGTERM);
   1068     ASSERT_OK(pthread_sigmask(SIG_UNBLOCK, &set, NULL));
   1069   }
   1070   ASSERT_PTR_NE(SIG_ERR, signal(SIGTERM, SIG_DFL));
   1071 #endif
   1072 
   1073   /* Sending signum == 0 should check if the
   1074    * child process is still alive, not kill it.
   1075    */
   1076   r = uv_kill(process.pid, 0);
   1077   ASSERT_OK(r);
   1078 
   1079   /* Kill the process. */
   1080   r = uv_kill(process.pid, SIGTERM);
   1081   ASSERT_OK(r);
   1082 
   1083   r = uv_run(uv_default_loop(), UV_RUN_DEFAULT);
   1084   ASSERT_OK(r);
   1085 
   1086   ASSERT_EQ(1, exit_cb_called);
   1087   ASSERT_EQ(1, close_cb_called);
   1088 
   1089   MAKE_VALGRIND_HAPPY(uv_default_loop());
   1090   return 0;
   1091 }
   1092 
   1093 
   1094 #ifdef _WIN32
   1095 TEST_IMPL(spawn_detect_pipe_name_collisions_on_windows) {
   1096   int r;
   1097   uv_pipe_t out;
   1098   char name[64];
   1099   HANDLE pipe_handle;
   1100   uv_stdio_container_t stdio[2];
   1101 
   1102   init_process_options("spawn_helper2", exit_cb);
   1103 
   1104   uv_pipe_init(uv_default_loop(), &out, 0);
   1105   options.stdio = stdio;
   1106   options.stdio[0].flags = UV_IGNORE;
   1107   options.stdio[1].flags = UV_CREATE_PIPE | UV_WRITABLE_PIPE;
   1108   options.stdio[1].data.stream = (uv_stream_t*) &out;
   1109   options.stdio_count = 2;
   1110 
   1111   /* Create a pipe that'll cause a collision. */
   1112   snprintf(name,
   1113            sizeof(name),
   1114            "\\\\.\\pipe\\uv\\%p-%lu",
   1115            &out,
   1116            GetCurrentProcessId());
   1117   pipe_handle = CreateNamedPipeA(name,
   1118                                 PIPE_ACCESS_INBOUND | FILE_FLAG_OVERLAPPED,
   1119                                 PIPE_TYPE_BYTE | PIPE_READMODE_BYTE | PIPE_WAIT,
   1120                                 10,
   1121                                 65536,
   1122                                 65536,
   1123                                 0,
   1124                                 NULL);
   1125   ASSERT_PTR_NE(pipe_handle, INVALID_HANDLE_VALUE);
   1126 
   1127   r = uv_spawn(uv_default_loop(), &process, &options);
   1128   ASSERT_OK(r);
   1129 
   1130   r = uv_read_start((uv_stream_t*) &out, on_alloc, on_read);
   1131   ASSERT_OK(r);
   1132 
   1133   r = uv_run(uv_default_loop(), UV_RUN_DEFAULT);
   1134   ASSERT_OK(r);
   1135 
   1136   ASSERT_EQ(1, exit_cb_called);
   1137   ASSERT_EQ(2, close_cb_called); /* Once for process once for the pipe. */
   1138   printf("output is: %s", output);
   1139   ASSERT_OK(strcmp("hello world\n", output));
   1140 
   1141   MAKE_VALGRIND_HAPPY(uv_default_loop());
   1142   return 0;
   1143 }
   1144 
   1145 
   1146 #if !defined(USING_UV_SHARED)
   1147 int make_program_args(char** args, int verbatim_arguments, WCHAR** dst_ptr);
   1148 WCHAR* quote_cmd_arg(const WCHAR *source, WCHAR *target);
   1149 
   1150 TEST_IMPL(argument_escaping) {
   1151   const WCHAR* test_str[] = {
   1152     L"",
   1153     L"HelloWorld",
   1154     L"Hello World",
   1155     L"Hello\"World",
   1156     L"Hello World\\",
   1157     L"Hello\\\"World",
   1158     L"Hello\\World",
   1159     L"Hello\\\\World",
   1160     L"Hello World\\",
   1161     L"c:\\path\\to\\node.exe --eval \"require('c:\\\\path\\\\to\\\\test.js')\""
   1162   };
   1163   const int count = sizeof(test_str) / sizeof(*test_str);
   1164   WCHAR** test_output;
   1165   WCHAR* command_line;
   1166   WCHAR** cracked;
   1167   size_t total_size = 0;
   1168   int i;
   1169   int num_args;
   1170   int result;
   1171 
   1172   char* verbatim[] = {
   1173     "cmd.exe",
   1174     "/c",
   1175     "c:\\path\\to\\node.exe --eval \"require('c:\\\\path\\\\to\\\\test.js')\"",
   1176     NULL
   1177   };
   1178   WCHAR* verbatim_output;
   1179   WCHAR* non_verbatim_output;
   1180 
   1181   test_output = calloc(count, sizeof(WCHAR*));
   1182   ASSERT_NOT_NULL(test_output);
   1183   for (i = 0; i < count; ++i) {
   1184     test_output[i] = calloc(2 * (wcslen(test_str[i]) + 2), sizeof(WCHAR));
   1185     quote_cmd_arg(test_str[i], test_output[i]);
   1186     wprintf(L"input : %s\n", test_str[i]);
   1187     wprintf(L"output: %s\n", test_output[i]);
   1188     total_size += wcslen(test_output[i]) + 1;
   1189   }
   1190   command_line = calloc(total_size + 1, sizeof(WCHAR));
   1191   ASSERT_NOT_NULL(command_line);
   1192   for (i = 0; i < count; ++i) {
   1193     wcscat(command_line, test_output[i]);
   1194     wcscat(command_line, L" ");
   1195   }
   1196   command_line[total_size - 1] = L'\0';
   1197 
   1198   wprintf(L"command_line: %s\n", command_line);
   1199 
   1200   cracked = CommandLineToArgvW(command_line, &num_args);
   1201   for (i = 0; i < num_args; ++i) {
   1202     wprintf(L"%d: %s\t%s\n", i, test_str[i], cracked[i]);
   1203     ASSERT_OK(wcscmp(test_str[i], cracked[i]));
   1204   }
   1205 
   1206   LocalFree(cracked);
   1207   for (i = 0; i < count; ++i) {
   1208     free(test_output[i]);
   1209   }
   1210   free(test_output);
   1211 
   1212   result = make_program_args(verbatim, 1, &verbatim_output);
   1213   ASSERT_OK(result);
   1214   result = make_program_args(verbatim, 0, &non_verbatim_output);
   1215   ASSERT_OK(result);
   1216 
   1217   wprintf(L"    verbatim_output: %s\n", verbatim_output);
   1218   wprintf(L"non_verbatim_output: %s\n", non_verbatim_output);
   1219 
   1220   ASSERT_OK(wcscmp(verbatim_output,
   1221                    L"cmd.exe /c c:\\path\\to\\node.exe --eval "
   1222                    L"\"require('c:\\\\path\\\\to\\\\test.js')\""));
   1223   ASSERT_OK(wcscmp(non_verbatim_output,
   1224                    L"cmd.exe /c \"c:\\path\\to\\node.exe --eval "
   1225                    L"\\\"require('c:\\\\path\\\\to\\\\test.js')\\\"\""));
   1226 
   1227   free(verbatim_output);
   1228   free(non_verbatim_output);
   1229 
   1230   return 0;
   1231 }
   1232 
   1233 int make_program_env(char** env_block, WCHAR** dst_ptr);
   1234 
   1235 TEST_IMPL(environment_creation) {
   1236   size_t i;
   1237   char* environment[] = {
   1238     "FOO=BAR",
   1239     "SYSTEM=ROOT", /* substring of a supplied var name */
   1240     "SYSTEMROOTED=OMG", /* supplied var name is a substring */
   1241     "TEMP=C:\\Temp",
   1242     "INVALID",
   1243     "BAZ=QUX",
   1244     "B_Z=QUX",
   1245     "B\xe2\x82\xacZ=QUX",
   1246     "B\xf0\x90\x80\x82Z=QUX",
   1247     "B\xef\xbd\xa1Z=QUX",
   1248     "B\xf0\xa3\x91\x96Z=QUX",
   1249     "BAZ", /* repeat, invalid variable */
   1250     NULL
   1251   };
   1252   WCHAR* wenvironment[] = {
   1253     L"BAZ=QUX",
   1254     L"B_Z=QUX",
   1255     L"B\x20acZ=QUX",
   1256     L"B\xd800\xdc02Z=QUX",
   1257     L"B\xd84d\xdc56Z=QUX",
   1258     L"B\xff61Z=QUX",
   1259     L"FOO=BAR",
   1260     L"SYSTEM=ROOT", /* substring of a supplied var name */
   1261     L"SYSTEMROOTED=OMG", /* supplied var name is a substring */
   1262     L"TEMP=C:\\Temp",
   1263   };
   1264   WCHAR* from_env[] = {
   1265     /* list should be kept in sync with list
   1266      * in process.c, minus variables in wenvironment */
   1267     L"HOMEDRIVE",
   1268     L"HOMEPATH",
   1269     L"LOGONSERVER",
   1270     L"PATH",
   1271     L"USERDOMAIN",
   1272     L"USERNAME",
   1273     L"USERPROFILE",
   1274     L"SYSTEMDRIVE",
   1275     L"SYSTEMROOT",
   1276     L"WINDIR",
   1277     /* test for behavior in the absence of a
   1278      * required-environment variable: */
   1279     L"ZTHIS_ENV_VARIABLE_DOES_NOT_EXIST",
   1280   };
   1281   int found_in_loc_env[ARRAY_SIZE(wenvironment)] = {0};
   1282   int found_in_usr_env[ARRAY_SIZE(from_env)] = {0};
   1283   WCHAR *expected[ARRAY_SIZE(from_env)];
   1284   int result;
   1285   WCHAR* str;
   1286   WCHAR* prev;
   1287   WCHAR* env;
   1288 
   1289   for (i = 0; i < ARRAY_SIZE(from_env); i++) {
   1290       /* copy expected additions to environment locally */
   1291       size_t len = GetEnvironmentVariableW(from_env[i], NULL, 0);
   1292       if (len == 0) {
   1293         found_in_usr_env[i] = 1;
   1294         str = malloc(1 * sizeof(WCHAR));
   1295         *str = 0;
   1296         expected[i] = str;
   1297       } else {
   1298         size_t name_len = wcslen(from_env[i]);
   1299         str = malloc((name_len+1+len) * sizeof(WCHAR));
   1300         wmemcpy(str, from_env[i], name_len);
   1301         expected[i] = str;
   1302         str += name_len;
   1303         *str++ = L'=';
   1304         GetEnvironmentVariableW(from_env[i], str, len);
   1305      }
   1306   }
   1307 
   1308   result = make_program_env(environment, &env);
   1309   ASSERT_OK(result);
   1310 
   1311   for (str = env, prev = NULL; *str; prev = str, str += wcslen(str) + 1) {
   1312     int found = 0;
   1313 #if 0
   1314     _cputws(str);
   1315     putchar('\n');
   1316 #endif
   1317     for (i = 0; i < ARRAY_SIZE(wenvironment) && !found; i++) {
   1318       if (!wcscmp(str, wenvironment[i])) {
   1319         ASSERT(!found_in_loc_env[i]);
   1320         found_in_loc_env[i] = 1;
   1321         found = 1;
   1322       }
   1323     }
   1324     for (i = 0; i < ARRAY_SIZE(expected) && !found; i++) {
   1325       if (!wcscmp(str, expected[i])) {
   1326         ASSERT(!found_in_usr_env[i]);
   1327         found_in_usr_env[i] = 1;
   1328         found = 1;
   1329       }
   1330     }
   1331     if (prev) { /* verify sort order */
   1332       ASSERT_EQ(1, CompareStringOrdinal(prev, -1, str, -1, TRUE));
   1333     }
   1334     ASSERT(found); /* verify that we expected this variable */
   1335   }
   1336 
   1337   /* verify that we found all expected variables */
   1338   for (i = 0; i < ARRAY_SIZE(wenvironment); i++) {
   1339     ASSERT(found_in_loc_env[i]);
   1340   }
   1341   for (i = 0; i < ARRAY_SIZE(expected); i++) {
   1342     ASSERT(found_in_usr_env[i]);
   1343   }
   1344 
   1345   return 0;
   1346 }
   1347 #endif
   1348 
   1349 /* Regression test for issue #909 */
   1350 TEST_IMPL(spawn_with_an_odd_path) {
   1351   int r;
   1352 
   1353   char newpath[2048];
   1354   char *path = getenv("PATH");
   1355   ASSERT_NOT_NULL(path);
   1356   snprintf(newpath, 2048, ";.;%s", path);
   1357   SetEnvironmentVariable("PATH", newpath);
   1358 
   1359   init_process_options("", exit_cb);
   1360   options.file = options.args[0] = "program-that-had-better-not-exist";
   1361   r = uv_spawn(uv_default_loop(), &process, &options);
   1362   ASSERT(r == UV_ENOENT || r == UV_EACCES);
   1363   ASSERT_OK(uv_is_active((uv_handle_t*) &process));
   1364   uv_close((uv_handle_t*) &process, NULL);
   1365   ASSERT_OK(uv_run(uv_default_loop(), UV_RUN_DEFAULT));
   1366 
   1367   MAKE_VALGRIND_HAPPY(uv_default_loop());
   1368   return 0;
   1369 }
   1370 
   1371 
   1372 TEST_IMPL(spawn_no_path) {
   1373   char* env[1];
   1374   WCHAR* old_path = NULL;
   1375   DWORD old_path_len;
   1376 
   1377   if ((old_path_len = GetEnvironmentVariableW(L"PATH", NULL, 0)) > 0) {
   1378     old_path = malloc(old_path_len * sizeof(WCHAR));
   1379     GetEnvironmentVariableW(L"PATH", old_path, old_path_len);
   1380     SetEnvironmentVariableW(L"PATH", NULL);
   1381   }
   1382 
   1383   init_process_options("spawn_helper1", exit_cb);
   1384   options.env = env;
   1385   env[0] = NULL;
   1386 
   1387   ASSERT_OK(uv_spawn(uv_default_loop(), &process, &options));
   1388   ASSERT_OK(uv_run(uv_default_loop(), UV_RUN_DEFAULT));
   1389 
   1390   ASSERT_EQ(1, exit_cb_called);
   1391   ASSERT_EQ(1, close_cb_called);
   1392 
   1393   SetEnvironmentVariableW(L"PATH", old_path);
   1394 
   1395   MAKE_VALGRIND_HAPPY(uv_default_loop());
   1396   return 0;
   1397 }
   1398 
   1399 
   1400 TEST_IMPL(spawn_no_ext) {
   1401   char new_exepath[1024];
   1402 
   1403   init_process_options("spawn_helper1", exit_cb);
   1404   options.flags |= UV_PROCESS_WINDOWS_FILE_PATH_EXACT_NAME;
   1405   snprintf(new_exepath, sizeof(new_exepath), "%.*s_no_ext",
   1406            (int) (exepath_size - sizeof(".exe") + 1),
   1407            exepath);
   1408   options.file = options.args[0] = new_exepath;
   1409 
   1410   ASSERT_OK(uv_spawn(uv_default_loop(), &process, &options));
   1411   ASSERT_OK(uv_run(uv_default_loop(), UV_RUN_DEFAULT));
   1412 
   1413   ASSERT_EQ(1, exit_cb_called);
   1414   ASSERT_EQ(1, close_cb_called);
   1415 
   1416   MAKE_VALGRIND_HAPPY(uv_default_loop());
   1417   return 0;
   1418 }
   1419 
   1420 
   1421 TEST_IMPL(spawn_path_no_ext) {
   1422   int r;
   1423   int len;
   1424   int file_len;
   1425   char file[64];
   1426   char path[1024];
   1427   char* env[2];
   1428 
   1429   /* Set up the process, but make sure that the file to run is relative and
   1430    * requires a lookup into PATH. */
   1431   init_process_options("spawn_helper1", exit_cb);
   1432   options.flags |= UV_PROCESS_WINDOWS_FILE_PATH_EXACT_NAME;
   1433 
   1434   /* Set up the PATH env variable */
   1435   for (len = strlen(exepath), file_len = 0;
   1436        exepath[len - 1] != '/' && exepath[len - 1] != '\\';
   1437        len--, file_len++);
   1438   snprintf(file, sizeof(file), "%.*s_no_ext",
   1439            (int) (file_len - sizeof(".exe") + 1),
   1440            exepath + len);
   1441   exepath[len] = 0;
   1442   snprintf(path, sizeof(path), "PATH=%s", exepath);
   1443 
   1444   env[0] = path;
   1445   env[1] = NULL;
   1446 
   1447   options.file = options.args[0] = file;
   1448   options.env = env;
   1449 
   1450   r = uv_spawn(uv_default_loop(), &process, &options);
   1451   ASSERT(r == UV_ENOENT || r == UV_EACCES);
   1452   ASSERT_OK(uv_is_active((uv_handle_t*) &process));
   1453   uv_close((uv_handle_t*) &process, NULL);
   1454   ASSERT_OK(uv_run(uv_default_loop(), UV_RUN_DEFAULT));
   1455 
   1456   MAKE_VALGRIND_HAPPY(uv_default_loop());
   1457   return 0;
   1458 }
   1459 #endif
   1460 
   1461 #ifndef _WIN32
   1462 TEST_IMPL(spawn_setuid_setgid) {
   1463   int r;
   1464   struct passwd* pw;
   1465   char uidstr[10];
   1466   char gidstr[10];
   1467 
   1468   /* if not root, then this will fail. */
   1469   uv_uid_t uid = getuid();
   1470   if (uid != 0) {
   1471     RETURN_SKIP("It should be run as root user");
   1472   }
   1473 
   1474   init_process_options("spawn_helper_setuid_setgid", exit_cb);
   1475 
   1476   /* become the "nobody" user. */
   1477   pw = getpwnam("nobody");
   1478   ASSERT_NOT_NULL(pw);
   1479   options.uid = pw->pw_uid;
   1480   options.gid = pw->pw_gid;
   1481   snprintf(uidstr, sizeof(uidstr), "%d", pw->pw_uid);
   1482   snprintf(gidstr, sizeof(gidstr), "%d", pw->pw_gid);
   1483   options.args[2] = uidstr;
   1484   options.args[3] = gidstr;
   1485   options.flags = UV_PROCESS_SETUID | UV_PROCESS_SETGID;
   1486 
   1487   r = uv_spawn(uv_default_loop(), &process, &options);
   1488   if (r == UV_EACCES)
   1489     RETURN_SKIP("user 'nobody' cannot access the test runner");
   1490 
   1491   ASSERT_OK(r);
   1492 
   1493   r = uv_run(uv_default_loop(), UV_RUN_DEFAULT);
   1494   ASSERT_OK(r);
   1495 
   1496   ASSERT_EQ(1, exit_cb_called);
   1497   ASSERT_EQ(1, close_cb_called);
   1498 
   1499   MAKE_VALGRIND_HAPPY(uv_default_loop());
   1500   return 0;
   1501 }
   1502 #endif
   1503 
   1504 
   1505 #ifndef _WIN32
   1506 TEST_IMPL(spawn_setuid_fails) {
   1507   int r;
   1508 
   1509   /* if root, become nobody. */
   1510   /* On IBMi PASE, there is no nobody user. */
   1511 #ifndef __PASE__
   1512   uv_uid_t uid = getuid();
   1513   if (uid == 0) {
   1514     struct passwd* pw;
   1515     pw = getpwnam("nobody");
   1516     ASSERT_NOT_NULL(pw);
   1517     ASSERT_OK(setgid(pw->pw_gid));
   1518     ASSERT_OK(setuid(pw->pw_uid));
   1519   }
   1520 #endif  /* !__PASE__ */
   1521 
   1522   init_process_options("spawn_helper1", fail_cb);
   1523 
   1524   options.flags |= UV_PROCESS_SETUID;
   1525   /* On IBMi PASE, there is no root user. User may grant
   1526    * root-like privileges, including setting uid to 0.
   1527    */
   1528 #if defined(__PASE__)
   1529   options.uid = -1;
   1530 #else
   1531   options.uid = 0;
   1532 #endif
   1533 
   1534   /* These flags should be ignored on Unices. */
   1535   options.flags |= UV_PROCESS_WINDOWS_HIDE;
   1536   options.flags |= UV_PROCESS_WINDOWS_HIDE_CONSOLE;
   1537   options.flags |= UV_PROCESS_WINDOWS_HIDE_GUI;
   1538   options.flags |= UV_PROCESS_WINDOWS_VERBATIM_ARGUMENTS;
   1539 
   1540   r = uv_spawn(uv_default_loop(), &process, &options);
   1541 #if defined(__CYGWIN__)
   1542   ASSERT_EQ(r, UV_EINVAL);
   1543 #else
   1544   ASSERT_EQ(r, UV_EPERM);
   1545 #endif
   1546 
   1547   r = uv_run(uv_default_loop(), UV_RUN_DEFAULT);
   1548   ASSERT_OK(r);
   1549 
   1550   ASSERT_OK(close_cb_called);
   1551 
   1552   MAKE_VALGRIND_HAPPY(uv_default_loop());
   1553   return 0;
   1554 }
   1555 
   1556 
   1557 TEST_IMPL(spawn_setgid_fails) {
   1558   int r;
   1559 
   1560   /* if root, become nobody. */
   1561   /* On IBMi PASE, there is no nobody user. */
   1562 #ifndef __PASE__
   1563   uv_uid_t uid = getuid();
   1564   if (uid == 0) {
   1565     struct passwd* pw;
   1566     pw = getpwnam("nobody");
   1567     ASSERT_NOT_NULL(pw);
   1568     ASSERT_OK(setgid(pw->pw_gid));
   1569     ASSERT_OK(setuid(pw->pw_uid));
   1570   }
   1571 #endif  /* !__PASE__ */
   1572 
   1573   init_process_options("spawn_helper1", fail_cb);
   1574 
   1575   options.flags |= UV_PROCESS_SETGID;
   1576   /* On IBMi PASE, there is no root user. User may grant
   1577    * root-like privileges, including setting gid to 0.
   1578    */
   1579 #if defined(__MVS__) || defined(__PASE__)
   1580   options.gid = -1;
   1581 #else
   1582   options.gid = 0;
   1583 #endif
   1584 
   1585   r = uv_spawn(uv_default_loop(), &process, &options);
   1586 #if defined(__CYGWIN__) || defined(__MVS__)
   1587   ASSERT_EQ(r, UV_EINVAL);
   1588 #else
   1589   ASSERT_EQ(r, UV_EPERM);
   1590 #endif
   1591 
   1592   r = uv_run(uv_default_loop(), UV_RUN_DEFAULT);
   1593   ASSERT_OK(r);
   1594 
   1595   ASSERT_OK(close_cb_called);
   1596 
   1597   MAKE_VALGRIND_HAPPY(uv_default_loop());
   1598   return 0;
   1599 }
   1600 #endif
   1601 
   1602 
   1603 #ifdef _WIN32
   1604 
   1605 static void exit_cb_unexpected(uv_process_t* process,
   1606                                int64_t exit_status,
   1607                                int term_signal) {
   1608   ASSERT(0 && "should not have been called");
   1609 }
   1610 
   1611 
   1612 TEST_IMPL(spawn_setuid_fails) {
   1613   int r;
   1614 
   1615   init_process_options("spawn_helper1", exit_cb_unexpected);
   1616 
   1617   options.flags |= UV_PROCESS_SETUID;
   1618   options.uid = (uv_uid_t) -42424242;
   1619 
   1620   r = uv_spawn(uv_default_loop(), &process, &options);
   1621   ASSERT_EQ(r, UV_ENOTSUP);
   1622 
   1623   r = uv_run(uv_default_loop(), UV_RUN_DEFAULT);
   1624   ASSERT_OK(r);
   1625 
   1626   ASSERT_OK(close_cb_called);
   1627 
   1628   MAKE_VALGRIND_HAPPY(uv_default_loop());
   1629   return 0;
   1630 }
   1631 
   1632 
   1633 TEST_IMPL(spawn_setgid_fails) {
   1634   int r;
   1635 
   1636   init_process_options("spawn_helper1", exit_cb_unexpected);
   1637 
   1638   options.flags |= UV_PROCESS_SETGID;
   1639   options.gid = (uv_gid_t) -42424242;
   1640 
   1641   r = uv_spawn(uv_default_loop(), &process, &options);
   1642   ASSERT_EQ(r, UV_ENOTSUP);
   1643 
   1644   r = uv_run(uv_default_loop(), UV_RUN_DEFAULT);
   1645   ASSERT_OK(r);
   1646 
   1647   ASSERT_OK(close_cb_called);
   1648 
   1649   MAKE_VALGRIND_HAPPY(uv_default_loop());
   1650   return 0;
   1651 }
   1652 #endif
   1653 
   1654 
   1655 TEST_IMPL(spawn_auto_unref) {
   1656   init_process_options("spawn_helper1", NULL);
   1657   ASSERT_OK(uv_spawn(uv_default_loop(), &process, &options));
   1658   ASSERT_OK(uv_run(uv_default_loop(), UV_RUN_DEFAULT));
   1659   ASSERT_OK(uv_is_closing((uv_handle_t*) &process));
   1660   uv_close((uv_handle_t*) &process, NULL);
   1661   ASSERT_OK(uv_run(uv_default_loop(), UV_RUN_DEFAULT));
   1662   ASSERT_EQ(1, uv_is_closing((uv_handle_t*) &process));
   1663   MAKE_VALGRIND_HAPPY(uv_default_loop());
   1664   return 0;
   1665 }
   1666 
   1667 
   1668 TEST_IMPL(spawn_fs_open) {
   1669   int r;
   1670   uv_os_fd_t fd;
   1671   uv_os_fd_t dup_fd;
   1672   uv_fs_t fs_req;
   1673   uv_pipe_t in;
   1674   uv_write_t write_req;
   1675   uv_write_t write_req2;
   1676   uv_buf_t buf;
   1677   uv_stdio_container_t stdio[1];
   1678 #ifdef _WIN32
   1679   const char dev_null[] = "NUL";
   1680   HMODULE kernelbase_module;
   1681   sCompareObjectHandles pCompareObjectHandles; /* function introduced in Windows 10 */
   1682 #else
   1683   const char dev_null[] = "/dev/null";
   1684 #endif
   1685 
   1686   r = uv_fs_open(NULL, &fs_req, dev_null, UV_FS_O_RDWR, 0, NULL);
   1687   ASSERT_NE(r, -1);
   1688   fd = uv_get_osfhandle((uv_file) fs_req.result);
   1689   uv_fs_req_cleanup(&fs_req);
   1690 
   1691   init_process_options("spawn_helper8", exit_cb);
   1692 
   1693   ASSERT_OK(uv_pipe_init(uv_default_loop(), &in, 0));
   1694 
   1695   options.stdio = stdio;
   1696   options.stdio[0].flags = UV_CREATE_PIPE | UV_READABLE_PIPE;
   1697   options.stdio[0].data.stream = (uv_stream_t*) &in;
   1698   options.stdio_count = 1;
   1699 
   1700   /* make an inheritable copy */
   1701 #ifdef _WIN32
   1702   ASSERT_NE(0, DuplicateHandle(GetCurrentProcess(), fd, GetCurrentProcess(), &dup_fd,
   1703                                0, /* inherit */ TRUE, DUPLICATE_SAME_ACCESS));
   1704   kernelbase_module = GetModuleHandleA("kernelbase.dll");
   1705   pCompareObjectHandles = (sCompareObjectHandles)
   1706       GetProcAddress(kernelbase_module, "CompareObjectHandles");
   1707   ASSERT_NE(pCompareObjectHandles == NULL ||
   1708             pCompareObjectHandles(fd, dup_fd),
   1709             0);
   1710 #else
   1711   dup_fd = dup(fd);
   1712 #endif
   1713 
   1714   ASSERT_OK(uv_spawn(uv_default_loop(), &process, &options));
   1715 
   1716   buf = uv_buf_init((char*) &fd, sizeof(fd));
   1717   ASSERT_OK(uv_write(&write_req,
   1718                      (uv_stream_t*) &in,
   1719                      &buf,
   1720                      1,
   1721                      write_null_cb));
   1722 
   1723   buf = uv_buf_init((char*) &dup_fd, sizeof(fd));
   1724   ASSERT_OK(uv_write(&write_req2, (uv_stream_t*) &in, &buf, 1, write_cb));
   1725 
   1726   ASSERT_OK(uv_run(uv_default_loop(), UV_RUN_DEFAULT));
   1727   ASSERT_OK(uv_fs_close(NULL, &fs_req, r, NULL));
   1728 
   1729   ASSERT_EQ(1, exit_cb_called);
   1730   ASSERT_EQ(2, close_cb_called);  /* One for `in`, one for process */
   1731 
   1732   MAKE_VALGRIND_HAPPY(uv_default_loop());
   1733   return 0;
   1734 }
   1735 
   1736 
   1737 TEST_IMPL(closed_fd_events) {
   1738   uv_stdio_container_t stdio[3];
   1739   uv_pipe_t pipe_handle;
   1740   uv_fs_t req;
   1741   uv_buf_t bufs[1];
   1742   uv_file fd[2];
   1743   bufs[0] = uv_buf_init("", 1);
   1744 
   1745   /* create a pipe and share it with a child process */
   1746   ASSERT_OK(uv_pipe(fd, 0, 0));
   1747   ASSERT_GT(fd[0], 2);
   1748   ASSERT_GT(fd[1], 2);
   1749 
   1750   /* spawn_helper4 blocks indefinitely. */
   1751   init_process_options("spawn_helper4", exit_cb);
   1752   options.stdio_count = 3;
   1753   options.stdio = stdio;
   1754   options.stdio[0].flags = UV_INHERIT_FD;
   1755   options.stdio[0].data.fd = fd[0];
   1756   options.stdio[1].flags = UV_IGNORE;
   1757   options.stdio[2].flags = UV_IGNORE;
   1758 
   1759   ASSERT_OK(uv_spawn(uv_default_loop(), &process, &options));
   1760   uv_unref((uv_handle_t*) &process);
   1761 
   1762   /* read from the pipe with uv */
   1763   ASSERT_OK(uv_pipe_init(uv_default_loop(), &pipe_handle, 0));
   1764   ASSERT_OK(uv_pipe_open(&pipe_handle, fd[0]));
   1765   /* uv_pipe_open() takes ownership of the file descriptor. */
   1766   fd[0] = -1;
   1767 
   1768   ASSERT_OK(uv_read_start((uv_stream_t*) &pipe_handle,
   1769                           on_alloc,
   1770                           on_read_once));
   1771 
   1772   ASSERT_EQ(1, uv_fs_write(NULL, &req, fd[1], bufs, 1, -1, NULL));
   1773   ASSERT_EQ(1, req.result);
   1774   uv_fs_req_cleanup(&req);
   1775 
   1776   ASSERT_OK(uv_run(uv_default_loop(), UV_RUN_ONCE));
   1777 
   1778   /* should have received just one byte */
   1779   ASSERT_EQ(1, output_used);
   1780 
   1781   /* close the pipe and see if we still get events */
   1782   uv_close((uv_handle_t*) &pipe_handle, close_cb);
   1783 
   1784   ASSERT_EQ(1, uv_fs_write(NULL, &req, fd[1], bufs, 1, -1, NULL));
   1785   ASSERT_EQ(1, req.result);
   1786   uv_fs_req_cleanup(&req);
   1787 
   1788   ASSERT_OK(uv_timer_init(uv_default_loop(), &timer));
   1789   ASSERT_OK(uv_timer_start(&timer, timer_counter_cb, 10, 0));
   1790 
   1791   /* see if any spurious events interrupt the timer */
   1792   if (1 == uv_run(uv_default_loop(), UV_RUN_ONCE))
   1793     /* have to run again to really trigger the timer */
   1794     ASSERT_OK(uv_run(uv_default_loop(), UV_RUN_ONCE));
   1795 
   1796   ASSERT_EQ(1, timer_counter);
   1797 
   1798   /* cleanup */
   1799   ASSERT_OK(uv_process_kill(&process, SIGTERM));
   1800 #ifdef _WIN32
   1801   ASSERT_OK(_close(fd[1]));
   1802 #else
   1803   ASSERT_OK(close(fd[1]));
   1804 #endif
   1805 
   1806   MAKE_VALGRIND_HAPPY(uv_default_loop());
   1807   return 0;
   1808 }
   1809 
   1810 
   1811 TEST_IMPL(spawn_reads_child_path) {
   1812   int r;
   1813   int len;
   1814   char file[64];
   1815   char path[1024];
   1816   char* env[3];
   1817 
   1818   /* Need to carry over the dynamic linker path when the test runner is
   1819    * linked against libuv.so, see https://github.com/libuv/libuv/issues/85.
   1820    */
   1821 #if defined(__APPLE__)
   1822   static const char dyld_path_var[] = "DYLD_LIBRARY_PATH";
   1823 #elif defined(__MVS__) || defined(__PASE__)
   1824   static const char dyld_path_var[] = "LIBPATH";
   1825 #else
   1826   static const char dyld_path_var[] = "LD_LIBRARY_PATH";
   1827 #endif
   1828 
   1829   /* Set up the process, but make sure that the file to run is relative and
   1830    * requires a lookup into PATH. */
   1831   init_process_options("spawn_helper1", exit_cb);
   1832 
   1833   /* Set up the PATH env variable */
   1834   for (len = strlen(exepath);
   1835        exepath[len - 1] != '/' && exepath[len - 1] != '\\';
   1836        len--);
   1837   strcpy(file, exepath + len);
   1838   exepath[len] = 0;
   1839   strcpy(path, "PATH=");
   1840   strcpy(path + 5, exepath);
   1841 #if defined(__CYGWIN__) || defined(__MSYS__)
   1842   /* Carry over the dynamic linker path in case the test runner
   1843      is linked against cyguv-1.dll or msys-uv-1.dll, see above.  */
   1844   {
   1845     char* syspath = getenv("PATH");
   1846     if (syspath != NULL) {
   1847       strcat(path, ":");
   1848       strcat(path, syspath);
   1849     }
   1850   }
   1851 #endif
   1852 
   1853   env[0] = path;
   1854   env[1] = getenv(dyld_path_var);
   1855   env[2] = NULL;
   1856 
   1857   if (env[1] != NULL) {
   1858     static char buf[1024 + sizeof(dyld_path_var)];
   1859     snprintf(buf, sizeof(buf), "%s=%s", dyld_path_var, env[1]);
   1860     env[1] = buf;
   1861   }
   1862 
   1863   options.file = file;
   1864   options.args[0] = file;
   1865   options.env = env;
   1866 
   1867   r = uv_spawn(uv_default_loop(), &process, &options);
   1868   ASSERT_OK(r);
   1869 
   1870   r = uv_run(uv_default_loop(), UV_RUN_DEFAULT);
   1871   ASSERT_OK(r);
   1872 
   1873   ASSERT_EQ(1, exit_cb_called);
   1874   ASSERT_EQ(1, close_cb_called);
   1875 
   1876   MAKE_VALGRIND_HAPPY(uv_default_loop());
   1877   return 0;
   1878 }
   1879 
   1880 TEST_IMPL(spawn_inherit_streams) {
   1881   uv_process_t child_req;
   1882   uv_stdio_container_t child_stdio[2];
   1883   int fds_stdin[2];
   1884   int fds_stdout[2];
   1885   uv_pipe_t pipe_stdin_child;
   1886   uv_pipe_t pipe_stdout_child;
   1887   uv_pipe_t pipe_stdin_parent;
   1888   uv_pipe_t pipe_stdout_parent;
   1889   unsigned char ubuf[OUTPUT_SIZE - 1];
   1890   uv_buf_t buf;
   1891   unsigned int i;
   1892   int r;
   1893   int bidir;
   1894   uv_write_t write_req;
   1895   uv_loop_t* loop;
   1896 
   1897   init_process_options("spawn_helper9", exit_cb);
   1898 
   1899   loop = uv_default_loop();
   1900   ASSERT_OK(uv_pipe_init(loop, &pipe_stdin_child, 0));
   1901   ASSERT_OK(uv_pipe_init(loop, &pipe_stdout_child, 0));
   1902   ASSERT_OK(uv_pipe_init(loop, &pipe_stdin_parent, 0));
   1903   ASSERT_OK(uv_pipe_init(loop, &pipe_stdout_parent, 0));
   1904 
   1905   ASSERT_OK(uv_pipe(fds_stdin, 0, 0));
   1906   ASSERT_OK(uv_pipe(fds_stdout, 0, 0));
   1907 
   1908   ASSERT_OK(uv_pipe_open(&pipe_stdin_child, fds_stdin[0]));
   1909   ASSERT_OK(uv_pipe_open(&pipe_stdout_child, fds_stdout[1]));
   1910   ASSERT_OK(uv_pipe_open(&pipe_stdin_parent, fds_stdin[1]));
   1911   ASSERT_OK(uv_pipe_open(&pipe_stdout_parent, fds_stdout[0]));
   1912   ASSERT(uv_is_readable((uv_stream_t*) &pipe_stdin_child));
   1913   ASSERT(uv_is_writable((uv_stream_t*) &pipe_stdout_child));
   1914   ASSERT(uv_is_writable((uv_stream_t*) &pipe_stdin_parent));
   1915   ASSERT(uv_is_readable((uv_stream_t*) &pipe_stdout_parent));
   1916   /* Some systems (SVR4) open a bidirectional pipe, most don't. */
   1917   bidir = uv_is_writable((uv_stream_t*) &pipe_stdin_child);
   1918   ASSERT_EQ(uv_is_readable((uv_stream_t*) &pipe_stdout_child), bidir);
   1919   ASSERT_EQ(uv_is_readable((uv_stream_t*) &pipe_stdin_parent), bidir);
   1920   ASSERT_EQ(uv_is_writable((uv_stream_t*) &pipe_stdout_parent), bidir);
   1921 
   1922   child_stdio[0].flags = UV_INHERIT_STREAM;
   1923   child_stdio[0].data.stream = (uv_stream_t *) &pipe_stdin_child;
   1924 
   1925   child_stdio[1].flags = UV_INHERIT_STREAM;
   1926   child_stdio[1].data.stream = (uv_stream_t *) &pipe_stdout_child;
   1927 
   1928   options.stdio = child_stdio;
   1929   options.stdio_count = 2;
   1930 
   1931   ASSERT_OK(uv_spawn(loop, &child_req, &options));
   1932 
   1933   uv_close((uv_handle_t*) &pipe_stdin_child, NULL);
   1934   uv_close((uv_handle_t*) &pipe_stdout_child, NULL);
   1935 
   1936   buf = uv_buf_init((char*) ubuf, sizeof ubuf);
   1937   for (i = 0; i < sizeof ubuf; ++i)
   1938     ubuf[i] = i & 255u;
   1939   memset(output, 0, sizeof ubuf);
   1940 
   1941   r = uv_write(&write_req,
   1942                (uv_stream_t*) &pipe_stdin_parent,
   1943                &buf,
   1944                1,
   1945                write_cb);
   1946   ASSERT_OK(r);
   1947 
   1948   r = uv_read_start((uv_stream_t*) &pipe_stdout_parent, on_alloc, on_read);
   1949   ASSERT_OK(r);
   1950 
   1951   r = uv_run(loop, UV_RUN_DEFAULT);
   1952   ASSERT_OK(r);
   1953 
   1954   ASSERT_EQ(1, exit_cb_called);
   1955   ASSERT_EQ(3, close_cb_called);
   1956 
   1957   r = memcmp(ubuf, output, sizeof ubuf);
   1958   ASSERT_OK(r);
   1959 
   1960   MAKE_VALGRIND_HAPPY(loop);
   1961   return 0;
   1962 }
   1963 
   1964 TEST_IMPL(spawn_quoted_path) {
   1965 #ifndef _WIN32
   1966   RETURN_SKIP("Test for Windows");
   1967 #else
   1968   char* quoted_path_env[2];
   1969   args[0] = "not_existing";
   1970   args[1] = NULL;
   1971   options.file = args[0];
   1972   options.args = args;
   1973   options.exit_cb = exit_cb;
   1974   options.flags = 0;
   1975   /* We test if search_path works correctly with semicolons in quoted path. We
   1976    * will use an invalid drive, so we are sure no executable is spawned. */
   1977   quoted_path_env[0] = "PATH=\"xyz:\\test;\";xyz:\\other";
   1978   quoted_path_env[1] = NULL;
   1979   options.env = quoted_path_env;
   1980 
   1981   /* We test if libuv will not segfault. */
   1982   uv_spawn(uv_default_loop(), &process, &options);
   1983 
   1984   MAKE_VALGRIND_HAPPY(uv_default_loop());
   1985   return 0;
   1986 #endif
   1987 }
   1988 
   1989 TEST_IMPL(spawn_exercise_sigchld_issue) {
   1990   int r;
   1991   int i;
   1992   uv_process_options_t dummy_options = {0};
   1993   uv_process_t dummy_processes[100];
   1994   char* args[2];
   1995 
   1996   init_process_options("spawn_helper1", exit_cb);
   1997 
   1998   r = uv_spawn(uv_default_loop(), &process, &options);
   1999   ASSERT_OK(r);
   2000 
   2001   // This test exercises a bug in the darwin kernel that causes SIGCHLD not to
   2002   // be delivered sometimes. Calling posix_spawn many times increases the
   2003   // likelihood of encountering this issue, so spin a few times to make this
   2004   // test more reliable.
   2005   dummy_options.file = args[0] = "program-that-had-better-not-exist";
   2006   args[1] = NULL;
   2007   dummy_options.args = args;
   2008   dummy_options.exit_cb = fail_cb;
   2009   dummy_options.flags = 0;
   2010   for (i = 0; i < 100; i++) {
   2011     r = uv_spawn(uv_default_loop(), &dummy_processes[i], &dummy_options);
   2012     if (r != UV_ENOENT)
   2013       ASSERT_EQ(r, UV_EACCES);
   2014     uv_close((uv_handle_t*) &dummy_processes[i], close_cb);
   2015   }
   2016 
   2017   r = uv_run(uv_default_loop(), UV_RUN_DEFAULT);
   2018   ASSERT_OK(r);
   2019 
   2020   ASSERT_EQ(1, exit_cb_called);
   2021   ASSERT_EQ(101, close_cb_called);
   2022 
   2023   MAKE_VALGRIND_HAPPY(uv_default_loop());
   2024   return 0;
   2025 }
   2026 
   2027 /* Helper for child process of spawn_inherit_streams */
   2028 #ifndef _WIN32
   2029 void spawn_stdin_stdout(void) {
   2030   char buf[1024];
   2031   char* pbuf;
   2032   for (;;) {
   2033     ssize_t r, w, c;
   2034     do {
   2035       r = read(0, buf, sizeof buf);
   2036     } while (r == -1 && errno == EINTR);
   2037     if (r == 0) {
   2038       return;
   2039     }
   2040     ASSERT_GT(r, 0);
   2041     c = r;
   2042     pbuf = buf;
   2043     while (c) {
   2044       do {
   2045         w = write(1, pbuf, (size_t)c);
   2046       } while (w == -1 && errno == EINTR);
   2047       ASSERT_GE(w, 0);
   2048       pbuf = pbuf + w;
   2049       c = c - w;
   2050     }
   2051   }
   2052 }
   2053 #else
   2054 void spawn_stdin_stdout(void) {
   2055   char buf[1024];
   2056   char* pbuf;
   2057   HANDLE h_stdin = GetStdHandle(STD_INPUT_HANDLE);
   2058   HANDLE h_stdout = GetStdHandle(STD_OUTPUT_HANDLE);
   2059   ASSERT_PTR_NE(h_stdin, INVALID_HANDLE_VALUE);
   2060   ASSERT_PTR_NE(h_stdout, INVALID_HANDLE_VALUE);
   2061   for (;;) {
   2062     DWORD n_read;
   2063     DWORD n_written;
   2064     DWORD to_write;
   2065     if (!ReadFile(h_stdin, buf, sizeof buf, &n_read, NULL)) {
   2066       ASSERT_EQ(GetLastError(), ERROR_BROKEN_PIPE);
   2067       return;
   2068     }
   2069     to_write = n_read;
   2070     pbuf = buf;
   2071     while (to_write) {
   2072       ASSERT(WriteFile(h_stdout, pbuf, to_write, &n_written, NULL));
   2073       to_write -= n_written;
   2074       pbuf += n_written;
   2075     }
   2076   }
   2077 }
   2078 #endif /* !_WIN32 */
   2079 
   2080 TEST_IMPL(spawn_relative_path) {
   2081   char* sep;
   2082 
   2083   init_process_options("spawn_helper1", exit_cb);
   2084 
   2085   exepath_size = sizeof(exepath) - 2;
   2086   ASSERT_OK(uv_exepath(exepath, &exepath_size));
   2087   exepath[exepath_size] = '\0';
   2088 
   2089   /* Poor man's basename(3). */
   2090   sep = strrchr(exepath, '/');
   2091   if (sep == NULL)
   2092     sep = strrchr(exepath, '\\');
   2093   ASSERT_NOT_NULL(sep);
   2094 
   2095   /* Split into dirname and basename and make basename relative. */
   2096   memmove(sep + 2, sep, 1 + strlen(sep));
   2097   sep[0] = '\0';
   2098   sep[1] = '.';
   2099   sep[2] = '/';
   2100 
   2101   options.cwd = exepath;
   2102   options.file = options.args[0] = sep + 1;
   2103 
   2104   ASSERT_OK(uv_spawn(uv_default_loop(), &process, &options));
   2105   ASSERT_OK(uv_run(uv_default_loop(), UV_RUN_DEFAULT));
   2106 
   2107   ASSERT_EQ(1, exit_cb_called);
   2108   ASSERT_EQ(1, close_cb_called);
   2109 
   2110   MAKE_VALGRIND_HAPPY(uv_default_loop());
   2111   return 0;
   2112 }
   2113