Merge pull request #1603 from mitchellh/update-zig

Update Zig
This commit is contained in:
Mitchell Hashimoto
2024-03-22 20:25:29 -07:00
committed by GitHub
15 changed files with 103 additions and 92 deletions

View File

@ -5,8 +5,8 @@
.dependencies = .{
// Zig libs
.libxev = .{
.url = "https://github.com/mitchellh/libxev/archive/418cac65473668b02cc5a85194042bdaf04acd00.tar.gz",
.hash = "12203116ff408eb48f81c947dfeb06f7feebf6a9efa962a560ac69463098b2c04a96",
.url = "https://github.com/mitchellh/libxev/archive/0f73adfda1cff9c740160717b5431ebada6b8755.tar.gz",
.hash = "12203dcbe098ee49ea242432cd198b1ca557626988f056bea86630dcfe8660244407",
},
.mach_glfw = .{
.url = "https://github.com/der-teufel-programming/mach-glfw/archive/250affff8c52d1eaa0fab2ef1118f691bf1225ec.tar.gz",
@ -14,8 +14,8 @@
.lazy = true,
},
.zig_objc = .{
.url = "https://github.com/mitchellh/zig-objc/archive/83a52ce8e3452b299cb8f2ab91bfb34cf042c664.tar.gz",
.hash = "1220d55dc3e61375ac93cb2449ea7b33e6bea4e53e72d18b0e6bc0ec6d38c05faaed",
.url = "https://github.com/mitchellh/zig-objc/archive/0a89cc09da6804ae448241a673ce85a282216074.tar.gz",
.hash = "1220acfc53954f699415c6942422571670544a5236866fa7b6e069e2b1b2ba86ae9c",
},
.zig_js = .{
.url = "https://github.com/mitchellh/zig-js/archive/d4edb682733aef8dc3933683272bdf7c8b9fe658.tar.gz",

12
flake.lock generated
View File

@ -147,11 +147,11 @@
},
"nixpkgs-zig-0-12": {
"locked": {
"lastModified": 1710350178,
"narHash": "sha256-vZERN9g+/dfZvSRL9gNBYGVDv/8v7pmXr6LhWYxBgcU=",
"lastModified": 1711143939,
"narHash": "sha256-oT6a81U4NHjJH1hjaMVXKsdTZJwl2dT+MhMESKoevvA=",
"owner": "vancluever",
"repo": "nixpkgs",
"rev": "25322cf4d6b4ffb6f318ab45eab985d1b40e6056",
"rev": "c4749393c06e52da4adf42877fdf9bac7141f0de",
"type": "github"
},
"original": {
@ -194,11 +194,11 @@
]
},
"locked": {
"lastModified": 1710331756,
"narHash": "sha256-ZYFHWEHupxj/e9jOcjUOJLVTuvMR4fYMV53F0zu8Rfs=",
"lastModified": 1711109355,
"narHash": "sha256-VZPO5mq2di5yjHkkY9ZGEIZaX7EtdusSkxICBAtHAec=",
"owner": "mitchellh",
"repo": "zig-overlay",
"rev": "510a1f01f1ddc06df0f2b888f12ad1aa9a65cc31",
"rev": "5fe52bdf2c213e47712d93c9ce12dfed4c4cef86",
"type": "github"
},
"original": {

View File

@ -1,3 +1,3 @@
# This file is auto-generated! check build-support/check-zig-cache-hash.sh for
# more details.
"sha256-Rf0xVSlgIciiZP/ZeAkdHnEAQTWApewNFSY8xSDAMIk="
"sha256-nr8utAh2oMwnN6nyWzJo8VubFO5cCrHK+QNYuT2WBi0="

View File

@ -22,7 +22,8 @@ const internal_os = @import("os/main.zig");
const windows = internal_os.windows;
const TempDir = internal_os.TempDir;
const mem = std.mem;
const os = std.os;
const linux = std.os.linux;
const posix = std.posix;
const debug = std.debug;
const testing = std.testing;
const Allocator = std.mem.Allocator;
@ -70,7 +71,7 @@ pseudo_console: if (builtin.os.tag == .windows) ?windows.exp.HPCON else void =
data: ?*anyopaque = null,
/// Process ID is set after start is called.
pid: ?os.pid_t = null,
pid: ?posix.pid_t = null,
/// The various methods a process may exit.
pub const Exit = if (builtin.os.tag == .windows) union(enum) {
@ -89,12 +90,12 @@ pub const Exit = if (builtin.os.tag == .windows) union(enum) {
Unknown: u32,
pub fn init(status: u32) Exit {
return if (os.W.IFEXITED(status))
Exit{ .Exited = os.W.EXITSTATUS(status) }
else if (os.W.IFSIGNALED(status))
Exit{ .Signal = os.W.TERMSIG(status) }
else if (os.W.IFSTOPPED(status))
Exit{ .Stopped = os.W.STOPSIG(status) }
return if (posix.W.IFEXITED(status))
Exit{ .Exited = posix.W.EXITSTATUS(status) }
else if (posix.W.IFSIGNALED(status))
Exit{ .Signal = posix.W.TERMSIG(status) }
else if (posix.W.IFSTOPPED(status))
Exit{ .Stopped = posix.W.STOPSIG(status) }
else
Exit{ .Unknown = status };
}
@ -133,7 +134,7 @@ fn startPosix(self: *Command, arena: Allocator) !void {
@compileError("missing env vars");
// Fork
const pid = try std.os.fork();
const pid = try posix.fork();
if (pid != 0) {
// Parent, return immediately.
self.pid = @intCast(pid);
@ -143,18 +144,18 @@ fn startPosix(self: *Command, arena: Allocator) !void {
// We are the child.
// Setup our file descriptors for std streams.
if (self.stdin) |f| try setupFd(f.handle, os.STDIN_FILENO);
if (self.stdout) |f| try setupFd(f.handle, os.STDOUT_FILENO);
if (self.stderr) |f| try setupFd(f.handle, os.STDERR_FILENO);
if (self.stdin) |f| try setupFd(f.handle, posix.STDIN_FILENO);
if (self.stdout) |f| try setupFd(f.handle, posix.STDOUT_FILENO);
if (self.stderr) |f| try setupFd(f.handle, posix.STDERR_FILENO);
// Setup our working directory
if (self.cwd) |cwd| try os.chdir(cwd);
if (self.cwd) |cwd| try posix.chdir(cwd);
// If the user requested a pre exec callback, call it now.
if (self.pre_exec) |f| f(self);
// Finally, replace our process.
_ = std.os.execveZ(pathZ, argsZ, envp) catch null;
_ = posix.execveZ(pathZ, argsZ, envp) catch null;
// If we are executing this code, the exec failed. In that scenario,
// we return a very specific error that can be detected to determine
@ -180,7 +181,7 @@ fn startWindows(self: *Command, arena: Allocator) !void {
.creation = windows.OPEN_EXISTING,
},
) else null;
defer if (null_fd) |fd| std.os.close(fd);
defer if (null_fd) |fd| posix.close(fd);
// TODO: In the case of having FDs instead of pty, need to set up
// attributes such that the child process only inherits these handles,
@ -272,8 +273,8 @@ fn setupFd(src: File.Handle, target: i32) !void {
// file descriptor to be closed on exec since we're exactly exec-ing after
// this.
while (true) {
const rc = os.linux.dup3(src, target, 0);
switch (os.errno(rc)) {
const rc = linux.dup3(src, target, 0);
switch (posix.errno(rc)) {
.SUCCESS => break,
.INTR => continue,
.AGAIN, .ACCES => return error.Locked,
@ -285,19 +286,19 @@ fn setupFd(src: File.Handle, target: i32) !void {
.NOTDIR => unreachable, // invalid parameter
.DEADLK => return error.DeadLock,
.NOLCK => return error.LockedRegionLimitExceeded,
else => |err| return os.unexpectedErrno(err),
else => |err| return posix.unexpectedErrno(err),
}
}
},
.ios, .macos => {
// Mac doesn't support dup3 so we use dup2. We purposely clear
// CLO_ON_EXEC for this fd.
const flags = try os.fcntl(src, os.F.GETFD, 0);
if (flags & os.FD_CLOEXEC != 0) {
_ = try os.fcntl(src, os.F.SETFD, flags & ~@as(u32, os.FD_CLOEXEC));
const flags = try posix.fcntl(src, posix.F.GETFD, 0);
if (flags & posix.FD_CLOEXEC != 0) {
_ = try posix.fcntl(src, posix.F.SETFD, flags & ~@as(u32, posix.FD_CLOEXEC));
}
try os.dup2(src, target);
try posix.dup2(src, target);
},
else => @compileError("unsupported platform"),
}
@ -322,7 +323,7 @@ pub fn wait(self: Command, block: bool) !Exit {
return .{ .Exited = exit_code };
}
const res = if (block) std.os.waitpid(self.pid.?, 0) else res: {
const res = if (block) posix.waitpid(self.pid.?, 0) else res: {
// We specify NOHANG because its not our fault if the process we launch
// for the tty doesn't properly waitpid its children. We don't want
// to hang the terminal over it.
@ -331,7 +332,7 @@ pub fn wait(self: Command, block: bool) !Exit {
// wait call has not been performed, so we need to keep trying until we get
// a non-zero pid back, otherwise we end up with zombie processes.
while (true) {
const res = std.os.waitpid(self.pid.?, std.c.W.NOHANG);
const res = posix.waitpid(self.pid.?, std.c.W.NOHANG);
if (res.pid != 0) break :res res;
}
};
@ -361,11 +362,11 @@ pub fn expandPath(alloc: Allocator, cmd: []const u8) !?[]u8 {
const PATH = switch (builtin.os.tag) {
.windows => blk: {
const win_path = os.getenvW(std.unicode.utf8ToUtf16LeStringLiteral("PATH")) orelse return null;
const win_path = std.process.getenvW(std.unicode.utf8ToUtf16LeStringLiteral("PATH")) orelse return null;
const path = try std.unicode.utf16leToUtf8Alloc(alloc, win_path);
break :blk path;
},
else => os.getenvZ("PATH") orelse return null,
else => std.posix.getenvZ("PATH") orelse return null,
};
defer if (builtin.os.tag == .windows) alloc.free(PATH);
@ -568,7 +569,7 @@ test "Command: pre exec" {
fn do(_: *Command) void {
// This runs in the child, so we can exit and it won't
// kill the test runner.
os.exit(42);
posix.exit(42);
}
}).do,
};

View File

@ -9,6 +9,7 @@
const std = @import("std");
const assert = std.debug.assert;
const posix = std.posix;
const builtin = @import("builtin");
const build_config = @import("build_config.zig");
const main = @import("main.zig");
@ -65,7 +66,7 @@ export fn ghostty_cli_main(argc: usize, argv: [*][*:0]u8) noreturn {
std.os.argv = argv[0..argc];
main.main() catch |err| {
std.log.err("failed to run ghostty error={}", .{err});
std.os.exit(1);
posix.exit(1);
};
}

View File

@ -4,6 +4,7 @@
const std = @import("std");
const builtin = @import("builtin");
const Allocator = std.mem.Allocator;
const posix = std.posix;
const build_config = @import("build_config.zig");
const options = @import("build_options");
const glfw = @import("glfw");
@ -42,7 +43,7 @@ pub fn main() !MainReturn {
// no other Zig code should EVER access the global state.
state.init() catch |err| {
const stderr = std.io.getStdErr().writer();
defer std.os.exit(1);
defer posix.exit(1);
const ErrSet = @TypeOf(err) || error{Unknown};
switch (@as(ErrSet, @errorCast(err))) {
error.MultipleActions => try stderr.print(
@ -72,7 +73,7 @@ pub fn main() !MainReturn {
// Execute our action if we have one
if (state.action) |action| {
std.log.info("executing CLI action={}", .{action});
std.os.exit(action.run(alloc) catch |err| err: {
posix.exit(action.run(alloc) catch |err| err: {
std.log.err("CLI action failed error={}", .{err});
break :err 1;
});
@ -94,7 +95,7 @@ pub fn main() !MainReturn {
.{},
);
std.os.exit(0);
posix.exit(0);
}
// Create our app state

View File

@ -1,6 +1,7 @@
const std = @import("std");
const builtin = @import("builtin");
const build_config = @import("../build_config.zig");
const posix = std.posix;
const c = @cImport({
@cInclude("unistd.h");
@ -24,7 +25,7 @@ pub fn launchedFromDesktop() bool {
// app bundle (i.e. via open) then we still treat it as if it
// was launched from the desktop.
if (build_config.artifact == .lib and
std.os.getenv("GHOSTTY_MAC_APP") != null) break :macos true;
posix.getenv("GHOSTTY_MAC_APP") != null) break :macos true;
break :macos c.getppid() == 1;
},
@ -36,7 +37,7 @@ pub fn launchedFromDesktop() bool {
// another terminal was launched from a desktop file and then launches
// Ghostty and Ghostty inherits the env.
.linux => linux: {
const gio_pid_str = std.os.getenv("GIO_LAUNCHED_DESKTOP_FILE_PID") orelse
const gio_pid_str = posix.getenv("GIO_LAUNCHED_DESKTOP_FILE_PID") orelse
break :linux false;
const pid = c.getpid();

View File

@ -1,6 +1,7 @@
const std = @import("std");
const builtin = @import("builtin");
const Allocator = std.mem.Allocator;
const posix = std.posix;
/// The separator used in environment variables such as PATH.
pub const PATH_SEP = switch (builtin.os.tag) {
@ -46,7 +47,7 @@ pub const GetEnvResult = struct {
pub fn getenv(alloc: Allocator, key: []const u8) !?GetEnvResult {
return switch (builtin.os.tag) {
// Non-Windows doesn't need to allocate
else => if (std.os.getenv(key)) |v| .{ .value = v } else null,
else => if (posix.getenv(key)) |v| .{ .value = v } else null,
// Windows needs to allocate
.windows => if (std.process.getEnvVarOwned(alloc, key)) |v| .{

View File

@ -1,5 +1,6 @@
const std = @import("std");
const builtin = @import("builtin");
const posix = std.posix;
const log = std.log.scoped(.os);
@ -7,8 +8,7 @@ const log = std.log.scoped(.os);
/// need to do this because each window consumes at least a handful of fds.
/// This is extracted from the Zig compiler source code.
pub fn fixMaxFiles() void {
if (!@hasDecl(std.os.system, "rlimit")) return;
const posix = std.os;
if (!@hasDecl(posix.system, "rlimit")) return;
var lim = posix.getrlimit(.NOFILE) catch {
log.warn("failed to query file handle limit, may limit max windows", .{});
@ -49,14 +49,14 @@ pub fn fixMaxFiles() void {
pub fn allocTmpDir(allocator: std.mem.Allocator) ?[]const u8 {
if (builtin.os.tag == .windows) {
// TODO: what is a good fallback path on windows?
const v = std.os.getenvW(std.unicode.utf8ToUtf16LeStringLiteral("TMP")) orelse return null;
const v = std.process.getenvW(std.unicode.utf8ToUtf16LeStringLiteral("TMP")) orelse return null;
return std.unicode.utf16leToUtf8Alloc(allocator, v) catch |e| {
log.warn("failed to convert temp dir path from windows string: {}", .{e});
return null;
};
}
if (std.os.getenv("TMPDIR")) |v| return v;
if (std.os.getenv("TMP")) |v| return v;
if (posix.getenv("TMPDIR")) |v| return v;
if (posix.getenv("TMP")) |v| return v;
return "/tmp";
}

View File

@ -2,6 +2,7 @@ const std = @import("std");
const builtin = @import("builtin");
const assert = std.debug.assert;
const passwd = @import("passwd.zig");
const posix = std.posix;
const Error = error{
/// The buffer used for output is not large enough to store the value.
@ -24,7 +25,7 @@ pub inline fn home(buf: []u8) !?[]u8 {
fn homeUnix(buf: []u8) !?[]u8 {
// First: if we have a HOME env var, then we use that.
if (std.os.getenv("HOME")) |result| {
if (posix.getenv("HOME")) |result| {
if (buf.len < result.len) return Error.BufferTooSmall;
@memcpy(buf[0..result.len], result);
return buf[0..result.len];

View File

@ -1,11 +1,12 @@
const std = @import("std");
const builtin = @import("builtin");
const windows = @import("windows.zig");
const posix = std.posix;
/// pipe() that works on Windows and POSIX.
pub fn pipe() ![2]std.os.fd_t {
pub fn pipe() ![2]posix.fd_t {
switch (builtin.os.tag) {
else => return try std.os.pipe(),
else => return try posix.pipe(),
.windows => {
var read: windows.HANDLE = undefined;
var write: windows.HANDLE = undefined;

View File

@ -5,6 +5,7 @@ const std = @import("std");
const builtin = @import("builtin");
const assert = std.debug.assert;
const Allocator = std.mem.Allocator;
const posix = std.posix;
const homedir = @import("homedir.zig");
pub const Options = struct {
@ -24,7 +25,7 @@ pub fn config(alloc: Allocator, opts: Options) ![]u8 {
// both whether we have the env var and whether we own it.
// on Windows we treat `LOCALAPPDATA` as a fallback for `XDG_CONFIG_HOME`
const env_, const owned = switch (builtin.os.tag) {
else => .{ std.os.getenv("XDG_CONFIG_HOME"), false },
else => .{ posix.getenv("XDG_CONFIG_HOME"), false },
.windows => windows: {
if (std.process.getEnvVarOwned(alloc, "XDG_CONFIG_HOME")) |env| {
break :windows .{ env, true };

View File

@ -1,6 +1,7 @@
const std = @import("std");
const builtin = @import("builtin");
const windows = @import("os/main.zig").windows;
const posix = std.posix;
const log = std.log.scoped(.pty);
@ -26,7 +27,7 @@ pub const Pty = switch (builtin.os.tag) {
// a termio that doesn't use a pty. This isn't used in any user-facing
// artifacts, this is just a stopgap to get compilation to work on iOS.
const NullPty = struct {
pub const Fd = std.os.fd_t;
pub const Fd = posix.fd_t;
master: Fd,
slave: Fd,
@ -54,7 +55,7 @@ const NullPty = struct {
/// of Linux syscalls. The caller is responsible for detail-oriented handling
/// of the returned file handles.
const PosixPty = struct {
pub const Fd = std.os.fd_t;
pub const Fd = posix.fd_t;
// https://github.com/ziglang/zig/issues/13277
// Once above is fixed, use `c.TIOCSCTTY`
@ -95,8 +96,8 @@ const PosixPty = struct {
) < 0)
return error.OpenptyFailed;
errdefer {
_ = std.os.system.close(master_fd);
_ = std.os.system.close(slave_fd);
_ = posix.system.close(master_fd);
_ = posix.system.close(slave_fd);
}
// Enable UTF-8 mode. I think this is on by default on Linux but it
@ -115,8 +116,8 @@ const PosixPty = struct {
}
pub fn deinit(self: *Pty) void {
_ = std.os.system.close(self.master);
_ = std.os.system.close(self.slave);
_ = posix.system.close(self.master);
_ = posix.system.close(self.slave);
self.* = undefined;
}
@ -142,7 +143,7 @@ const PosixPty = struct {
if (setsid() < 0) return error.ProcessGroupFailed;
// Set controlling terminal
switch (std.os.system.getErrno(c.ioctl(self.slave, TIOCSCTTY, @as(c_ulong, 0)))) {
switch (posix.errno(c.ioctl(self.slave, TIOCSCTTY, @as(c_ulong, 0)))) {
.SUCCESS => {},
else => |err| {
log.err("error setting controlling terminal errno={}", .{err});
@ -151,8 +152,8 @@ const PosixPty = struct {
}
// Can close master/slave pair now
std.os.close(self.slave);
std.os.close(self.master);
posix.close(self.slave);
posix.close(self.master);
// TODO: reset signals
}

View File

@ -3,6 +3,7 @@ const builtin = @import("builtin");
const assert = std.debug.assert;
const Allocator = std.mem.Allocator;
const ArenaAllocator = std.heap.ArenaAllocator;
const posix = std.posix;
const command = @import("graphics_command.zig");
const point = @import("../point.zig");
@ -78,7 +79,7 @@ pub const LoadingImage = struct {
if (comptime builtin.os.tag != .windows) {
if (std.mem.indexOfScalar(u8, buf[0..size], 0) != null) {
// std.os.realpath *asserts* that the path does not have
// posix.realpath *asserts* that the path does not have
// internal nulls instead of erroring.
log.warn("failed to get absolute path: BadPathName", .{});
return error.InvalidData;
@ -86,7 +87,7 @@ pub const LoadingImage = struct {
}
var abs_buf: [std.fs.MAX_PATH_BYTES]u8 = undefined;
const path = std.os.realpath(buf[0..size], &abs_buf) catch |err| {
const path = posix.realpath(buf[0..size], &abs_buf) catch |err| {
log.warn("failed to get absolute path: {}", .{err});
return error.InvalidData;
};
@ -151,7 +152,7 @@ pub const LoadingImage = struct {
if (!isPathInTempDir(path)) return error.TemporaryFileNotInTempDir;
}
defer if (medium == .temporary_file) {
std.os.unlink(path) catch |err| {
posix.unlink(path) catch |err| {
log.warn("failed to delete temporary file: {}", .{err});
};
};
@ -209,7 +210,7 @@ pub const LoadingImage = struct {
// The temporary dir is sometimes a symlink. On macOS for
// example /tmp is /private/var/...
var buf: [std.fs.MAX_PATH_BYTES]u8 = undefined;
if (std.os.realpath(dir, &buf)) |real_dir| {
if (posix.realpath(dir, &buf)) |real_dir| {
if (std.mem.startsWith(u8, path, real_dir)) return true;
} else |_| {}
}

View File

@ -8,6 +8,7 @@ const assert = std.debug.assert;
const Allocator = std.mem.Allocator;
const ArenaAllocator = std.heap.ArenaAllocator;
const EnvMap = std.process.EnvMap;
const posix = std.posix;
const termio = @import("../termio.zig");
const Command = @import("../Command.zig");
const Pty = @import("../pty.zig").Pty;
@ -206,7 +207,7 @@ pub fn threadEnter(self: *Exec, thread: *termio.Thread) !ThreadData {
// (Linux) which are usually guaranteed to exist. Still, we
// want to handle this scenario.
self.execFailedInChild() catch {};
std.os.exit(1);
posix.exit(1);
};
errdefer self.subprocess.stop();
const pid = pid: {
@ -221,8 +222,8 @@ pub fn threadEnter(self: *Exec, thread: *termio.Thread) !ThreadData {
// Create our pipe that we'll use to kill our read thread.
// pipe[0] is the read end, pipe[1] is the write end.
const pipe = try internal_os.pipe();
errdefer std.os.close(pipe[0]);
errdefer std.os.close(pipe[1]);
errdefer posix.close(pipe[0]);
errdefer posix.close(pipe[1]);
// Setup our data that is used for callbacks
var ev_data_ptr = try alloc.create(EventData);
@ -335,7 +336,7 @@ pub fn threadExit(self: *Exec, data: ThreadData) void {
// Quit our read thread after exiting the subprocess so that
// we don't get stuck waiting for data to stop flowing if it is
// a particularly noisy process.
_ = std.os.write(data.read_thread_pipe, "x") catch |err|
_ = posix.write(data.read_thread_pipe, "x") catch |err|
log.warn("error writing to read thread quit pipe err={}", .{err});
if (comptime builtin.os.tag == .windows) {
@ -658,11 +659,11 @@ const ThreadData = struct {
/// Our read thread
read_thread: std.Thread,
read_thread_pipe: std.os.fd_t,
read_thread_fd: if (builtin.os.tag == .windows) std.os.fd_t else void,
read_thread_pipe: posix.fd_t,
read_thread_fd: if (builtin.os.tag == .windows) posix.fd_t else void,
pub fn deinit(self: *ThreadData) void {
std.os.close(self.read_thread_pipe);
posix.close(self.read_thread_pipe);
self.ev.deinit(self.alloc);
self.alloc.destroy(self.ev);
self.* = undefined;
@ -1251,7 +1252,7 @@ const Subprocess = struct {
// Once started, we can close the pty child side. We do this after
// wait right now but that is fine too. This lets us read the
// parent and detect EOF.
_ = std.os.close(pty.slave);
_ = posix.close(pty.slave);
return .{
.read = pty.master,
@ -1393,7 +1394,7 @@ const Subprocess = struct {
// The gist is that it lets us detect when children
// are still alive without blocking so that we can
// kill them again.
const res = std.os.waitpid(pid, std.c.W.NOHANG);
const res = posix.waitpid(pid, std.c.W.NOHANG);
if (res.pid != 0) break;
std.time.sleep(10 * std.time.ns_per_ms);
}
@ -1462,18 +1463,18 @@ const Subprocess = struct {
/// fds and this is still much faster and lower overhead than any async
/// mechanism.
const ReadThread = struct {
fn threadMainPosix(fd: std.os.fd_t, ev: *EventData, quit: std.os.fd_t) void {
fn threadMainPosix(fd: posix.fd_t, ev: *EventData, quit: posix.fd_t) void {
// Always close our end of the pipe when we exit.
defer std.os.close(quit);
defer posix.close(quit);
// First thing, we want to set the fd to non-blocking. We do this
// so that we can try to read from the fd in a tight loop and only
// check the quit fd occasionally.
if (std.os.fcntl(fd, std.os.F.GETFL, 0)) |flags| {
_ = std.os.fcntl(
if (posix.fcntl(fd, posix.F.GETFL, 0)) |flags| {
_ = posix.fcntl(
fd,
std.os.F.SETFL,
flags | @as(u32, @bitCast(std.os.O{ .NONBLOCK = true })),
posix.F.SETFL,
flags | @as(u32, @bitCast(posix.O{ .NONBLOCK = true })),
) catch |err| {
log.warn("read thread failed to set flags err={}", .{err});
log.warn("this isn't a fatal error, but may cause performance issues", .{});
@ -1485,9 +1486,9 @@ const ReadThread = struct {
// Build up the list of fds we're going to poll. We are looking
// for data on the pty and our quit notification.
var pollfds: [2]std.os.pollfd = .{
.{ .fd = fd, .events = std.os.POLL.IN, .revents = undefined },
.{ .fd = quit, .events = std.os.POLL.IN, .revents = undefined },
var pollfds: [2]posix.pollfd = .{
.{ .fd = fd, .events = posix.POLL.IN, .revents = undefined },
.{ .fd = quit, .events = posix.POLL.IN, .revents = undefined },
};
var buf: [1024]u8 = undefined;
@ -1498,7 +1499,7 @@ const ReadThread = struct {
// the data will eventually stop while we're trying to quit. This
// is always true because we kill the process.
while (true) {
const n = std.os.read(fd, &buf) catch |err| {
const n = posix.read(fd, &buf) catch |err| {
switch (err) {
// This means our pty is closed. We're probably
// gracefully shutting down.
@ -1530,22 +1531,22 @@ const ReadThread = struct {
}
// Wait for data.
_ = std.os.poll(&pollfds, -1) catch |err| {
_ = posix.poll(&pollfds, -1) catch |err| {
log.warn("poll failed on read thread, exiting early err={}", .{err});
return;
};
// If our quit fd is set, we're done.
if (pollfds[1].revents & std.os.POLL.IN != 0) {
if (pollfds[1].revents & posix.POLL.IN != 0) {
log.info("read thread got quit signal", .{});
return;
}
}
}
fn threadMainWindows(fd: std.os.fd_t, ev: *EventData, quit: std.os.fd_t) void {
fn threadMainWindows(fd: posix.fd_t, ev: *EventData, quit: posix.fd_t) void {
// Always close our end of the pipe when we exit.
defer std.os.close(quit);
defer posix.close(quit);
var buf: [1024]u8 = undefined;
while (true) {
@ -2641,8 +2642,8 @@ const StreamHandler = struct {
}
// Otherwise, it must match our hostname.
var buf: [std.os.HOST_NAME_MAX]u8 = undefined;
const hostname = std.os.gethostname(&buf) catch |err| {
var buf: [posix.HOST_NAME_MAX]u8 = undefined;
const hostname = posix.gethostname(&buf) catch |err| {
log.warn("failed to get hostname for OSC 7 validation: {}", .{err});
break :host_valid false;
};