Skip to content
This repository
Browse code

Implement timeout handling

  • Loading branch information...
commit 4bb7bee1030baff31f9e53f508950656d62e28d3 1 parent de1c1a7
Felix Geisendörfer felixge authored piscisaureus committed
1  include/uv.h
@@ -894,6 +894,7 @@ typedef struct uv_spawn_sync_t{
894 894 int stderr_read;
895 895
896 896 int pid;
  897 + int exit_timeout;
897 898 int exit_code;
898 899 int exit_signal;
899 900 } uv_spawn_sync_t;
33 src/unix/process.c
@@ -299,17 +299,17 @@ int uv_process_kill(uv_process_t* process, int signum) {
299 299 }
300 300 }
301 301
302   -static int spawn_sync_pipe[2];
  302 +static int sigchld_pipe[2];
303 303
304 304 #define MAX(a, b) ((a) > (b) ? (a) : (b))
305 305
306 306 void SyncCHLDHandler(int sig) {
307 307 char c;
308 308 assert(sig == SIGCHLD);
309   - assert(spawn_sync_pipe[0] >= 0);
310   - assert(spawn_sync_pipe[1] >= 0);
  309 + assert(sigchld_pipe[0] >= 0);
  310 + assert(sigchld_pipe[1] >= 0);
311 311
312   - write(spawn_sync_pipe[1], &c, 1);
  312 + write(sigchld_pipe[1], &c, 1);
313 313 }
314 314
315 315 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) {
326 326 spawn->pid = -1;
327 327 spawn->exit_code = -1;
328 328 spawn->exit_signal = -1;
  329 + spawn->exit_timeout = 0;
329 330 spawn->stdout_read = 0;
330 331 spawn->stderr_read = 0;
331 332
@@ -339,7 +340,7 @@ int uv_spawn_sync(uv_loop_t* loop, uv_spawn_sync_t* spawn) {
339 340 return -1;
340 341 }
341 342
342   - if (pipe(spawn_sync_pipe)) {
  343 + if (pipe(sigchld_pipe)) {
343 344 perror("pipe");
344 345 return -1;
345 346 }
@@ -372,7 +373,7 @@ int uv_spawn_sync(uv_loop_t* loop, uv_spawn_sync_t* spawn) {
372 373 }
373 374
374 375 /* parent */
375   - nfds = spawn_sync_pipe[0];
  376 + nfds = sigchld_pipe[0];
376 377
377 378 if (spawn->stdout_buf) {
378 379 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) {
412 413 FD_SET(stderr_pipe[0], &pipes);
413 414 }
414 415
415   - FD_SET(spawn_sync_pipe[0], &pipes);
  416 + FD_SET(sigchld_pipe[0], &pipes);
416 417
417 418 elapsed = uv_now(loop) - start_time;
418 419 time_to_timeout = spawn->timeout - elapsed;
@@ -433,8 +434,8 @@ int uv_spawn_sync(uv_loop_t* loop, uv_spawn_sync_t* spawn) {
433 434
434 435 if (r == 0) {
435 436 /* timeout */
436   - close(spawn_sync_pipe[0]);
437   - close(spawn_sync_pipe[1]);
  437 + close(sigchld_pipe[0]);
  438 + close(sigchld_pipe[1]);
438 439
439 440 if (spawn->stdout_buf) {
440 441 close(stdout_pipe[0]);
@@ -445,8 +446,8 @@ int uv_spawn_sync(uv_loop_t* loop, uv_spawn_sync_t* spawn) {
445 446 }
446 447
447 448 kill(spawn->pid, SIGKILL);
448   - perror("timeout");
449   - return -1;
  449 + spawn->exit_timeout = 1;
  450 + return 0;
450 451 }
451 452
452 453 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) {
479 480 spawn->stderr_read += r;
480 481 }
481 482
482   - if (FD_ISSET(spawn_sync_pipe[0], &pipes)) {
  483 + if (FD_ISSET(sigchld_pipe[0], &pipes)) {
483 484 /* The child process has exited. */
484 485 int status;
485 486
@@ -489,8 +490,8 @@ int uv_spawn_sync(uv_loop_t* loop, uv_spawn_sync_t* spawn) {
489 490 goto error;
490 491 }
491 492
492   - close(spawn_sync_pipe[0]);
493   - close(spawn_sync_pipe[1]);
  493 + close(sigchld_pipe[0]);
  494 + close(sigchld_pipe[1]);
494 495
495 496 if (spawn->stdout_buf) {
496 497 close(stdout_pipe[0]);
@@ -515,8 +516,8 @@ int uv_spawn_sync(uv_loop_t* loop, uv_spawn_sync_t* spawn) {
515 516 }
516 517
517 518 error:
518   - close(spawn_sync_pipe[0]);
519   - close(spawn_sync_pipe[1]);
  519 + close(sigchld_pipe[0]);
  520 + close(sigchld_pipe[1]);
520 521
521 522 if (spawn->stdout_buf) {
522 523 close(stdout_pipe[0]);
2  test/test-list.h
@@ -85,6 +85,7 @@ TEST_DECLARE (spawn_sync_stdio)
85 85 TEST_DECLARE (spawn_sync_stdout)
86 86 TEST_DECLARE (spawn_sync_stderr)
87 87 TEST_DECLARE (spawn_sync_combine_stdio)
  88 +TEST_DECLARE (spawn_sync_timeout)
88 89 TEST_DECLARE (fs_file_noent)
89 90 TEST_DECLARE (fs_file_async)
90 91 TEST_DECLARE (fs_file_sync)
@@ -213,6 +214,7 @@ TASK_LIST_START
213 214 TEST_ENTRY (spawn_sync_stdout)
214 215 TEST_ENTRY (spawn_sync_stderr)
215 216 TEST_ENTRY (spawn_sync_combine_stdio)
  217 + TEST_ENTRY (spawn_sync_timeout)
216 218 #ifdef _WIN32
217 219 TEST_ENTRY (spawn_detect_pipe_name_collisions_on_windows)
218 220 TEST_ENTRY (argument_escaping)
24 test/test-spawn-sync.c
@@ -59,6 +59,7 @@ void debug(int r) {
59 59 fprintf(stderr, "spawn.stderr_read: %i\n", spawn.stderr_read);
60 60 fprintf(stderr, "spawn.stderr_size: %i\n", spawn.stderr_size);
61 61 fprintf(stderr, "spawn.stderr: %s\n", spawn.stderr_buf);
  62 + fprintf(stderr, "spawn.exit_timeout: %i\n", spawn.exit_timeout);
62 63 fprintf(stderr, "spawn.exit_code: %i\n", spawn.exit_code);
63 64 fprintf(stderr, "spawn.exit_signal: %i\n", spawn.exit_signal);
64 65 }
@@ -70,6 +71,7 @@ TEST_IMPL(spawn_sync_exit_code) {
70 71 init_process_options("spawn_helper1");
71 72
72 73 r = uv_spawn_sync(uv_default_loop(), &spawn);
  74 + debug(r);
73 75
74 76 ASSERT(spawn.pid >= 0);
75 77 ASSERT(r == 0);
@@ -86,6 +88,7 @@ TEST_IMPL(spawn_sync_exit_signal) {
86 88 init_process_options("spawn_helper_suicide");
87 89
88 90 r = uv_spawn_sync(uv_default_loop(), &spawn);
  91 + debug(r);
89 92
90 93 ASSERT(r == 0);
91 94 ASSERT(spawn.exit_signal == SIGKILL);
@@ -103,7 +106,6 @@ TEST_IMPL(spawn_sync_stdio) {
103 106 init_process_options("stdout_stderr");
104 107
105 108 r = uv_spawn_sync(uv_default_loop(), &spawn);
106   -
107 109 debug(r);
108 110
109 111 ASSERT(r == 0);
@@ -125,7 +127,6 @@ TEST_IMPL(spawn_sync_stdout) {
125 127 spawn.stderr_buf = NULL;
126 128
127 129 r = uv_spawn_sync(uv_default_loop(), &spawn);
128   -
129 130 debug(r);
130 131
131 132 ASSERT(r == 0);
@@ -146,7 +147,6 @@ TEST_IMPL(spawn_sync_stderr) {
146 147 spawn.stdout_buf = NULL;
147 148
148 149 r = uv_spawn_sync(uv_default_loop(), &spawn);
149   -
150 150 debug(r);
151 151
152 152 ASSERT(r == 0);
@@ -168,7 +168,6 @@ TEST_IMPL(spawn_sync_combine_stdio) {
168 168 spawn.combine = 1;
169 169
170 170 r = uv_spawn_sync(uv_default_loop(), &spawn);
171   -
172 171 debug(r);
173 172
174 173 ASSERT(r == 0);
@@ -177,3 +176,20 @@ TEST_IMPL(spawn_sync_combine_stdio) {
177 176
178 177 return 0;
179 178 }
  179 +
  180 +TEST_IMPL(spawn_sync_timeout) {
  181 + int r;
  182 + uv_init();
  183 +
  184 + init_process_options("spawn_helper4");
  185 +
  186 + r = uv_spawn_sync(uv_default_loop(), &spawn);
  187 + debug(r);
  188 +
  189 + ASSERT(r == 0);
  190 + ASSERT(spawn.exit_timeout == 1);
  191 + ASSERT(spawn.exit_signal == -1);
  192 + ASSERT(spawn.exit_code == -1);
  193 +
  194 + return 0;
  195 +}

0 comments on commit 4bb7bee

Please sign in to comment.
Something went wrong with that request. Please try again.