mirror of
https://github.com/oven-sh/bun
synced 2026-02-16 13:51:47 +00:00
Refactor shell script parsing and cancellation handling
Co-authored-by: zack <zack@theradisic.com>
This commit is contained in:
@@ -69,24 +69,25 @@ pub fn setEnv(this: *ParsedShellScript, globalThis: *JSC.JSGlobalObject, callfra
|
||||
return globalThis.throw("$`...`.env(): expected an object argument", .{});
|
||||
};
|
||||
|
||||
var iter = try JSC.JSObject.DictionaryIterator.init(globalThis, jsenv.asObjectRef() orelse {
|
||||
const obj_ref = jsenv.asObjectRef() orelse {
|
||||
return globalThis.throw("$`...`.env(): expected an object argument", .{});
|
||||
});
|
||||
};
|
||||
const obj: *JSC.JSObject = @ptrCast(obj_ref);
|
||||
var iter = try JSC.JSPropertyIterator(.{ .skip_empty_name = false, .include_value = true }).init(globalThis, obj);
|
||||
defer iter.deinit();
|
||||
|
||||
if (this.export_env == null) {
|
||||
this.export_env = EnvMap.init(bun.default_allocator);
|
||||
}
|
||||
|
||||
while (iter.next()) |entry| {
|
||||
var key = try entry.key.toOwnedSlice(globalThis);
|
||||
const len = @as(u32, @truncate(entry.key.getLength(globalThis)));
|
||||
while (try iter.next()) |key| {
|
||||
var value = iter.value;
|
||||
if (value.isUndefined()) continue;
|
||||
|
||||
var val = entry.value;
|
||||
var val_slice = try val.toOwnedSlice(globalThis);
|
||||
if (entry.key_allocated) key = try EnvStr.EnvKey.toOwnedSlice(key);
|
||||
try this.export_env.?.put(key, val_slice);
|
||||
_ = len; // autofix
|
||||
const key_str = try key.toOwnedSlice(bun.default_allocator);
|
||||
const val_slice = try (try value.getZigString(globalThis)).toOwnedSlice(bun.default_allocator);
|
||||
|
||||
this.export_env.?.insert(EnvStr.initRefCounted(key_str), EnvStr.initRefCounted(val_slice));
|
||||
}
|
||||
|
||||
return .js_undefined;
|
||||
|
||||
@@ -129,7 +129,7 @@ pub const Yield = union(enum) {
|
||||
}
|
||||
}
|
||||
|
||||
state: switch (current_yield) {
|
||||
switch (current_yield) {
|
||||
.pipeline => |x| {
|
||||
pipeline_stack.append(x) catch bun.outOfMemory();
|
||||
current_yield = x.next();
|
||||
|
||||
@@ -178,6 +178,11 @@ pub fn next(this: *Cp) Yield {
|
||||
return this.bltn().done(0);
|
||||
}
|
||||
|
||||
pub fn cancel(cp: *Cp) void {
|
||||
// TODO: Add atomic cancellation flag for threaded execution
|
||||
_ = cp;
|
||||
}
|
||||
|
||||
pub fn deinit(cp: *Cp) void {
|
||||
assert(cp.state == .done or cp.state == .waiting_write_err);
|
||||
}
|
||||
|
||||
@@ -711,7 +711,7 @@ pub fn cancel(this: *Cmd) Yield {
|
||||
.none => {},
|
||||
.subproc => |*subproc| {
|
||||
// Try to kill the subprocess with SIGTERM
|
||||
_ = subproc.child.tryKill(std.posix.SIGTERM);
|
||||
_ = subproc.child.tryKill(@intFromEnum(bun.SignalCode.SIGTERM));
|
||||
},
|
||||
.bltn => |*builtin| {
|
||||
// Call cancel on the builtin
|
||||
@@ -721,14 +721,10 @@ pub fn cancel(this: *Cmd) Yield {
|
||||
|
||||
// Cancel any pending IO chunks
|
||||
if (this.io.stdout == .fd) {
|
||||
if (this.io.stdout.fd.writer) |writer| {
|
||||
writer.cancelChunks(this);
|
||||
}
|
||||
this.io.stdout.fd.writer.cancelChunks(this);
|
||||
}
|
||||
if (this.io.stderr == .fd) {
|
||||
if (this.io.stderr.fd.writer) |writer| {
|
||||
writer.cancelChunks(this);
|
||||
}
|
||||
this.io.stderr.fd.writer.cancelChunks(this);
|
||||
}
|
||||
|
||||
return .suspended;
|
||||
|
||||
@@ -215,14 +215,10 @@ pub fn cancel(this: *CondExpr) Yield {
|
||||
|
||||
// Cancel any IO chunks
|
||||
if (this.io.stdout == .fd) {
|
||||
if (this.io.stdout.fd.writer) |writer| {
|
||||
writer.cancelChunks(this);
|
||||
}
|
||||
this.io.stdout.fd.writer.cancelChunks(this);
|
||||
}
|
||||
if (this.io.stderr == .fd) {
|
||||
if (this.io.stderr.fd.writer) |writer| {
|
||||
writer.cancelChunks(this);
|
||||
}
|
||||
this.io.stderr.fd.writer.cancelChunks(this);
|
||||
}
|
||||
|
||||
// Report cancellation to parent
|
||||
|
||||
@@ -151,15 +151,13 @@ pub fn cancel(this: *Expansion) Yield {
|
||||
|
||||
// If a command substitution is running, cancel the child Script
|
||||
if (this.child_state == .cmd_subst) {
|
||||
if (this.child_state.cmd_subst.cmd) |child| {
|
||||
_ = child.cancel();
|
||||
}
|
||||
_ = this.child_state.cmd_subst.cmd.cancel();
|
||||
}
|
||||
|
||||
// Clean up state
|
||||
if (this.current_out.items.len > 0) {
|
||||
switch (this.out) {
|
||||
.array_of_ptr => |buf| {
|
||||
.array_of_ptr => {
|
||||
for (this.current_out.items) |item| {
|
||||
_ = item; // Unused, we're cancelling
|
||||
}
|
||||
|
||||
@@ -175,14 +175,10 @@ pub fn cancel(this: *Subshell) Yield {
|
||||
|
||||
// Cancel any IO chunks
|
||||
if (this.io.stdout == .fd) {
|
||||
if (this.io.stdout.fd.writer) |writer| {
|
||||
writer.cancelChunks(this);
|
||||
}
|
||||
this.io.stdout.fd.writer.cancelChunks(this);
|
||||
}
|
||||
if (this.io.stderr == .fd) {
|
||||
if (this.io.stderr.fd.writer) |writer| {
|
||||
writer.cancelChunks(this);
|
||||
}
|
||||
this.io.stderr.fd.writer.cancelChunks(this);
|
||||
}
|
||||
|
||||
// Report cancellation to parent
|
||||
|
||||
Reference in New Issue
Block a user