aboutsummaryrefslogtreecommitdiff
path: root/vendor/libghostty-vt/src/lib/compat/fd.zig
diff options
context:
space:
mode:
authorCan Celik <ogulcancelik@gmail.com>2026-09-10 21:51:57 +0300
committerGitHub <noreply@github.com>2026-09-10 21:51:57 +0300
commit425c86179791cd32e2d4ce0ae7f269940b4b0663 (patch)
treee52c4383a6d69216cbe2a32638bf90841d7e2189 /vendor/libghostty-vt/src/lib/compat/fd.zig
parent90e947a6e26e02f10ec7f1694c4eb5b78a86406b (diff)
chore: upgrade libghostty and preserve terminal behavior (#3906)
Diffstat (limited to 'vendor/libghostty-vt/src/lib/compat/fd.zig')
-rw-r--r--vendor/libghostty-vt/src/lib/compat/fd.zig83
1 files changed, 83 insertions, 0 deletions
diff --git a/vendor/libghostty-vt/src/lib/compat/fd.zig b/vendor/libghostty-vt/src/lib/compat/fd.zig
new file mode 100644
index 00000000..3bef7414
--- /dev/null
+++ b/vendor/libghostty-vt/src/lib/compat/fd.zig
@@ -0,0 +1,83 @@
+//! Code taken from 0.15.2 and `std.fs.file`. See README.md for license and
+//! details.
+const std = @import("std");
+
+pub const PipeError = error{
+ SystemFdQuotaExceeded,
+ ProcessFdQuotaExceeded,
+} || std.posix.UnexpectedError;
+
+pub fn close(fd: std.posix.fd_t) void {
+ switch (std.posix.errno(std.posix.system.close(fd))) {
+ .BADF => unreachable, // Always a race condition
+ else => {}, // Includes EINTR, see std.posix source in 0.15.2
+ }
+}
+
+pub fn pipe() PipeError![2]std.posix.fd_t {
+ var fds: [2]std.posix.fd_t = undefined;
+ switch (std.posix.errno(std.posix.system.pipe(&fds))) {
+ .SUCCESS => return fds,
+ .INVAL => unreachable, // Invalid parameters to pipe()
+ .FAULT => unreachable, // Invalid fds pointer
+ .NFILE => return error.SystemFdQuotaExceeded,
+ .MFILE => return error.ProcessFdQuotaExceeded,
+ else => |err| return std.posix.unexpectedErrno(err),
+ }
+}
+
+pub fn pipe2(flags: std.posix.O) PipeError![2]std.posix.fd_t {
+ if (@TypeOf(std.posix.system.pipe2) != void) {
+ var fds: [2]std.posix.fd_t = undefined;
+ switch (std.posix.errno(std.posix.system.pipe2(&fds, flags))) {
+ .SUCCESS => return fds,
+ .INVAL => unreachable, // Invalid flags
+ .FAULT => unreachable, // Invalid fds pointer
+ .NFILE => return error.SystemFdQuotaExceeded,
+ .MFILE => return error.ProcessFdQuotaExceeded,
+ else => |err| return std.posix.unexpectedErrno(err),
+ }
+ }
+
+ const fds: [2]std.posix.fd_t = try pipe();
+ errdefer {
+ close(fds[0]);
+ close(fds[1]);
+ }
+
+ // https://github.com/ziglang/zig/issues/18882
+ if (@as(u32, @bitCast(flags)) == 0)
+ return fds;
+
+ // CLOEXEC is special, it's a file descriptor flag and must be set using
+ // F.SETFD.
+ if (flags.CLOEXEC) {
+ for (fds) |fd| {
+ switch (std.posix.errno(std.posix.system.fcntl(fd, std.posix.F.SETFD, @as(u32, std.posix.FD_CLOEXEC)))) {
+ .SUCCESS => {},
+ .INVAL => unreachable, // Invalid flags
+ .BADF => unreachable, // Always a race condition
+ else => |err| return std.posix.unexpectedErrno(err),
+ }
+ }
+ }
+
+ const new_flags: u32 = f: {
+ var new_flags = flags;
+ new_flags.CLOEXEC = false;
+ break :f @bitCast(new_flags);
+ };
+ // Set every other flag affecting the file status using F.SETFL.
+ if (new_flags != 0) {
+ for (fds) |fd| {
+ switch (std.posix.errno(std.posix.system.fcntl(fd, std.posix.F.SETFL, new_flags))) {
+ .SUCCESS => {},
+ .INVAL => unreachable, // Invalid flags
+ .BADF => unreachable, // Always a race condition
+ else => |err| return std.posix.unexpectedErrno(err),
+ }
+ }
+ }
+
+ return fds;
+}