aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorGravatar Jarred Sumner <709451+Jarred-Sumner@users.noreply.github.com> 2022-10-10 22:16:19 -0700
committerGravatar Jarred Sumner <709451+Jarred-Sumner@users.noreply.github.com> 2022-10-10 22:16:19 -0700
commitd07e4f8bd178b4e7450a6990c51ca3bfa0201127 (patch)
tree945e7216d7ac970214efb876378078c1147ebcb9
parente4bf189e9dc1589eff9e72333ef41ab181d86da3 (diff)
downloadbun-d07e4f8bd178b4e7450a6990c51ca3bfa0201127.tar.gz
bun-d07e4f8bd178b4e7450a6990c51ca3bfa0201127.tar.zst
bun-d07e4f8bd178b4e7450a6990c51ca3bfa0201127.zip
Automatically close stdout/stderr on subprocess exit if possible
Diffstat (limited to '')
-rw-r--r--src/bun.js/api/bun/subprocess.zig4
-rw-r--r--src/bun.js/webcore/streams.zig22
2 files changed, 21 insertions, 5 deletions
diff --git a/src/bun.js/api/bun/subprocess.zig b/src/bun.js/api/bun/subprocess.zig
index 9fac2ee37..f30995532 100644
--- a/src/bun.js/api/bun/subprocess.zig
+++ b/src/bun.js/api/bun/subprocess.zig
@@ -85,14 +85,14 @@ pub const Subprocess = struct {
buffer: BufferedOutput,
pub fn finish(this: *@This()) void {
- if (this.* == .stream) {
+ if (this.* == .stream and this.stream.ptr == .File) {
this.stream.ptr.File.finish();
}
}
pub fn done(this: *@This()) void {
if (this.* == .stream) {
- this.stream.ptr.File.finish();
+ if (this.stream.ptr == .File) this.stream.ptr.File.finish();
this.stream.done();
return;
}
diff --git a/src/bun.js/webcore/streams.zig b/src/bun.js/webcore/streams.zig
index 1484a94b1..79a0339aa 100644
--- a/src/bun.js/webcore/streams.zig
+++ b/src/bun.js/webcore/streams.zig
@@ -3058,6 +3058,14 @@ pub const FileBlobLoader = struct {
poll_ref: JSC.PollRef = .{},
has_adjusted_pipe_size_on_linux: bool = false,
finished: bool = false,
+
+ /// When we have some way of knowing that EOF truly is the write end of the
+ /// pipe being closed
+ /// Set this to true so we automatically mark it as done
+ /// This is used in Bun.spawn() to automatically close stdout and stderr
+ /// when the process exits
+ close_on_eof: bool = false,
+
signal: JSC.WebCore.Signal = .{},
pub usingnamespace NewReadyWatcher(@This(), .read, ready);
@@ -3085,6 +3093,7 @@ pub const FileBlobLoader = struct {
pub fn finish(this: *FileBlobLoader) void {
if (this.finished) return;
this.finished = true;
+ this.close_on_eof = true;
// we are done
// resolve any promises with done
@@ -3430,7 +3439,7 @@ pub const FileBlobLoader = struct {
// - empty file
// - stream closed for some reason
// - FIFO returned EOF
- if ((result == 0 and (remaining == 0 or std.os.S.ISFIFO(this.mode)))) {
+ if ((result == 0 and (remaining == 0 or this.close_on_eof))) {
this.finalize();
return .{ .done = {} };
}
@@ -3573,14 +3582,21 @@ pub const FileBlobLoader = struct {
if (result == 0 and free_buffer_on_error) {
bun.default_allocator.free(buf_to_use);
buf_to_use = read_buf;
-
- return this.handleReadChunk(result, view, true, buf_to_use);
} else if (free_buffer_on_error) {
this.view.clear();
this.buf = &.{};
return this.handleReadChunk(result, view, true, buf_to_use);
}
+ if (result == 0 and !this.finished and !this.close_on_eof and std.os.S.ISFIFO(this.mode)) {
+ this.view.set(this.globalThis(), view);
+ this.buf = read_buf;
+ this.watch(this.fd);
+ return .{
+ .pending = &this.pending,
+ };
+ }
+
return this.handleReadChunk(result, view, false, buf_to_use);
},
}