Browse files

Support getting either stdout or stderr

  • Loading branch information...
1 parent 4935802 commit c374a955e924ab63c569102e947524867d676ee5 @felixge felixge committed with piscisaureus Sep 9, 2011
Showing with 111 additions and 23 deletions.
  1. +62 −23 src/unix/process.c
  2. +4 −0 test/test-list.h
  3. +45 −0 test/test-spawn-sync.c
View
85 src/unix/process.c
@@ -327,13 +327,14 @@ int uv_spawn_sync(uv_loop_t* loop, uv_spawn_sync_t* spawn) {
spawn->exit_code = -1;
spawn->exit_signal = -1;
spawn->stdout_read = 0;
+ spawn->stderr_read = 0;
- if (pipe(stdout_pipe)) {
+ if (spawn->stdout_buf && pipe(stdout_pipe)) {
perror("pipe");
return -1;
}
- if (pipe(stderr_pipe)) {
+ if (spawn->stderr_buf && pipe(stderr_pipe)) {
perror("pipe");
return -1;
}
@@ -349,14 +350,17 @@ int uv_spawn_sync(uv_loop_t* loop, uv_spawn_sync_t* spawn) {
return -1;
case 0: /* child */
- /* close read ends */
- close(stdout_pipe[0]);
- close(stderr_pipe[0]);
+ if (spawn->stdout_buf) {
+ close(stdout_pipe[0]); /* close read end */
+ dup2(stdout_pipe[1], STDOUT_FILENO);
- dup2(stdout_pipe[1], STDOUT_FILENO);
- if (spawn->combine) {
- dup2(stdout_pipe[1], STDERR_FILENO);
- } else {
+ if (spawn->combine) {
+ dup2(stdout_pipe[1], STDERR_FILENO);
+ }
+ }
+
+ if (spawn->stderr_buf) {
+ close(stderr_pipe[0]); /* close read end */
dup2(stderr_pipe[1], STDERR_FILENO);
}
@@ -367,11 +371,19 @@ int uv_spawn_sync(uv_loop_t* loop, uv_spawn_sync_t* spawn) {
}
/* parent */
- /* close the write ends */
- close(stdout_pipe[1]);
- close(stderr_pipe[1]);
+ nfds = spawn_sync_pipe[0];
+
+ if (spawn->stdout_buf) {
+ close(stdout_pipe[1]); /* close the write end */
+ nfds = MAX(nfds, stdout_pipe[0]);
+ }
+
+ if (spawn->stderr_buf) {
+ close(stderr_pipe[1]); /* close the write end */
+ nfds = MAX(nfds, stderr_pipe[0]);
+ }
- nfds = MAX(MAX(stdout_pipe[0], stderr_pipe[0]), spawn_sync_pipe[0]) + 1;
+ nfds = nfds + 1;
start_time = uv_now(loop); /* time in ms */
/* Set up sighandling */
@@ -390,8 +402,15 @@ int uv_spawn_sync(uv_loop_t* loop, uv_spawn_sync_t* spawn) {
int r;
FD_ZERO(&pipes);
- FD_SET(stdout_pipe[0], &pipes);
- FD_SET(stderr_pipe[0], &pipes);
+
+ if (spawn->stdout_buf) {
+ FD_SET(stdout_pipe[0], &pipes);
+ }
+
+ if (spawn->stderr_buf) {
+ FD_SET(stderr_pipe[0], &pipes);
+ }
+
FD_SET(spawn_sync_pipe[0], &pipes);
elapsed = uv_now(loop) - start_time;
@@ -415,14 +434,21 @@ int uv_spawn_sync(uv_loop_t* loop, uv_spawn_sync_t* spawn) {
/* timeout */
close(spawn_sync_pipe[0]);
close(spawn_sync_pipe[1]);
- close(stdout_pipe[0]);
- close(stderr_pipe[0]);
+
+ if (spawn->stdout_buf) {
+ close(stdout_pipe[0]);
+ }
+
+ if (spawn->stderr_buf) {
+ close(stderr_pipe[0]);
+ }
+
kill(spawn->pid, SIGKILL);
perror("timeout");
return -1;
}
- if (FD_ISSET(stdout_pipe[0], &pipes)) {
+ if (spawn->stdout_buf && FD_ISSET(stdout_pipe[0], &pipes)) {
/* Check for buffer overflow. */
if (spawn->stdout_size - spawn->stdout_read <= 0) {
perror("buffer overflow");
@@ -437,7 +463,7 @@ int uv_spawn_sync(uv_loop_t* loop, uv_spawn_sync_t* spawn) {
spawn->stdout_read += r;
}
- if (FD_ISSET(stderr_pipe[0], &pipes)) {
+ if (spawn->stderr_buf && FD_ISSET(stderr_pipe[0], &pipes)) {
/* Check for buffer overflow. */
if (spawn->stderr_size - spawn->stderr_read <= 0) {
perror("buffer overflow");
@@ -464,8 +490,14 @@ int uv_spawn_sync(uv_loop_t* loop, uv_spawn_sync_t* spawn) {
close(spawn_sync_pipe[0]);
close(spawn_sync_pipe[1]);
- close(stdout_pipe[0]);
- close(stderr_pipe[0]);
+
+ if (spawn->stdout_buf) {
+ close(stdout_pipe[0]);
+ }
+
+ if (spawn->stderr_buf) {
+ close(stderr_pipe[0]);
+ }
if (WIFEXITED(status)) {
spawn->exit_code = WEXITSTATUS(status);
@@ -484,8 +516,15 @@ int uv_spawn_sync(uv_loop_t* loop, uv_spawn_sync_t* spawn) {
error:
close(spawn_sync_pipe[0]);
close(spawn_sync_pipe[1]);
- close(stdout_pipe[0]);
- close(stderr_pipe[0]);
+
+ if (spawn->stdout_buf) {
+ close(stdout_pipe[0]);
+ }
+
+ if (spawn->stderr_buf) {
+ close(stderr_pipe[0]);
+ }
+
kill(spawn->pid, SIGKILL);
return -1;
}
View
4 test/test-list.h
@@ -82,6 +82,8 @@ TEST_DECLARE (spawn_and_kill)
TEST_DECLARE (spawn_sync_exit_code)
TEST_DECLARE (spawn_sync_exit_signal)
TEST_DECLARE (spawn_sync_stdio)
+TEST_DECLARE (spawn_sync_stdout)
+TEST_DECLARE (spawn_sync_stderr)
TEST_DECLARE (spawn_sync_combine_stdio)
TEST_DECLARE (fs_file_noent)
TEST_DECLARE (fs_file_async)
@@ -208,6 +210,8 @@ TASK_LIST_START
TEST_ENTRY (spawn_sync_exit_code)
TEST_ENTRY (spawn_sync_exit_signal)
TEST_ENTRY (spawn_sync_stdio)
+ TEST_ENTRY (spawn_sync_stdout)
+ TEST_ENTRY (spawn_sync_stderr)
TEST_ENTRY (spawn_sync_combine_stdio)
#ifdef _WIN32
TEST_ENTRY (spawn_detect_pipe_name_collisions_on_windows)
View
45 test/test-spawn-sync.c
@@ -56,6 +56,9 @@ void debug(int r) {
fprintf(stderr, "spawn.stdout_read: %i\n", spawn.stdout_read);
fprintf(stderr, "spawn.stdout_size: %i\n", spawn.stdout_size);
fprintf(stderr, "spawn.stdout: %s\n", spawn.stdout_buf);
+ fprintf(stderr, "spawn.stderr_read: %i\n", spawn.stderr_read);
+ fprintf(stderr, "spawn.stderr_size: %i\n", spawn.stderr_size);
+ fprintf(stderr, "spawn.stderr: %s\n", spawn.stderr_buf);
fprintf(stderr, "spawn.exit_code: %i\n", spawn.exit_code);
fprintf(stderr, "spawn.exit_signal: %i\n", spawn.exit_signal);
}
@@ -112,6 +115,48 @@ TEST_IMPL(spawn_sync_stdio) {
return 0;
}
+TEST_IMPL(spawn_sync_stdout) {
+ int r;
+ char *expected_stdout = "stdout\n";
+ uv_init();
+
+ init_process_options("stdout_stderr");
+
+ spawn.stderr_buf = NULL;
+
+ r = uv_spawn_sync(uv_default_loop(), &spawn);
+
+ debug(r);
+
+ ASSERT(r == 0);
+ ASSERT(strcmp(spawn.stdout_buf, expected_stdout) == 0);
+ ASSERT(spawn.stdout_read == strlen(expected_stdout));
+ ASSERT(spawn.stderr_read == 0);
+
+ return 0;
+}
+
+TEST_IMPL(spawn_sync_stderr) {
+ int r;
+ char *expected_stderr = "stderr\n";
+ uv_init();
+
+ init_process_options("stdout_stderr");
+
+ spawn.stdout_buf = NULL;
+
+ r = uv_spawn_sync(uv_default_loop(), &spawn);
+
+ debug(r);
+
+ ASSERT(r == 0);
+ ASSERT(strcmp(spawn.stderr_buf, expected_stderr) == 0);
+ ASSERT(spawn.stderr_read == strlen(expected_stderr));
+ ASSERT(spawn.stdout_read == 0);
+
+ return 0;
+}
+
TEST_IMPL(spawn_sync_combine_stdio) {
int r;
char *expected_stdout = "stdout\nstderr\n";

0 comments on commit c374a95

Please sign in to comment.