Skip to content

Commit 93aedba

Browse files
committed
Fixes: #52776
1 parent 052aec7 commit 93aedba

File tree

3 files changed

+59
-4
lines changed

3 files changed

+59
-4
lines changed

src/spawn_sync.cc

Lines changed: 31 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,7 @@
2525
#include "node_errors.h"
2626
#include "node_external_reference.h"
2727
#include "node_internals.h"
28+
#include "stream_wrap.h"
2829
#include "string_bytes.h"
2930
#include "util-inl.h"
3031

@@ -1063,12 +1064,26 @@ Maybe<int> SyncProcessRunner::ParseStdioOption(int child_fd,
10631064
return Nothing<int>();
10641065
}
10651066
return Just(AddStdioInheritFD(child_fd, inherit_fd));
1066-
}
1067+
} else if (js_type->StrictEquals(env()->wrap_string())) {
1068+
Local<Value> val;
1069+
if (!js_stdio_option->Get(context, env()->handle_string()).ToLocal(&val)) {
1070+
return Nothing<int>();
1071+
}
1072+
if (!val->IsObject()) {
1073+
return Just<int>(UV_EINVAL);
1074+
}
1075+
1076+
Local<Object> handle = val.As<Object>();
1077+
Local<v8::FunctionTemplate> sw = env()->libuv_stream_wrap_ctor_template();
1078+
if (sw.IsEmpty() || !sw->HasInstance(handle)) {
1079+
return Just<int>(UV_EINVAL);
1080+
}
10671081

1068-
Utf8Value stdio_type(env()->isolate(), js_type);
1069-
fprintf(stderr, "invalid child stdio type: %s\n", stdio_type.out());
1082+
uv_stream_t* stream = LibuvStreamWrap::From(env(), handle)->stream();
1083+
return Just(AddStdioInheritStream(child_fd, stream));
1084+
}
10701085

1071-
UNREACHABLE();
1086+
return Just<int>(UV_EINVAL);
10721087
}
10731088

10741089
int SyncProcessRunner::AddStdioIgnore(uint32_t child_fd) {
@@ -1116,6 +1131,18 @@ int SyncProcessRunner::AddStdioInheritFD(uint32_t child_fd, int inherit_fd) {
11161131
return 0;
11171132
}
11181133

1134+
1135+
int SyncProcessRunner::AddStdioInheritStream(uint32_t child_fd,
1136+
uv_stream_t* stream) {
1137+
CHECK_LT(child_fd, stdio_count_);
1138+
CHECK(!stdio_pipes_[child_fd]);
1139+
1140+
uv_stdio_containers_[child_fd].flags = UV_INHERIT_STREAM;
1141+
uv_stdio_containers_[child_fd].data.stream = stream;
1142+
1143+
return 0;
1144+
}
1145+
11191146
Maybe<int> SyncProcessRunner::CopyJsString(Local<Value> js_value,
11201147
const char** target) {
11211148
Isolate* isolate = env()->isolate();

src/spawn_sync.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -185,6 +185,7 @@ class SyncProcessRunner {
185185
bool writable,
186186
uv_buf_t input_buffer);
187187
inline int AddStdioInheritFD(uint32_t child_fd, int inherit_fd);
188+
inline int AddStdioInheritStream(uint32_t child_fd, uv_stream_t* stream);
188189

189190
static bool IsSet(v8::Local<v8::Value> value);
190191
v8::Maybe<int> CopyJsString(v8::Local<v8::Value> js_value,
Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
'use strict';
2+
3+
const common = require('../common');
4+
const assert = require('assert');
5+
const { spawn } = require('child_process');
6+
7+
if (common.isWindows) {
8+
common.skip('Not applicable on Windows');
9+
}
10+
11+
const child = spawn(process.execPath, [
12+
'-e',
13+
'require("fs").closeSync(0); setTimeout(() => {}, 2000)',
14+
], { stdio: ['pipe', 'ignore', 'ignore'] });
15+
16+
const timeout = setTimeout(() => {
17+
assert.fail('stdin close event was not emitted');
18+
}, 1000);
19+
20+
child.stdin.on('close', common.mustCall(() => {
21+
clearTimeout(timeout);
22+
child.kill();
23+
}));
24+
25+
child.on('exit', common.mustCall(() => {
26+
clearTimeout(timeout);
27+
}));

0 commit comments

Comments
 (0)