mirror of
https://github.com/ghostty-org/ghostty.git
synced 2025-07-20 02:36:22 +03:00
@ -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
12
flake.lock
generated
@ -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": {
|
||||
|
@ -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="
|
||||
|
@ -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,
|
||||
};
|
||||
|
@ -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);
|
||||
};
|
||||
}
|
||||
|
||||
|
@ -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
|
||||
|
@ -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();
|
||||
|
@ -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| .{
|
||||
|
@ -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";
|
||||
}
|
||||
|
||||
|
@ -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];
|
||||
|
@ -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;
|
||||
|
@ -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 };
|
||||
|
19
src/pty.zig
19
src/pty.zig
@ -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
|
||||
}
|
||||
|
@ -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 |_| {}
|
||||
}
|
||||
|
@ -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;
|
||||
};
|
||||
|
Reference in New Issue
Block a user