aboutsummaryrefslogtreecommitdiff
path: root/src/bun.js/node/syscall.zig
diff options
context:
space:
mode:
Diffstat (limited to 'src/bun.js/node/syscall.zig')
-rw-r--r--src/bun.js/node/syscall.zig65
1 files changed, 65 insertions, 0 deletions
diff --git a/src/bun.js/node/syscall.zig b/src/bun.js/node/syscall.zig
index 7ad927c3a..14cee4e36 100644
--- a/src/bun.js/node/syscall.zig
+++ b/src/bun.js/node/syscall.zig
@@ -203,6 +203,7 @@ pub fn open(file_path: [:0]const u8, flags: JSC.Node.Mode, perm: JSC.Node.Mode)
// The zig standard library marks BADF as unreachable
// That error is not unreachable for us
pub fn close(fd: std.os.fd_t) ?Syscall.Error {
+ log("close({d})", .{fd});
if (comptime Environment.isMac) {
// This avoids the EINTR problem.
return switch (system.getErrno(system.@"close$NOCANCEL"(fd))) {
@@ -682,3 +683,67 @@ pub const Error = struct {
return this.toSystemError().toErrorInstance(ptr);
}
};
+
+pub fn setPipeCapacityOnLinux(fd: JSC.Node.FileDescriptor, capacity: usize) Maybe(usize) {
+ if (comptime !Environment.isLinux) @compileError("Linux-only");
+ std.debug.assert(capacity > 0);
+
+ // In Linux versions before 2.6.11, the capacity of a
+ // pipe was the same as the system page size (e.g., 4096
+ // bytes on i386). Since Linux 2.6.11, the pipe
+ // capacity is 16 pages (i.e., 65,536 bytes in a system
+ // with a page size of 4096 bytes). Since Linux 2.6.35,
+ // the default pipe capacity is 16 pages, but the
+ // capacity can be queried and set using the
+ // fcntl(2) F_GETPIPE_SZ and F_SETPIPE_SZ operations.
+ // See fcntl(2) for more information.
+ //:# define F_SETPIPE_SZ 1031 /* Set pipe page size array.
+ const F_SETPIPE_SZ = 1031;
+ const F_GETPIPE_SZ = 1032;
+
+ // We don't use glibc here
+ // It didn't work. Always returned 0.
+ const pipe_len = std.os.linux.fcntl(fd, F_GETPIPE_SZ, 0);
+ if (Maybe(usize).errno(pipe_len)) |err| return err;
+ if (pipe_len == 0) return Maybe(usize){ .result = 0 };
+ if (pipe_len >= capacity) return Maybe(usize){ .result = pipe_len };
+
+ const new_pipe_len = std.os.linux.fcntl(fd, F_SETPIPE_SZ, capacity);
+ if (Maybe(usize).errno(new_pipe_len)) |err| return err;
+ return Maybe(usize){ .result = new_pipe_len };
+}
+
+pub fn getMaxPipeSizeOnLinux() usize {
+ return @intCast(
+ usize,
+ bun.once(struct {
+ fn once() c_int {
+ const strings = bun.strings;
+ const default_out_size = 512 * 1024;
+ const pipe_max_size_fd = switch (JSC.Node.Syscall.open("/proc/sys/fs/pipe-max-size", std.os.O.RDONLY, 0)) {
+ .result => |fd2| fd2,
+ .err => |err| {
+ log("Failed to open /proc/sys/fs/pipe-max-size: {d}\n", .{err.errno});
+ return default_out_size;
+ },
+ };
+ defer _ = JSC.Node.Syscall.close(pipe_max_size_fd);
+ var max_pipe_size_buf: [128]u8 = undefined;
+ const max_pipe_size = switch (JSC.Node.Syscall.read(pipe_max_size_fd, max_pipe_size_buf[0..])) {
+ .result => |bytes_read| std.fmt.parseInt(i64, strings.trim(max_pipe_size_buf[0..bytes_read], "\n"), 10) catch |err| {
+ log("Failed to parse /proc/sys/fs/pipe-max-size: {any}\n", .{@errorName(err)});
+ return default_out_size;
+ },
+ .err => |err| {
+ log("Failed to read /proc/sys/fs/pipe-max-size: {d}\n", .{err.errno});
+ return default_out_size;
+ },
+ };
+
+ // we set the absolute max to 8 MB because honestly that's a huge pipe
+ // my current linux machine only goes up to 1 MB, so that's very unlikely to be hit
+ return @minimum(@truncate(c_int, max_pipe_size -| 32), 1024 * 1024 * 8);
+ }
+ }.once, c_int),
+ );
+}