diff --git a/src/spawn_sync.cc b/src/spawn_sync.cc index d03803fe3abc5b..5dbacef9593c01 100644 --- a/src/spawn_sync.cc +++ b/src/spawn_sync.cc @@ -92,14 +92,15 @@ void SyncProcessOutputBuffer::set_next(SyncProcessOutputBuffer* next) { next_ = next; } - SyncProcessStdioPipe::SyncProcessStdioPipe(SyncProcessRunner* process_handler, bool readable, bool writable, + bool overlapped, uv_buf_t input_buffer) : process_handler_(process_handler), readable_(readable), writable_(writable), + overlapped_(overlapped), input_buffer_(input_buffer), first_output_buffer_(nullptr), @@ -113,7 +114,6 @@ SyncProcessStdioPipe::SyncProcessStdioPipe(SyncProcessRunner* process_handler, CHECK(readable || writable); } - SyncProcessStdioPipe::~SyncProcessStdioPipe() { CHECK(lifecycle_ == kUninitialized || lifecycle_ == kClosed); @@ -202,6 +202,9 @@ bool SyncProcessStdioPipe::writable() const { return writable_; } +bool SyncProcessStdioPipe::overlapped() const { + return overlapped_; +} uv_stdio_flags SyncProcessStdioPipe::uv_flags() const { unsigned int flags; @@ -211,6 +214,7 @@ uv_stdio_flags SyncProcessStdioPipe::uv_flags() const { flags |= UV_READABLE_PIPE; if (writable()) flags |= UV_WRITABLE_PIPE; + if (overlapped()) flags |= UV_OVERLAPPED_PIPE; return static_cast(flags); } @@ -909,7 +913,8 @@ int SyncProcessRunner::ParseStdioOption(int child_fd, if (js_type->StrictEquals(env()->ignore_string())) { return AddStdioIgnore(child_fd); - } else if (js_type->StrictEquals(env()->pipe_string())) { + } else if (js_type->StrictEquals(env()->pipe_string()) || + js_type->StrictEquals(env()->overlapped_string())) { Isolate* isolate = env()->isolate(); Local rs = env()->readable_string(); Local ws = env()->writable_string(); @@ -936,7 +941,8 @@ int SyncProcessRunner::ParseStdioOption(int child_fd, } } - return AddStdioPipe(child_fd, readable, writable, buf); + bool overlapped = js_type->StrictEquals(env()->overlapped_string()); + return AddStdioPipe(child_fd, readable, writable, overlapped, buf); } else if (js_type->StrictEquals(env()->inherit_string()) || js_type->StrictEquals(env()->fd_string())) { @@ -959,16 +965,16 @@ int SyncProcessRunner::AddStdioIgnore(uint32_t child_fd) { return 0; } - int SyncProcessRunner::AddStdioPipe(uint32_t child_fd, bool readable, bool writable, + bool overlapped, uv_buf_t input_buffer) { CHECK_LT(child_fd, stdio_count_); CHECK(!stdio_pipes_[child_fd]); - std::unique_ptr h( - new SyncProcessStdioPipe(this, readable, writable, input_buffer)); + std::unique_ptr h(new SyncProcessStdioPipe( + this, readable, writable, overlapped, input_buffer)); int r = h->Initialize(uv_loop_); if (r < 0) { @@ -984,7 +990,6 @@ int SyncProcessRunner::AddStdioPipe(uint32_t child_fd, return 0; } - int SyncProcessRunner::AddStdioInheritFD(uint32_t child_fd, int inherit_fd) { CHECK_LT(child_fd, stdio_count_); CHECK(!stdio_pipes_[child_fd]); diff --git a/src/spawn_sync.h b/src/spawn_sync.h index d5b74e67d83094..928c5fc6633469 100644 --- a/src/spawn_sync.h +++ b/src/spawn_sync.h @@ -75,6 +75,7 @@ class SyncProcessStdioPipe { SyncProcessStdioPipe(SyncProcessRunner* process_handler, bool readable, bool writable, + bool overlapped, uv_buf_t input_buffer); ~SyncProcessStdioPipe(); @@ -86,6 +87,7 @@ class SyncProcessStdioPipe { inline bool readable() const; inline bool writable() const; + inline bool overlapped() const; inline uv_stdio_flags uv_flags() const; inline uv_pipe_t* uv_pipe() const; @@ -118,6 +120,7 @@ class SyncProcessStdioPipe { bool readable_; bool writable_; + bool overlapped_; uv_buf_t input_buffer_; SyncProcessOutputBuffer* first_output_buffer_; @@ -182,6 +185,7 @@ class SyncProcessRunner { inline int AddStdioPipe(uint32_t child_fd, bool readable, bool writable, + bool overlapped, uv_buf_t input_buffer); inline int AddStdioInheritFD(uint32_t child_fd, int inherit_fd); diff --git a/test/parallel/test-child-process-stdio-overlapped.js b/test/parallel/test-child-process-stdio-overlapped.js index 5c48e7ee105792..4cefbc570b28c6 100644 --- a/test/parallel/test-child-process-stdio-overlapped.js +++ b/test/parallel/test-child-process-stdio-overlapped.js @@ -37,6 +37,17 @@ if (!require('fs').existsSync(exePath)) { common.skip(exe + ' binary is not available'); } +// We can't synchronously write to the child (the 'input' and 'stdio' options +// conflict) but we can at least verify it starts up normally and is then +// terminated by the timer watchdog. +const { error } = child_process.spawnSync(exePath, [], { + stdio: ['overlapped', 'pipe', 'pipe'], + timeout: 42, +}); + +assert.ok(error); +assert.strictEqual(error.code, 'ETIMEDOUT'); + const child = child_process.spawn(exePath, [], { stdio: ['overlapped', 'pipe', 'pipe'] });