From fd77a5d6c6466f8c9d7ea6221b946599320702bb Mon Sep 17 00:00:00 2001 From: Tonis Tiigi Date: Sun, 23 Mar 2014 12:48:06 +0200 Subject: [PATCH] process: don't close stdio fds during spawn This is needed when closed stdio fd is reused for uv_spawn pipe. Fixes #1211 --- src/unix/process.c | 2 +- test/test-list.h | 2 ++ test/test-spawn.c | 33 +++++++++++++++++++++++++++++++++ 3 files changed, 36 insertions(+), 1 deletion(-) diff --git a/src/unix/process.c b/src/unix/process.c index 406df5fd..19686a29 100644 --- a/src/unix/process.c +++ b/src/unix/process.c @@ -315,7 +315,7 @@ static void uv__process_child_init(uv_process_options_t options, if (fd <= 2) uv__nonblock(fd, 0); - if (close_fd != -1) + if (close_fd >= stdio_count) close(close_fd); } diff --git a/test/test-list.h b/test/test-list.h index 2d8942c3..c280ca95 100644 --- a/test/test-list.h +++ b/test/test-list.h @@ -163,6 +163,7 @@ TEST_DECLARE (spawn_setgid_fails) TEST_DECLARE (spawn_stdout_to_file) TEST_DECLARE (spawn_stdout_and_stderr_to_file) TEST_DECLARE (spawn_auto_unref) +TEST_DECLARE (spawn_closed_process_io) TEST_DECLARE (fs_poll) TEST_DECLARE (kill) TEST_DECLARE (fs_file_noent) @@ -443,6 +444,7 @@ TASK_LIST_START TEST_ENTRY (spawn_stdout_to_file) TEST_ENTRY (spawn_stdout_and_stderr_to_file) TEST_ENTRY (spawn_auto_unref) + TEST_ENTRY (spawn_closed_process_io) TEST_ENTRY (fs_poll) TEST_ENTRY (kill) diff --git a/test/test-spawn.c b/test/test-spawn.c index 337cd1d8..3afe0cbc 100644 --- a/test/test-spawn.c +++ b/test/test-spawn.c @@ -676,6 +676,39 @@ TEST_IMPL(spawn_same_stdout_stderr) { } +TEST_IMPL(spawn_closed_process_io) { + uv_pipe_t in; + uv_write_t write_req; + uv_buf_t buf; + uv_stdio_container_t stdio[2]; + static char buffer[] = "hello-from-spawn_stdin"; + + init_process_options("spawn_helper1", exit_cb); + + uv_pipe_init(uv_default_loop(), &in, 0); + options.stdio = stdio; + options.stdio[0].flags = UV_CREATE_PIPE | UV_READABLE_PIPE; + options.stdio[0].data.stream = (uv_stream_t*) ∈ + options.stdio_count = 1; + + close(0); /* Close process stdin. */ + + ASSERT(0 == uv_spawn(uv_default_loop(), &process, options)); + + buf.base = buffer; + buf.len = sizeof(buffer); + ASSERT(0 == uv_write(&write_req, (uv_stream_t*) &in, &buf, 1, write_cb)); + + ASSERT(0 == uv_run(uv_default_loop(), UV_RUN_DEFAULT)); + + ASSERT(exit_cb_called == 1); + ASSERT(close_cb_called == 2); /* process, child stdin */ + + MAKE_VALGRIND_HAPPY(); + return 0; +} + + TEST_IMPL(kill) { int r; uv_err_t err;