diff --git a/src/fd.zig b/src/fd.zig index 78f9079bf9..c013a2beb8 100644 --- a/src/fd.zig +++ b/src/fd.zig @@ -198,18 +198,18 @@ pub const FDImpl = packed struct { }; } - /// This function will prevent stdout and stderr from being closed. + /// This function will prevent stdin, stdout, and stderr from being closed. pub fn close(this: FDImpl) ?bun.sys.Error { if (environment.os != .windows or this.kind == .uv) { // This branch executes always on linux (uv() is no-op), // or on Windows when given a UV file descriptor. const fd = this.uv(); - if (fd == 1 or fd == 2) { + if (fd == 0 or fd == 1 or fd == 2) { log("close({}) SKIPPED", .{fd}); return null; } } - return this.closeAllowingStdoutAndStderr(); + return this.closeAllowingStdinStdoutAndStderr(); } /// Assumes given a valid file descriptor @@ -227,7 +227,7 @@ pub const FDImpl = packed struct { }; } - pub fn closeAllowingStdoutAndStderr(this: FDImpl) ?bun.sys.Error { + pub fn closeAllowingStdinStdoutAndStderr(this: FDImpl) ?bun.sys.Error { if (allow_assert) { bun.assert(this.value.as_system != invalid_value); // probably a UAF } diff --git a/src/sys.zig b/src/sys.zig index b3e31f0ba2..cfae2331fc 100644 --- a/src/sys.zig +++ b/src/sys.zig @@ -1835,11 +1835,11 @@ pub fn close2(fd: bun.FileDescriptor) ?Syscall.Error { return null; } - return closeAllowingStdoutAndStderr(fd); + return closeAllowingStdinStdoutAndStderr(fd); } -pub fn closeAllowingStdoutAndStderr(fd: bun.FileDescriptor) ?Syscall.Error { - return bun.FDImpl.decode(fd).closeAllowingStdoutAndStderr(); +pub fn closeAllowingStdinStdoutAndStderr(fd: bun.FileDescriptor) ?Syscall.Error { + return bun.FDImpl.decode(fd).closeAllowingStdinStdoutAndStderr(); } pub const max_count = switch (builtin.os.tag) { diff --git a/test/js/node/test/parallel/test-stdin-from-file.js b/test/js/node/test/parallel/test-stdin-from-file.js new file mode 100644 index 0000000000..c8301ff459 --- /dev/null +++ b/test/js/node/test/parallel/test-stdin-from-file.js @@ -0,0 +1,23 @@ +'use strict'; +const common = require('../common'); +const fixtures = require('../common/fixtures'); +const tmpdir = require('../common/tmpdir'); +const assert = require('assert'); +const childProcess = require('child_process'); +const fs = require('fs'); + +const stdoutScript = fixtures.path('echo-close-check.js'); +const tmpFile = tmpdir.resolve('stdin.txt'); +const string = fixtures.utf8TestText; + +tmpdir.refresh(); + +fs.writeFileSync(tmpFile, string); + +childProcess.exec(...common.escapePOSIXShell`"${process.argv0}" "${stdoutScript}" < "${tmpFile}"`, common.mustCall(function(err, stdout, stderr) { + fs.unlinkSync(tmpFile); + + assert.ifError(err); + assert.strictEqual(stdout, `hello world\r\n${string}`); + assert.strictEqual(stderr, ''); +}));