From 847d87fd3f74a675ca4bcf1175153851b0cdcc68 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Felix=20Geisendo=CC=88rfer?= Date: Tue, 13 Sep 2011 16:15:55 -0700 Subject: [PATCH] Initial stdin support Not correct yet. --- include/uv.h | 3 +++ src/unix/process.c | 28 ++++++++++++++++++++++++++++ test/test-list.h | 2 ++ test/test-spawn-sync.c | 21 ++++++++++++++++++++- 4 files changed, 53 insertions(+), 1 deletion(-) diff --git a/include/uv.h b/include/uv.h index 8dac6f3231..30e22837d3 100644 --- a/include/uv.h +++ b/include/uv.h @@ -885,6 +885,9 @@ typedef struct uv_spawn_sync_t{ int combine; + char *stdin_buf; + int stdin_size; + char *stdout_buf; int stdout_read; int stdout_size; diff --git a/src/unix/process.c b/src/unix/process.c index 6439fbc20b..da1bbcab1f 100644 --- a/src/unix/process.c +++ b/src/unix/process.c @@ -313,6 +313,7 @@ void SyncCHLDHandler(int sig) { } int uv_spawn_sync(uv_loop_t* loop, uv_spawn_sync_t* spawn) { + int stdin_pipe[2]; int stdout_pipe[2]; int stderr_pipe[2]; int nfds; @@ -330,6 +331,11 @@ int uv_spawn_sync(uv_loop_t* loop, uv_spawn_sync_t* spawn) { spawn->stdout_read = 0; spawn->stderr_read = 0; + if (spawn->stdin_buf && pipe(stdin_pipe)) { + uv_err_new(loop, errno); + return -1; + } + if (spawn->stdout_buf && pipe(stdout_pipe)) { uv_err_new(loop, errno); return -1; @@ -351,6 +357,11 @@ int uv_spawn_sync(uv_loop_t* loop, uv_spawn_sync_t* spawn) { return -1; case 0: /* child */ + if (spawn->stdin_buf) { + close(stdin_pipe[1]); /* close write end */ + dup2(stdin_pipe[0], STDIN_FILENO); + } + if (spawn->stdout_buf) { close(stdout_pipe[0]); /* close read end */ dup2(stdout_pipe[1], STDOUT_FILENO); @@ -385,6 +396,11 @@ int uv_spawn_sync(uv_loop_t* loop, uv_spawn_sync_t* spawn) { nfds = MAX(nfds, stderr_pipe[0]); } + if (spawn->stdin_buf) { + int c = write(stdin_pipe[1], spawn->stdin_buf, spawn->stdin_size); + close(stdin_pipe[0]); /* close the read end */ + } + nfds = nfds + 1; start_time = uv_now(loop); /* time in ms */ @@ -437,6 +453,10 @@ int uv_spawn_sync(uv_loop_t* loop, uv_spawn_sync_t* spawn) { close(sigchld_pipe[0]); close(sigchld_pipe[1]); + if (spawn->stdin_buf) { + close(stdin_pipe[1]); + } + if (spawn->stdout_buf) { close(stdout_pipe[0]); } @@ -497,6 +517,10 @@ int uv_spawn_sync(uv_loop_t* loop, uv_spawn_sync_t* spawn) { close(sigchld_pipe[0]); close(sigchld_pipe[1]); + if (spawn->stdin_buf) { + close(stdin_pipe[1]); + } + if (spawn->stdout_buf) { close(stdout_pipe[0]); } @@ -523,6 +547,10 @@ int uv_spawn_sync(uv_loop_t* loop, uv_spawn_sync_t* spawn) { close(sigchld_pipe[0]); close(sigchld_pipe[1]); + if (spawn->stdin_buf) { + close(stdin_pipe[1]); + } + if (spawn->stdout_buf) { close(stdout_pipe[0]); } diff --git a/test/test-list.h b/test/test-list.h index dfcabcd85c..a1c63e0376 100644 --- a/test/test-list.h +++ b/test/test-list.h @@ -87,6 +87,7 @@ TEST_DECLARE (spawn_sync_stderr) TEST_DECLARE (spawn_sync_stdout_overflow) TEST_DECLARE (spawn_sync_stderr_overflow) TEST_DECLARE (spawn_sync_combine_stdio) +TEST_DECLARE (spawn_sync_stdin) TEST_DECLARE (spawn_sync_timeout) TEST_DECLARE (fs_file_noent) TEST_DECLARE (fs_file_async) @@ -218,6 +219,7 @@ TASK_LIST_START TEST_ENTRY (spawn_sync_stdout_overflow) TEST_ENTRY (spawn_sync_stderr_overflow) TEST_ENTRY (spawn_sync_combine_stdio) + TEST_ENTRY (spawn_sync_stdin) TEST_ENTRY (spawn_sync_timeout) #ifdef _WIN32 TEST_ENTRY (spawn_detect_pipe_name_collisions_on_windows) diff --git a/test/test-spawn-sync.c b/test/test-spawn-sync.c index c3615c10f6..3af53f8484 100644 --- a/test/test-spawn-sync.c +++ b/test/test-spawn-sync.c @@ -47,7 +47,7 @@ static void init_process_options(char* test) { spawn.stdout_size = 1024; spawn.stdout_buf = malloc(spawn.stdout_size); spawn.stderr_size = 1024; - spawn.stderr_buf = malloc(spawn.stdout_size); + spawn.stderr_buf = malloc(spawn.stderr_size); } void debug(int r) { @@ -218,6 +218,25 @@ TEST_IMPL(spawn_sync_combine_stdio) { return 0; } +TEST_IMPL(spawn_sync_stdin) { + int r; + uv_init(); + + init_process_options("spawn_helper_stdin"); + + spawn.stdin_buf = "stdin\n"; + spawn.stdin_size = strlen(spawn.stdin_buf); + + r = uv_spawn_sync(uv_default_loop(), &spawn); + debug(r); + + ASSERT(r == 0); + ASSERT(strcmp(spawn.stdout_buf, spawn.stdin_buf) == 0); + ASSERT(spawn.stdout_read == strlen(spawn.stdin_buf)); + + return 0; +} + TEST_IMPL(spawn_sync_timeout) { int r; uv_init();