Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Browse files

Implement timeout handling

  • Loading branch information...
commit 4bb7bee1030baff31f9e53f508950656d62e28d3 1 parent de1c1a7
Felix Geisendörfer felixge authored piscisaureus committed
1  include/uv.h
View
@@ -894,6 +894,7 @@ typedef struct uv_spawn_sync_t{
int stderr_read;
int pid;
+ int exit_timeout;
int exit_code;
int exit_signal;
} uv_spawn_sync_t;
33 src/unix/process.c
View
@@ -299,17 +299,17 @@ int uv_process_kill(uv_process_t* process, int signum) {
}
}
-static int spawn_sync_pipe[2];
+static int sigchld_pipe[2];
#define MAX(a, b) ((a) > (b) ? (a) : (b))
void SyncCHLDHandler(int sig) {
char c;
assert(sig == SIGCHLD);
- assert(spawn_sync_pipe[0] >= 0);
- assert(spawn_sync_pipe[1] >= 0);
+ assert(sigchld_pipe[0] >= 0);
+ assert(sigchld_pipe[1] >= 0);
- write(spawn_sync_pipe[1], &c, 1);
+ write(sigchld_pipe[1], &c, 1);
}
int uv_spawn_sync(uv_loop_t* loop, uv_spawn_sync_t* spawn) {
@@ -326,6 +326,7 @@ int uv_spawn_sync(uv_loop_t* loop, uv_spawn_sync_t* spawn) {
spawn->pid = -1;
spawn->exit_code = -1;
spawn->exit_signal = -1;
+ spawn->exit_timeout = 0;
spawn->stdout_read = 0;
spawn->stderr_read = 0;
@@ -339,7 +340,7 @@ int uv_spawn_sync(uv_loop_t* loop, uv_spawn_sync_t* spawn) {
return -1;
}
- if (pipe(spawn_sync_pipe)) {
+ if (pipe(sigchld_pipe)) {
perror("pipe");
return -1;
}
@@ -372,7 +373,7 @@ int uv_spawn_sync(uv_loop_t* loop, uv_spawn_sync_t* spawn) {
}
/* parent */
- nfds = spawn_sync_pipe[0];
+ nfds = sigchld_pipe[0];
if (spawn->stdout_buf) {
close(stdout_pipe[1]); /* close the write end */
@@ -412,7 +413,7 @@ int uv_spawn_sync(uv_loop_t* loop, uv_spawn_sync_t* spawn) {
FD_SET(stderr_pipe[0], &pipes);
}
- FD_SET(spawn_sync_pipe[0], &pipes);
+ FD_SET(sigchld_pipe[0], &pipes);
elapsed = uv_now(loop) - start_time;
time_to_timeout = spawn->timeout - elapsed;
@@ -433,8 +434,8 @@ int uv_spawn_sync(uv_loop_t* loop, uv_spawn_sync_t* spawn) {
if (r == 0) {
/* timeout */
- close(spawn_sync_pipe[0]);
- close(spawn_sync_pipe[1]);
+ close(sigchld_pipe[0]);
+ close(sigchld_pipe[1]);
if (spawn->stdout_buf) {
close(stdout_pipe[0]);
@@ -445,8 +446,8 @@ int uv_spawn_sync(uv_loop_t* loop, uv_spawn_sync_t* spawn) {
}
kill(spawn->pid, SIGKILL);
- perror("timeout");
- return -1;
+ spawn->exit_timeout = 1;
+ return 0;
}
if (spawn->stdout_buf && FD_ISSET(stdout_pipe[0], &pipes)) {
@@ -479,7 +480,7 @@ int uv_spawn_sync(uv_loop_t* loop, uv_spawn_sync_t* spawn) {
spawn->stderr_read += r;
}
- if (FD_ISSET(spawn_sync_pipe[0], &pipes)) {
+ if (FD_ISSET(sigchld_pipe[0], &pipes)) {
/* The child process has exited. */
int status;
@@ -489,8 +490,8 @@ int uv_spawn_sync(uv_loop_t* loop, uv_spawn_sync_t* spawn) {
goto error;
}
- close(spawn_sync_pipe[0]);
- close(spawn_sync_pipe[1]);
+ close(sigchld_pipe[0]);
+ close(sigchld_pipe[1]);
if (spawn->stdout_buf) {
close(stdout_pipe[0]);
@@ -515,8 +516,8 @@ 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(sigchld_pipe[0]);
+ close(sigchld_pipe[1]);
if (spawn->stdout_buf) {
close(stdout_pipe[0]);
2  test/test-list.h
View
@@ -85,6 +85,7 @@ TEST_DECLARE (spawn_sync_stdio)
TEST_DECLARE (spawn_sync_stdout)
TEST_DECLARE (spawn_sync_stderr)
TEST_DECLARE (spawn_sync_combine_stdio)
+TEST_DECLARE (spawn_sync_timeout)
TEST_DECLARE (fs_file_noent)
TEST_DECLARE (fs_file_async)
TEST_DECLARE (fs_file_sync)
@@ -213,6 +214,7 @@ TASK_LIST_START
TEST_ENTRY (spawn_sync_stdout)
TEST_ENTRY (spawn_sync_stderr)
TEST_ENTRY (spawn_sync_combine_stdio)
+ TEST_ENTRY (spawn_sync_timeout)
#ifdef _WIN32
TEST_ENTRY (spawn_detect_pipe_name_collisions_on_windows)
TEST_ENTRY (argument_escaping)
24 test/test-spawn-sync.c
View
@@ -59,6 +59,7 @@ void debug(int r) {
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_timeout: %i\n", spawn.exit_timeout);
fprintf(stderr, "spawn.exit_code: %i\n", spawn.exit_code);
fprintf(stderr, "spawn.exit_signal: %i\n", spawn.exit_signal);
}
@@ -70,6 +71,7 @@ TEST_IMPL(spawn_sync_exit_code) {
init_process_options("spawn_helper1");
r = uv_spawn_sync(uv_default_loop(), &spawn);
+ debug(r);
ASSERT(spawn.pid >= 0);
ASSERT(r == 0);
@@ -86,6 +88,7 @@ TEST_IMPL(spawn_sync_exit_signal) {
init_process_options("spawn_helper_suicide");
r = uv_spawn_sync(uv_default_loop(), &spawn);
+ debug(r);
ASSERT(r == 0);
ASSERT(spawn.exit_signal == SIGKILL);
@@ -103,7 +106,6 @@ TEST_IMPL(spawn_sync_stdio) {
init_process_options("stdout_stderr");
r = uv_spawn_sync(uv_default_loop(), &spawn);
-
debug(r);
ASSERT(r == 0);
@@ -125,7 +127,6 @@ TEST_IMPL(spawn_sync_stdout) {
spawn.stderr_buf = NULL;
r = uv_spawn_sync(uv_default_loop(), &spawn);
-
debug(r);
ASSERT(r == 0);
@@ -146,7 +147,6 @@ TEST_IMPL(spawn_sync_stderr) {
spawn.stdout_buf = NULL;
r = uv_spawn_sync(uv_default_loop(), &spawn);
-
debug(r);
ASSERT(r == 0);
@@ -168,7 +168,6 @@ TEST_IMPL(spawn_sync_combine_stdio) {
spawn.combine = 1;
r = uv_spawn_sync(uv_default_loop(), &spawn);
-
debug(r);
ASSERT(r == 0);
@@ -177,3 +176,20 @@ TEST_IMPL(spawn_sync_combine_stdio) {
return 0;
}
+
+TEST_IMPL(spawn_sync_timeout) {
+ int r;
+ uv_init();
+
+ init_process_options("spawn_helper4");
+
+ r = uv_spawn_sync(uv_default_loop(), &spawn);
+ debug(r);
+
+ ASSERT(r == 0);
+ ASSERT(spawn.exit_timeout == 1);
+ ASSERT(spawn.exit_signal == -1);
+ ASSERT(spawn.exit_code == -1);
+
+ return 0;
+}
Please sign in to comment.
Something went wrong with that request. Please try again.