aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorGravatar Jarred Sumner <jarred@jarredsumner.com> 2023-09-12 06:34:20 -0700
committerGravatar GitHub <noreply@github.com> 2023-09-12 06:34:20 -0700
commitb432006e439fcde9f8748fd369ad0e33a22bf347 (patch)
treed28ab2c083ece076c3bccd0ff4b44501a411957d
parent015f0a6e9aebe04dcc54dce4d000c0ecec5547b3 (diff)
downloadbun-b432006e439fcde9f8748fd369ad0e33a22bf347.tar.gz
bun-b432006e439fcde9f8748fd369ad0e33a22bf347.tar.zst
bun-b432006e439fcde9f8748fd369ad0e33a22bf347.zip
Clean up some edgecases with posix_spawn usage (#5079)
* Check that the pid matches * Fixup EINTR check * Remove extra slashes * fixup * fixup * != 0 --------- Co-authored-by: Jarred Sumner <709451+Jarred-Sumner@users.noreply.github.com>
-rw-r--r--src/bun.js/api/bun/subprocess.zig76
-rw-r--r--src/install/install.zig10
2 files changed, 66 insertions, 20 deletions
diff --git a/src/bun.js/api/bun/subprocess.zig b/src/bun.js/api/bun/subprocess.zig
index 50bd846ac..5695c15ad 100644
--- a/src/bun.js/api/bun/subprocess.zig
+++ b/src/bun.js/api/bun/subprocess.zig
@@ -1462,25 +1462,61 @@ pub const Subprocess = struct {
const kernel = @import("../../../analytics.zig").GenerateHeader.GeneratePlatform.kernelVersion();
// pidfd_nonblock only supported in 5.10+
- const pidfd_flags: u32 = if (!is_sync and kernel.orderWithoutTag(.{ .major = 5, .minor = 10, .patch = 0 }).compare(.gte))
+ var pidfd_flags: u32 = if (!is_sync and kernel.orderWithoutTag(.{ .major = 5, .minor = 10, .patch = 0 }).compare(.gte))
std.os.O.NONBLOCK
else
0;
- const fd = std.os.linux.pidfd_open(
- pid,
+ var rc = std.os.linux.pidfd_open(
+ @intCast(pid),
pidfd_flags,
);
- switch (std.os.linux.getErrno(fd)) {
- .SUCCESS => break :brk @as(std.os.fd_t, @intCast(fd)),
- else => |err| {
- globalThis.throwValue(bun.sys.Error.fromCode(err, .open).toJSC(globalThis));
- var status: u32 = 0;
- // ensure we don't leak the child process on error
- _ = std.os.linux.waitpid(pid, &status, 0);
- return .zero;
- },
+ while (true) {
+ switch (std.os.linux.getErrno(rc)) {
+ .SUCCESS => break :brk @as(std.os.fd_t, @intCast(rc)),
+ .INTR => {
+ rc = std.os.linux.pidfd_open(
+ @intCast(pid),
+ pidfd_flags,
+ );
+ continue;
+ },
+ else => |err| {
+ if (err == .INVAL) {
+ if (pidfd_flags != 0) {
+ rc = std.os.linux.pidfd_open(
+ @intCast(pid),
+ 0,
+ );
+ pidfd_flags = 0;
+ continue;
+ }
+ }
+
+ const error_instance = brk2: {
+ if (err == .NOSYS) {
+ break :brk2 globalThis.createErrorInstance(
+ \\"pidfd_open(2)" system call is not supported by your Linux kernel
+ \\To fix this error, either:
+ \\- Upgrade your Linux kernel to a newer version (current: {})
+ \\- Ensure the seccomp filter allows "pidfd_open"
+ ,
+ .{
+ kernel.fmt(""),
+ },
+ );
+ }
+
+ break :brk2 bun.sys.Error.fromCode(err, .open).toJSC(globalThis);
+ };
+ globalThis.throwValue(error_instance);
+ var status: u32 = 0;
+ // ensure we don't leak the child process on error
+ _ = std.os.linux.waitpid(pid, &status, 0);
+ return .zero;
+ },
+ }
}
};
@@ -1682,14 +1718,16 @@ pub const Subprocess = struct {
this.waitpid_err = err;
},
.result => |result| {
- if (std.os.W.IFEXITED(result.status)) {
- this.exit_code = @as(u8, @truncate(std.os.W.EXITSTATUS(result.status)));
- }
+ if (result.pid != 0) {
+ if (std.os.W.IFEXITED(result.status)) {
+ this.exit_code = @as(u8, @truncate(std.os.W.EXITSTATUS(result.status)));
+ }
- if (std.os.W.IFSIGNALED(result.status)) {
- this.signal_code = @as(SignalCode, @enumFromInt(@as(u8, @truncate(std.os.W.TERMSIG(result.status)))));
- } else if (std.os.W.IFSTOPPED(result.status)) {
- this.signal_code = @as(SignalCode, @enumFromInt(@as(u8, @truncate(std.os.W.STOPSIG(result.status)))));
+ if (std.os.W.IFSIGNALED(result.status)) {
+ this.signal_code = @as(SignalCode, @enumFromInt(@as(u8, @truncate(std.os.W.TERMSIG(result.status)))));
+ } else if (std.os.W.IFSTOPPED(result.status)) {
+ this.signal_code = @as(SignalCode, @enumFromInt(@as(u8, @truncate(std.os.W.STOPSIG(result.status)))));
+ }
}
if (!this.hasExited()) {
diff --git a/src/install/install.zig b/src/install/install.zig
index d7113cfe9..bcf33cb53 100644
--- a/src/install/install.zig
+++ b/src/install/install.zig
@@ -1250,7 +1250,15 @@ const PackageInstall = struct {
std.os.mkdirat(destination_dir_.dir.fd, entry.path, 0o755) catch {};
},
.file => {
- try std.os.linkat(entry.dir.dir.fd, entry.basename, destination_dir_.dir.fd, entry.path, 0);
+ std.os.linkat(entry.dir.dir.fd, entry.basename, destination_dir_.dir.fd, entry.path, 0) catch |err| {
+ if (err != error.PathAlreadyExists) {
+ return err;
+ }
+
+ std.os.unlinkat(destination_dir_.dir.fd, entry.path, 0) catch {};
+ try std.os.linkat(entry.dir.dir.fd, entry.basename, destination_dir_.dir.fd, entry.path, 0);
+ };
+
real_file_count += 1;
},
else => {},