Skip to content

Commit d6da170

Browse files
bzozMylesBorins
authored andcommitted
src: ensure that fd 0-2 are valid on windows
Check that stdin, stdout and stderr are valid file descriptors on Windows. If not, reopen them with 'nul' file. Refs: #875 Fixes: #11656 PR-URL: #11863 Reviewed-By: Ben Noordhuis <[email protected]> Reviewed-By: James M Snell <[email protected]> Reviewed-By: Jeremiah Senkpiel <[email protected]> Reviewed-By: Anna Henningsen <[email protected]>
1 parent 68b23be commit d6da170

File tree

3 files changed

+34
-1
lines changed

3 files changed

+34
-1
lines changed

src/node.cc

+13
Original file line numberDiff line numberDiff line change
@@ -4161,6 +4161,19 @@ inline void PlatformInit() {
41614161
} while (min + 1 < max);
41624162
}
41634163
#endif // __POSIX__
4164+
#ifdef _WIN32
4165+
for (int fd = 0; fd <= 2; ++fd) {
4166+
auto handle = reinterpret_cast<HANDLE>(_get_osfhandle(fd));
4167+
if (handle == INVALID_HANDLE_VALUE ||
4168+
GetFileType(handle) == FILE_TYPE_UNKNOWN) {
4169+
// Ignore _close result. If it fails or not depends on used Windows
4170+
// version. We will just check _open result.
4171+
_close(fd);
4172+
if (fd != _open("nul", _O_RDWR))
4173+
ABORT();
4174+
}
4175+
}
4176+
#endif // _WIN32
41644177
}
41654178

41664179

test/fixtures/spawn_closed_stdio.py

+8
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
import os
2+
import sys
3+
import subprocess
4+
os.close(0)
5+
os.close(1)
6+
os.close(2)
7+
exit_code = subprocess.call(sys.argv[1:], shell=False)
8+
sys.exit(exit_code)

test/parallel/test-stdio-closed.js

+13-1
Original file line numberDiff line numberDiff line change
@@ -3,9 +3,21 @@ const common = require('../common');
33
const assert = require('assert');
44
const spawn = require('child_process').spawn;
55
const fs = require('fs');
6+
const path = require('path');
67

78
if (common.isWindows) {
8-
common.skip('platform not supported.');
9+
if (process.argv[2] === 'child') {
10+
process.stdin;
11+
process.stdout;
12+
process.stderr;
13+
return;
14+
}
15+
const python = process.env.PYTHON || 'python';
16+
const script = path.join(common.fixturesDir, 'spawn_closed_stdio.py');
17+
const proc = spawn(python, [script, process.execPath, __filename, 'child']);
18+
proc.on('exit', common.mustCall(function(exitCode) {
19+
assert.strictEqual(exitCode, 0);
20+
}));
921
return;
1022
}
1123

0 commit comments

Comments
 (0)