Commit 07c89c0
Eric Bower
·
2026-10-23 21:04:42 -0400 EDT
parent 770eb5f
chore: update to zig 0.17
16 files changed,
+153,
-112
+1,
-1
jump to top
+1,
-1
jump to top
| ... | ... | @@ -2,7 +2,7 @@ FROM debian:12 | |
| 2 | 2 | ||
| 3 | 3 | RUN apt-get update && apt-get install -y curl git bats coreutils python3 && rm -rf /var/lib/apt/lists/* | |
| 4 | 4 | ||
| 5 | - | ARG ZIG_VERSION=0.16.0 | |
| 5 | + | ARG ZIG_VERSION=0.17.0 | |
| 6 | 6 | # `uname -m` already reports the names zig uses in its tarballs (x86_64, | |
| 7 | 7 | # aarch64), so it needs no mapping. | |
| 8 | 8 | RUN ARCH="$(uname -m)" && \ |
+39,
-1
jump to top
+39,
-1
jump to top
| ... | ... | @@ -1,4 +1,5 @@ | |
| 1 | 1 | const std = @import("std"); | |
| 2 | + | const Translator = @import("translate_c").Translator; | |
| 2 | 3 | const build_zig_zon = @import("build.zig.zon"); | |
| 3 | 4 | ||
| 4 | 5 | const linux_targets: []const std.Target.Query = &.{ |
| ... | ... | @@ -26,11 +27,24 @@ pub fn build(b: *std.Build) void { | |
| 26 | 27 | options.addOption([]const u8, "ghostty_version", ghostty_ver); | |
| 27 | 28 | options.addOption(bool, "has_daemon", enable_daemon); | |
| 28 | 29 | ||
| 30 | + | const translate_c = b.dependency("translate_c", .{}); | |
| 31 | + | const translator: Translator = .init(translate_c, .{ | |
| 32 | + | .c_source_file = b.path("src/c.h"), | |
| 33 | + | .target = target, | |
| 34 | + | .optimize = optimize, | |
| 35 | + | }); | |
| 36 | + | ||
| 29 | 37 | const exe_mod = b.createModule(.{ | |
| 30 | 38 | .root_source_file = b.path("src/main.zig"), | |
| 31 | 39 | .target = target, | |
| 32 | 40 | .optimize = optimize, | |
| 33 | 41 | .link_libc = true, | |
| 42 | + | .imports = &.{ | |
| 43 | + | .{ | |
| 44 | + | .name = "cross", | |
| 45 | + | .module = translator.mod, | |
| 46 | + | }, | |
| 47 | + | }, | |
| 34 | 48 | }); | |
| 35 | 49 | exe_mod.addOptions("build_options", options); | |
| 36 | 50 |
| ... | ... | @@ -56,6 +70,12 @@ pub fn build(b: *std.Build) void { | |
| 56 | 70 | .target = target, | |
| 57 | 71 | .optimize = optimize, | |
| 58 | 72 | .link_libc = true, | |
| 73 | + | .imports = &.{ | |
| 74 | + | .{ | |
| 75 | + | .name = "cross", | |
| 76 | + | .module = translator.mod, | |
| 77 | + | }, | |
| 78 | + | }, | |
| 59 | 79 | }); | |
| 60 | 80 | ||
| 61 | 81 | zmx_pkg_mod.addOptions("build_options", options); |
| ... | ... | @@ -79,6 +99,12 @@ pub fn build(b: *std.Build) void { | |
| 79 | 99 | .target = target, | |
| 80 | 100 | .optimize = optimize, | |
| 81 | 101 | .link_libc = true, | |
| 102 | + | .imports = &.{ | |
| 103 | + | .{ | |
| 104 | + | .name = "cross", | |
| 105 | + | .module = translator.mod, | |
| 106 | + | }, | |
| 107 | + | }, | |
| 82 | 108 | }); | |
| 83 | 109 | ex_mod.addImport("zmx", zmx_pkg_mod); | |
| 84 | 110 | const ex_exe = b.addExecutable(.{ .name = ex.name, .root_module = ex_mod }); |
| ... | ... | @@ -101,7 +127,7 @@ pub fn build(b: *std.Build) void { | |
| 101 | 127 | b.installArtifact(exe); | |
| 102 | 128 | const run_cmd = b.addRunArtifact(exe); | |
| 103 | 129 | run_cmd.step.dependOn(b.getInstallStep()); | |
| 104 | - | if (b.args) |args| run_cmd.addArgs(args); | |
| 130 | + | run_cmd.addPassthruArgs(); | |
| 105 | 131 | run_step.dependOn(&run_cmd.step); | |
| 106 | 132 | } | |
| 107 | 133 | } |
| ... | ... | @@ -114,6 +140,12 @@ pub fn build(b: *std.Build) void { | |
| 114 | 140 | .target = target, | |
| 115 | 141 | .optimize = optimize, | |
| 116 | 142 | .link_libc = true, | |
| 143 | + | .imports = &.{ | |
| 144 | + | .{ | |
| 145 | + | .name = "cross", | |
| 146 | + | .module = translator.mod, | |
| 147 | + | }, | |
| 148 | + | }, | |
| 117 | 149 | }); | |
| 118 | 150 | test_module.addOptions("build_options", options); | |
| 119 | 151 | const test_dep = b.dependency("ghostty", .{ |
| ... | ... | @@ -170,6 +202,12 @@ pub fn build(b: *std.Build) void { | |
| 170 | 202 | .target = resolved, | |
| 171 | 203 | .optimize = .ReleaseSafe, | |
| 172 | 204 | .link_libc = true, | |
| 205 | + | .imports = &.{ | |
| 206 | + | .{ | |
| 207 | + | .name = "cross", | |
| 208 | + | .module = translator.mod, | |
| 209 | + | }, | |
| 210 | + | }, | |
| 173 | 211 | }); | |
| 174 | 212 | release_mod.addOptions("build_options", options); | |
| 175 | 213 |
+7,
-3
jump to top
+7,
-3
jump to top
| ... | ... | @@ -2,11 +2,15 @@ | |
| 2 | 2 | .name = .zmx, | |
| 3 | 3 | .version = "0.8.1", | |
| 4 | 4 | .fingerprint = 0x28aad87005052b4e, // Changing this has security and trust implications. | |
| 5 | - | .minimum_zig_version = "0.16.0", | |
| 5 | + | .minimum_zig_version = "0.17.0", | |
| 6 | 6 | .dependencies = .{ | |
| 7 | 7 | .ghostty = .{ | |
| 8 | - | .url = "git+https://github.com/ghostty-org/ghostty#8af6897c0afc63037a8a3efee4162a380e3a4572", | |
| 9 | - | .hash = "ghostty-1.3.2-dev-5UdBC4FtYAV-PdFOt-gceWieTHLri0H4ztHtd6Tr4dGj", | |
| 8 | + | .url = "git+https://github.com/ghostty-org/ghostty#22f100c6367045bb5fc86172f837047dee2f7670", | |
| 9 | + | .hash = "ghostty-1.3.2-dev-5UdBC57IhQX5QCxEHr_MlUcomZtBUMVoo9BwUBIAtkln", | |
| 10 | + | }, | |
| 11 | + | .translate_c = .{ | |
| 12 | + | .url = "git+https://codeberg.org/ziglang/translate-c?ref=zig-0.17.x#cfac21f3199b2b02ce3fd7db652aa456421fe4ab", | |
| 13 | + | .hash = "translate_c-2.0.2-Q_BUWvBNBwDnyehSiuAJmdFcMYHYGA-Jc3KiYdrV2Dqx", | |
| 10 | 14 | }, | |
| 11 | 15 | }, | |
| 12 | 16 | .paths = .{ |
+30,
-0
jump to top
+30,
-0
jump to top
| ... | ... | @@ -0,0 +1,30 @@ | |
| 1 | + | #ifndef MY_C_H | |
| 2 | + | #define MY_C_H | |
| 3 | + | ||
| 4 | + | #include <stdlib.h> | |
| 5 | + | #include <unistd.h> | |
| 6 | + | #include <termios.h> | |
| 7 | + | ||
| 8 | + | #if defined(__APPLE__) | |
| 9 | + | #include <sys/ioctl.h> | |
| 10 | + | #include <sys/types.h> | |
| 11 | + | ||
| 12 | + | // Declare forkpty manually for macOS cross-compilation environments | |
| 13 | + | // where util.h might be missing from sysroot. | |
| 14 | + | pid_t forkpty(int *amaster, char *name, const struct termios *termp, const struct winsize *winp); | |
| 15 | + | ||
| 16 | + | #elif defined(__OpenBSD__) | |
| 17 | + | #include <sys/types.h> | |
| 18 | + | #include <sys/ioctl.h> | |
| 19 | + | #include <util.h> | |
| 20 | + | ||
| 21 | + | #elif defined(__FreeBSD__) | |
| 22 | + | #include <libutil.h> | |
| 23 | + | ||
| 24 | + | #else | |
| 25 | + | #include <sys/ioctl.h> | |
| 26 | + | #include <pty.h> | |
| 27 | + | ||
| 28 | + | #endif | |
| 29 | + | ||
| 30 | + | #endif // MY_C_H |
+7,
-7
jump to top
+7,
-7
jump to top
| ... | ... | @@ -5,7 +5,7 @@ pub const Cfg = @This(); | |
| 5 | 5 | ||
| 6 | 6 | const std = @import("std"); | |
| 7 | 7 | const lib_posix = @import("posix.zig"); | |
| 8 | - | const cross = @import("cross.zig"); | |
| 8 | + | const cross = @import("cross"); | |
| 9 | 9 | ||
| 10 | 10 | socket_dir: []const u8, | |
| 11 | 11 | log_dir: []const u8, |
| ... | ... | @@ -113,8 +113,8 @@ test "Cfg.init uses default modes when env vars are not set" { | |
| 113 | 113 | const alloc = std.testing.allocator; | |
| 114 | 114 | ||
| 115 | 115 | // Ensure they are not set | |
| 116 | - | _ = cross.c.unsetenv("ZMX_DIR_MODE"); | |
| 117 | - | _ = cross.c.unsetenv("ZMX_LOG_MODE"); | |
| 116 | + | _ = cross.unsetenv("ZMX_DIR_MODE"); | |
| 117 | + | _ = cross.unsetenv("ZMX_LOG_MODE"); | |
| 118 | 118 | ||
| 119 | 119 | var cfg = try Cfg.init(alloc, std.testing.io); | |
| 120 | 120 | defer cfg.deinit(alloc); |
| ... | ... | @@ -127,11 +127,11 @@ test "Cfg.init uses custom modes from env vars" { | |
| 127 | 127 | const alloc = std.testing.allocator; | |
| 128 | 128 | ||
| 129 | 129 | // Set custom octal values | |
| 130 | - | _ = cross.c.setenv("ZMX_DIR_MODE", "770", 1); | |
| 131 | - | _ = cross.c.setenv("ZMX_LOG_MODE", "660", 1); | |
| 130 | + | _ = cross.setenv("ZMX_DIR_MODE", "770", 1); | |
| 131 | + | _ = cross.setenv("ZMX_LOG_MODE", "660", 1); | |
| 132 | 132 | defer { | |
| 133 | - | _ = cross.c.unsetenv("ZMX_DIR_MODE"); | |
| 134 | - | _ = cross.c.unsetenv("ZMX_LOG_MODE"); | |
| 133 | + | _ = cross.unsetenv("ZMX_DIR_MODE"); | |
| 134 | + | _ = cross.unsetenv("ZMX_LOG_MODE"); | |
| 135 | 135 | } | |
| 136 | 136 | ||
| 137 | 137 | var cfg = try Cfg.init(alloc, std.testing.io); |
+12,
-12
jump to top
+12,
-12
jump to top
| ... | ... | @@ -12,7 +12,7 @@ const Cfg = @import("cfg.zig"); | |
| 12 | 12 | const util = @import("util.zig"); | |
| 13 | 13 | const label = @import("label.zig"); | |
| 14 | 14 | const lib_posix = @import("posix.zig"); | |
| 15 | - | const cross = @import("cross.zig"); | |
| 15 | + | const cross = @import("cross"); | |
| 16 | 16 | const signal = @import("signal.zig"); | |
| 17 | 17 | const loop = @import("loop.zig"); | |
| 18 | 18 | const Daemon = if (has_daemon) loop.Daemon else struct {}; |
| ... | ... | @@ -163,25 +163,25 @@ pub fn attach(alloc: Allocator, io: Io, name: []const u8, opts: AttachOptions) ! | |
| 163 | 163 | ||
| 164 | 164 | const client_sock = try socket.sessionConnect(socket_path); | |
| 165 | 165 | ||
| 166 | - | var orig_termios: cross.c.termios = undefined; | |
| 167 | - | const stdin_is_tty = cross.c.tcgetattr(lib_posix.STDIN_FILENO, &orig_termios) == 0; | |
| 166 | + | var orig_termios: cross.termios = undefined; | |
| 167 | + | const stdin_is_tty = cross.tcgetattr(lib_posix.STDIN_FILENO, &orig_termios) == 0; | |
| 168 | 168 | const restore_seq = "\x1bc\x1b]110\x1b\\\x1b]111\x1b\\\x1b]112\x1b\\"; | |
| 169 | 169 | ||
| 170 | 170 | defer { | |
| 171 | 171 | if (stdin_is_tty) { | |
| 172 | - | _ = cross.c.tcsetattr(lib_posix.STDIN_FILENO, cross.c.TCSAFLUSH, &orig_termios); | |
| 172 | + | _ = cross.tcsetattr(lib_posix.STDIN_FILENO, cross.TCSAFLUSH, &orig_termios); | |
| 173 | 173 | } | |
| 174 | 174 | _ = lib_posix.write(lib_posix.STDOUT_FILENO, restore_seq) catch {}; | |
| 175 | 175 | } | |
| 176 | 176 | ||
| 177 | 177 | if (stdin_is_tty) { | |
| 178 | 178 | var raw_termios = orig_termios; | |
| 179 | - | cross.c.cfmakeraw(&raw_termios); | |
| 180 | - | raw_termios.c_cc[cross.c.VLNEXT] = cross.c._POSIX_VDISABLE; | |
| 181 | - | raw_termios.c_cc[cross.c.VQUIT] = cross.c._POSIX_VDISABLE; | |
| 182 | - | raw_termios.c_cc[cross.c.VMIN] = 1; | |
| 183 | - | raw_termios.c_cc[cross.c.VTIME] = 0; | |
| 184 | - | _ = cross.c.tcsetattr(lib_posix.STDIN_FILENO, cross.c.TCSANOW, &raw_termios); | |
| 179 | + | cross.cfmakeraw(&raw_termios); | |
| 180 | + | raw_termios.c_cc[cross.VLNEXT] = cross._POSIX_VDISABLE; | |
| 181 | + | raw_termios.c_cc[cross.VQUIT] = cross._POSIX_VDISABLE; | |
| 182 | + | raw_termios.c_cc[cross.VMIN] = 1; | |
| 183 | + | raw_termios.c_cc[cross.VTIME] = 0; | |
| 184 | + | _ = cross.tcsetattr(lib_posix.STDIN_FILENO, cross.TCSANOW, &raw_termios); | |
| 185 | 185 | } | |
| 186 | 186 | ||
| 187 | 187 | const clear_seq = "\x1b[0m\x1b[2J\x1b[H"; |
| ... | ... | @@ -748,12 +748,12 @@ pub fn historyRange(alloc: Allocator, io: Io, name: []const u8, format: HistoryF | |
| 748 | 748 | const reply_tag: ipc.Tag = if (scrollback_rows != null) .Capture else .History; | |
| 749 | 749 | if (scrollback_rows) |rows| { | |
| 750 | 750 | var request = std.mem.zeroes(ipc.Capture); | |
| 751 | - | request.format = @intFromEnum(format); | |
| 751 | + | request.format = @backingInt(format); | |
| 752 | 752 | request.rows = rows; | |
| 753 | 753 | try ipc.send(fd, .Capture, std.mem.asBytes(&request)); | |
| 754 | 754 | try ipc.send(fd, .Info, ""); | |
| 755 | 755 | } else { | |
| 756 | - | const format_byte = [_]u8{@intFromEnum(format)}; | |
| 756 | + | const format_byte = [_]u8{@backingInt(format)}; | |
| 757 | 757 | try ipc.send(fd, .History, &format_byte); | |
| 758 | 758 | } | |
| 759 | 759 |
+0,
-39
jump to top
+0,
-39
jump to top
| ... | ... | @@ -1,39 +0,0 @@ | |
| 1 | - | const builtin = @import("builtin"); | |
| 2 | - | const std = @import("std"); | |
| 3 | - | ||
| 4 | - | pub const c = switch (builtin.os.tag) { | |
| 5 | - | .macos => @cImport({ | |
| 6 | - | @cInclude("sys/ioctl.h"); // ioctl and constants | |
| 7 | - | @cInclude("termios.h"); | |
| 8 | - | @cInclude("stdlib.h"); | |
| 9 | - | @cInclude("unistd.h"); | |
| 10 | - | }), | |
| 11 | - | .openbsd => @cImport({ | |
| 12 | - | @cInclude("sys/types.h"); | |
| 13 | - | @cInclude("sys/ioctl.h"); | |
| 14 | - | @cInclude("termios.h"); | |
| 15 | - | @cInclude("util.h"); // forkpty() | |
| 16 | - | @cInclude("stdlib.h"); | |
| 17 | - | @cInclude("unistd.h"); | |
| 18 | - | }), | |
| 19 | - | .freebsd => @cImport({ | |
| 20 | - | @cInclude("termios.h"); // ioctl and constants | |
| 21 | - | @cInclude("libutil.h"); // openpty() | |
| 22 | - | @cInclude("stdlib.h"); | |
| 23 | - | @cInclude("unistd.h"); | |
| 24 | - | }), | |
| 25 | - | else => @cImport({ | |
| 26 | - | @cInclude("sys/ioctl.h"); // ioctl and constants | |
| 27 | - | @cInclude("pty.h"); | |
| 28 | - | @cInclude("stdlib.h"); | |
| 29 | - | @cInclude("unistd.h"); | |
| 30 | - | }), | |
| 31 | - | }; | |
| 32 | - | ||
| 33 | - | // Manually declare forkpty for macOS since util.h is not available during cross-compilation | |
| 34 | - | pub const forkpty = if (builtin.os.tag == .macos) | |
| 35 | - | struct { | |
| 36 | - | extern "c" fn forkpty(master_fd: *c_int, name: ?[*:0]u8, termp: ?*const c.struct_termios, winp: ?*const c.struct_winsize) c_int; | |
| 37 | - | }.forkpty | |
| 38 | - | else | |
| 39 | - | c.forkpty; |
+19,
-11
jump to top
+19,
-11
jump to top
| ... | ... | @@ -5,7 +5,7 @@ const socket = @import("socket.zig"); | |
| 5 | 5 | const ipc = @import("ipc.zig"); | |
| 6 | 6 | const assert = std.debug.assert; | |
| 7 | 7 | const log = @import("log.zig"); | |
| 8 | - | const cross = @import("cross.zig"); | |
| 8 | + | const cross = @import("cross"); | |
| 9 | 9 | ||
| 10 | 10 | const Cmd = struct { | |
| 11 | 11 | file: [*:0]const u8, |
| ... | ... | @@ -19,7 +19,8 @@ pub fn createCmdZ(def_shell: []const u8, is_task_mode: bool, command: ?[]const [ | |
| 19 | 19 | if (cmd_args.len > 0) { | |
| 20 | 20 | const argv = try gpa.allocSentinel(?[*:0]const u8, cmd_args.len, null); | |
| 21 | 21 | for (cmd_args, 0..) |arg, i| { | |
| 22 | - | argv[i] = try gpa.dupeZ(u8, arg); | |
| 22 | + | const s = try gpa.dupeSentinel(u8, arg, 0); | |
| 23 | + | argv[i] = s.ptr; | |
| 23 | 24 | } | |
| 24 | 25 | return .{ | |
| 25 | 26 | .file = argv[0].?, |
| ... | ... | @@ -28,17 +29,24 @@ pub fn createCmdZ(def_shell: []const u8, is_task_mode: bool, command: ?[]const [ | |
| 28 | 29 | } | |
| 29 | 30 | } | |
| 30 | 31 | ||
| 31 | - | const z = try std.fmt.allocPrintSentinel(gpa, "{s}", .{def_shell}, 0); | |
| 32 | - | const shell: [:0]const u8 = if (is_task_mode) "bash" else z; | |
| 32 | + | const shell: [:0]const u8 = if (is_task_mode) | |
| 33 | + | "bash" | |
| 34 | + | else | |
| 35 | + | try gpa.dupeSentinel(u8, def_shell, 0); | |
| 33 | 36 | ||
| 34 | 37 | // Use "-shellname" as argv[0] to signal login shell (traditional method) | |
| 35 | - | const login_shell = try std.fmt.allocPrintSentinel(gpa, "-{s}", .{std.fs.path.basename(shell)}, 0); | |
| 38 | + | const login_shell = try std.fmt.allocPrintSentinel( | |
| 39 | + | gpa, | |
| 40 | + | "-{s}", | |
| 41 | + | .{std.fs.path.basename(shell)}, | |
| 42 | + | 0, | |
| 43 | + | ); | |
| 36 | 44 | const argv = try gpa.allocSentinel(?[*:0]const u8, 1, null); | |
| 37 | 45 | argv[0] = login_shell.ptr; | |
| 38 | 46 | ||
| 39 | 47 | return .{ | |
| 40 | 48 | .file = shell, | |
| 41 | - | .argv_ptr = argv, | |
| 49 | + | .argv_ptr = argv.ptr, | |
| 42 | 50 | }; | |
| 43 | 51 | } | |
| 44 | 52 |
| ... | ... | @@ -63,14 +71,14 @@ fn exec(sesh_name: []const u8, cmd: Cmd) !noreturn { | |
| 63 | 71 | .{sesh_name}, | |
| 64 | 72 | 0, | |
| 65 | 73 | ); | |
| 66 | - | _ = cross.c.putenv(session_env.ptr); | |
| 74 | + | _ = cross.putenv(session_env.ptr); | |
| 67 | 75 | ||
| 68 | - | if (cross.c.getenv("TERM")) |term_env| { | |
| 76 | + | if (cross.getenv("TERM")) |term_env| { | |
| 69 | 77 | if (std.mem.eql(u8, std.mem.span(term_env), "dumb")) { | |
| 70 | - | _ = cross.c.putenv(@constCast("TERM=xterm-256color")); | |
| 78 | + | _ = cross.putenv(@constCast("TERM=xterm-256color")); | |
| 71 | 79 | } | |
| 72 | 80 | } else { | |
| 73 | - | _ = cross.c.putenv(@constCast("TERM=xterm-256color")); | |
| 81 | + | _ = cross.putenv(@constCast("TERM=xterm-256color")); | |
| 74 | 82 | } | |
| 75 | 83 | ||
| 76 | 84 | const err = lib_posix.execvpeZ(cmd.file, cmd.argv_ptr, std.c.environ); |
| ... | ... | @@ -89,7 +97,7 @@ pub const PtyInfo = struct { | |
| 89 | 97 | /// This is the second fork in the double-fork technique explained in the | |
| 90 | 98 | /// daemonize() comment. | |
| 91 | 99 | pub fn spawnPty(sesh_name: []const u8, cmd: Cmd, size: ipc.Resize) !PtyInfo { | |
| 92 | - | var ws: cross.c.struct_winsize = .{ | |
| 100 | + | var ws: cross.struct_winsize = .{ | |
| 93 | 101 | .ws_row = size.rows, | |
| 94 | 102 | .ws_col = size.cols, | |
| 95 | 103 | .ws_xpixel = size.xpixel, |
+10,
-10
jump to top
+10,
-10
jump to top
| ... | ... | @@ -1,5 +1,5 @@ | |
| 1 | 1 | const std = @import("std"); | |
| 2 | - | const cross = @import("cross.zig"); | |
| 2 | + | const cross = @import("cross"); | |
| 3 | 3 | const socket = @import("socket.zig"); | |
| 4 | 4 | const lib_posix = @import("posix.zig"); | |
| 5 | 5 |
| ... | ... | @@ -39,7 +39,7 @@ pub const Tag = enum(u8) { | |
| 39 | 39 | }; | |
| 40 | 40 | ||
| 41 | 41 | comptime { | |
| 42 | - | if (@typeInfo(Tag).@"enum".is_exhaustive) @compileError( | |
| 42 | + | if (@typeInfo(Tag).@"enum".mode == .exhaustive) @compileError( | |
| 43 | 43 | "ipc.Tag must stay non-exhaustive -- old daemons rely on `_` to ignore unknown tags", | |
| 44 | 44 | ); | |
| 45 | 45 | } |
| ... | ... | @@ -57,7 +57,7 @@ pub const Resize = extern struct { | |
| 57 | 57 | xpixel: u16 = 0, | |
| 58 | 58 | ypixel: u16 = 0, | |
| 59 | 59 | ||
| 60 | - | pub fn winsize(self: Resize) cross.c.struct_winsize { | |
| 60 | + | pub fn winsize(self: Resize) cross.struct_winsize { | |
| 61 | 61 | return .{ | |
| 62 | 62 | .ws_row = self.rows, | |
| 63 | 63 | .ws_col = self.cols, |
| ... | ... | @@ -72,25 +72,25 @@ pub const Resize = extern struct { | |
| 72 | 72 | /// screen; zero returns only the screen. | |
| 73 | 73 | pub const Capture = extern struct { | |
| 74 | 74 | format: u8, | |
| 75 | - | _reserved: [3]u8 = .{0} ** 3, | |
| 75 | + | _reserved: [3]u8 = @splat(0), | |
| 76 | 76 | rows: u32, | |
| 77 | 77 | }; | |
| 78 | 78 | ||
| 79 | 79 | pub fn getTerminalSize(fd: i32) Resize { | |
| 80 | - | var ws: cross.c.struct_winsize = undefined; | |
| 81 | - | if (cross.c.ioctl(fd, cross.c.TIOCGWINSZ, &ws) == 0 and ws.ws_row > 0 and ws.ws_col > 0) { | |
| 80 | + | var ws: cross.struct_winsize = undefined; | |
| 81 | + | if (cross.ioctl(fd, cross.TIOCGWINSZ, &ws) == 0 and ws.ws_row > 0 and ws.ws_col > 0) { | |
| 82 | 82 | return .{ .rows = ws.ws_row, .cols = ws.ws_col, .xpixel = ws.ws_xpixel, .ypixel = ws.ws_ypixel }; | |
| 83 | 83 | } | |
| 84 | 84 | inline for (.{ lib_posix.STDOUT_FILENO, lib_posix.STDIN_FILENO, lib_posix.STDERR_FILENO }) |fallback_fd| { | |
| 85 | 85 | if (fallback_fd != fd) { | |
| 86 | - | if (cross.c.ioctl(fallback_fd, cross.c.TIOCGWINSZ, &ws) == 0 and ws.ws_row > 0 and ws.ws_col > 0) { | |
| 86 | + | if (cross.ioctl(fallback_fd, cross.TIOCGWINSZ, &ws) == 0 and ws.ws_row > 0 and ws.ws_col > 0) { | |
| 87 | 87 | return .{ .rows = ws.ws_row, .cols = ws.ws_col, .xpixel = ws.ws_xpixel, .ypixel = ws.ws_ypixel }; | |
| 88 | 88 | } | |
| 89 | 89 | } | |
| 90 | 90 | } | |
| 91 | 91 | if (lib_posix.open("/dev/tty", .{ .ACCMODE = .RDWR }, 0)) |tty_fd| { | |
| 92 | 92 | defer lib_posix.close(tty_fd); | |
| 93 | - | if (cross.c.ioctl(tty_fd, cross.c.TIOCGWINSZ, &ws) == 0 and ws.ws_row > 0 and ws.ws_col > 0) { | |
| 93 | + | if (cross.ioctl(tty_fd, cross.TIOCGWINSZ, &ws) == 0 and ws.ws_row > 0 and ws.ws_col > 0) { | |
| 94 | 94 | return .{ .rows = ws.ws_row, .cols = ws.ws_col, .xpixel = ws.ws_xpixel, .ypixel = ws.ws_ypixel }; | |
| 95 | 95 | } | |
| 96 | 96 | } else |_| {} |
| ... | ... | @@ -115,7 +115,7 @@ pub const Info = extern struct { | |
| 115 | 115 | task_ended_at: u64, | |
| 116 | 116 | task_exit_code: u8, | |
| 117 | 117 | protocol_version: u8 = PROTOCOL_VERSION, | |
| 118 | - | _reserved: [6]u8 = .{0} ** 6, | |
| 118 | + | _reserved: [6]u8 = @splat(0), | |
| 119 | 119 | }; | |
| 120 | 120 | ||
| 121 | 121 | pub fn send(fd: i32, tag: Tag, data: []const u8) !void { |
| ... | ... | @@ -357,7 +357,7 @@ test "Tag wire values are frozen" { | |
| 357 | 357 | .{ Tag.LabelSet, 15 }, .{ Tag.LabelClear, 16 }, .{ Tag.LabelData, 17 }, | |
| 358 | 358 | .{ Tag.Send, 18 }, .{ Tag.EnvGet, 19 }, .{ Tag.EnvSet, 20 }, | |
| 359 | 359 | .{ Tag.EnvData, 21 }, .{ Tag.Capture, 22 }, .{ Tag.Unsupported, 255 }, | |
| 360 | - | }) |p| try std.testing.expectEqual(@as(u8, p[1]), @intFromEnum(p[0])); | |
| 360 | + | }) |p| try std.testing.expectEqual(@as(u8, p[1]), @backingInt(p[0])); | |
| 361 | 361 | } | |
| 362 | 362 | ||
| 363 | 363 | pub fn roundTripForTag( |
+2,
-2
jump to top
+2,
-2
jump to top
| ... | ... | @@ -1,5 +1,5 @@ | |
| 1 | 1 | const std = @import("std"); | |
| 2 | - | const cross = @import("cross.zig"); | |
| 2 | + | const cross = @import("cross"); | |
| 3 | 3 | ||
| 4 | 4 | pub var log_system = LogSystem{}; | |
| 5 | 5 |
| ... | ... | @@ -40,7 +40,7 @@ pub const LogSystem = struct { | |
| 40 | 40 | // between our length() check and seekTo(), causing us to overwrite | |
| 41 | 41 | // recent parent entries. lseek(fd, 0, SEEK_END) is atomic — it | |
| 42 | 42 | // always positions at the true end of file at seek time. | |
| 43 | - | const new_pos = cross.c.lseek(file.handle, 0, cross.c.SEEK_END); | |
| 43 | + | const new_pos = cross.lseek(file.handle, 0, cross.SEEK_END); | |
| 44 | 44 | if (new_pos == -1) { | |
| 45 | 45 | std.Io.File.close(file, self.io); | |
| 46 | 46 | return error.SeekFailed; |
+10,
-10
jump to top
+10,
-10
jump to top
| ... | ... | @@ -2,7 +2,7 @@ const std = @import("std"); | |
| 2 | 2 | const ipc = @import("ipc.zig"); | |
| 3 | 3 | const log = @import("log.zig"); | |
| 4 | 4 | const util = @import("util.zig"); | |
| 5 | - | const cross = @import("cross.zig"); | |
| 5 | + | const cross = @import("cross"); | |
| 6 | 6 | const socket = @import("socket.zig"); | |
| 7 | 7 | const label = @import("label.zig"); | |
| 8 | 8 | const lib_posix = @import("posix.zig"); |
| ... | ... | @@ -19,7 +19,7 @@ const ghostty_vt = terminal.ghostty_vt; | |
| 19 | 19 | pub fn clientLoop(client_sock_fd: i32, env_str: []const u8) !ClientResult { | |
| 20 | 20 | std.log.info("client loop fd={d}", .{client_sock_fd}); | |
| 21 | 21 | const gpa: std.mem.Allocator = blk: { | |
| 22 | - | if (builtin.mode == .Debug) { | |
| 22 | + | if (builtin.mode == .debug) { | |
| 23 | 23 | const GPA = std.heap.DebugAllocator(.{}); | |
| 24 | 24 | const Static = struct { | |
| 25 | 25 | var gpa: GPA = .{}; |
| ... | ... | @@ -31,7 +31,7 @@ pub fn clientLoop(client_sock_fd: i32, env_str: []const u8) !ClientResult { | |
| 31 | 31 | defer lib_posix.close(client_sock_fd); | |
| 32 | 32 | ||
| 33 | 33 | try signal.openSignalPipe(); | |
| 34 | - | signal.installWakeHandler(@intFromEnum(lib_posix.SIG.WINCH)); | |
| 34 | + | signal.installWakeHandler(@backingInt(lib_posix.SIG.WINCH)); | |
| 35 | 35 | ||
| 36 | 36 | // Make socket non-blocking to avoid blocking on writes | |
| 37 | 37 | var sock_flags = try lib_posix.fcntl(client_sock_fd, lib_posix.F.GETFL, 0); |
| ... | ... | @@ -240,7 +240,7 @@ fn daemonLoop(daemon: *Daemon, gpa: std.mem.Allocator, io: std.Io, server_sock_f | |
| 240 | 240 | std.log.info("daemon started session={s} pty_fd={d}", .{ daemon.session_name, pty_fd }); | |
| 241 | 241 | ||
| 242 | 242 | try signal.openSignalPipe(); | |
| 243 | - | signal.installWakeHandler(@intFromEnum(lib_posix.SIG.TERM)); | |
| 243 | + | signal.installWakeHandler(@backingInt(lib_posix.SIG.TERM)); | |
| 244 | 244 | var poll_fds = try std.ArrayList(lib_posix.pollfd).initCapacity(gpa, 8); | |
| 245 | 245 | defer poll_fds.deinit(gpa); | |
| 246 | 246 |
| ... | ... | @@ -508,7 +508,7 @@ fn daemonLoop(daemon: *Daemon, gpa: std.mem.Allocator, io: std.Io, server_sock_f | |
| 508 | 508 | _ => { | |
| 509 | 509 | std.log.warn( | |
| 510 | 510 | "ignoring unknown IPC tag={d}", | |
| 511 | - | .{@intFromEnum(msg.header.tag)}, | |
| 511 | + | .{@backingInt(msg.header.tag)}, | |
| 512 | 512 | ); | |
| 513 | 513 | ipc.appendMessage(gpa, &client.write_buf, .Unsupported, "") catch {}; | |
| 514 | 514 | client.has_pending_output = true; |
| ... | ... | @@ -838,7 +838,7 @@ pub const Daemon = struct { | |
| 838 | 838 | } | |
| 839 | 839 | ||
| 840 | 840 | const gpa: std.mem.Allocator = blk: { | |
| 841 | - | if (builtin.mode == .Debug) { | |
| 841 | + | if (builtin.mode == .debug) { | |
| 842 | 842 | const GPA = std.heap.DebugAllocator(.{}); | |
| 843 | 843 | const Static = struct { | |
| 844 | 844 | var gpa: GPA = .{}; |
| ... | ... | @@ -1028,7 +1028,7 @@ pub const Daemon = struct { | |
| 1028 | 1028 | // only resize if leader | |
| 1029 | 1029 | if (is_leader) { | |
| 1030 | 1030 | var ws = resize.winsize(); | |
| 1031 | - | _ = cross.c.ioctl(pty_fd, cross.c.TIOCSWINSZ, &ws); | |
| 1031 | + | _ = cross.ioctl(pty_fd, cross.TIOCSWINSZ, &ws); | |
| 1032 | 1032 | ||
| 1033 | 1033 | // On re-attach, deliver SIGWINCH to the foreground process group so | |
| 1034 | 1034 | // incremental renderers (Ink, Claude Code, etc.) know to repaint. |
| ... | ... | @@ -1036,7 +1036,7 @@ pub const Daemon = struct { | |
| 1036 | 1036 | // was unchanged, the kernel suppressed it, so signal the pgrp explicitly. | |
| 1037 | 1037 | if (self.has_pty_output) { | |
| 1038 | 1038 | var pgrp: lib_posix.pid_t = 0; | |
| 1039 | - | if (cross.c.ioctl(pty_fd, cross.c.TIOCGPGRP, &pgrp) == 0 and pgrp > 0) { | |
| 1039 | + | if (cross.ioctl(pty_fd, cross.TIOCGPGRP, &pgrp) == 0 and pgrp > 0) { | |
| 1040 | 1040 | lib_posix.kill(-pgrp, .WINCH) catch {}; | |
| 1041 | 1041 | } | |
| 1042 | 1042 | } |
| ... | ... | @@ -1062,7 +1062,7 @@ pub const Daemon = struct { | |
| 1062 | 1062 | ||
| 1063 | 1063 | const resize = std.mem.bytesToValue(ipc.Resize, payload); | |
| 1064 | 1064 | var ws = resize.winsize(); | |
| 1065 | - | _ = cross.c.ioctl(pty_fd, cross.c.TIOCSWINSZ, &ws); | |
| 1065 | + | _ = cross.ioctl(pty_fd, cross.TIOCSWINSZ, &ws); | |
| 1066 | 1066 | try resizeTerm(gpa, term, resize.cols, resize.rows); | |
| 1067 | 1067 | std.log.debug("resize rows={d} cols={d}", .{ resize.rows, resize.cols }); | |
| 1068 | 1068 | } |
| ... | ... | @@ -1158,7 +1158,7 @@ pub const Daemon = struct { | |
| 1158 | 1158 | ) !void { | |
| 1159 | 1159 | self.setPwd(term); | |
| 1160 | 1160 | const format: util.HistoryFormat = if (payload.len > 0) | |
| 1161 | - | @enumFromInt(payload[0]) | |
| 1161 | + | @fromBackingInt(@intCast(payload[0])) | |
| 1162 | 1162 | else | |
| 1163 | 1163 | .plain; | |
| 1164 | 1164 | if (util.serializeTerminal(gpa, term, format)) |output| { |
+6,
-6
jump to top
+6,
-6
jump to top
| ... | ... | @@ -395,11 +395,11 @@ pub fn listen(sock: socket_t, backlog: u31) ListenError!void { | |
| 395 | 395 | /// the system function call whose errno value is intended to be observed. | |
| 396 | 396 | fn errno(rc: anytype) E { | |
| 397 | 397 | if (use_libc) { | |
| 398 | - | return if (rc == -1) @enumFromInt(std.c._errno().*) else .SUCCESS; | |
| 398 | + | return if (rc == -1) @fromBackingInt(@intCast(std.c._errno().*)) else .SUCCESS; | |
| 399 | 399 | } | |
| 400 | 400 | const signed: isize = @bitCast(rc); | |
| 401 | 401 | const int = if (signed > -4096 and signed < 0) -signed else 0; | |
| 402 | - | return @enumFromInt(int); | |
| 402 | + | return @fromBackingInt(@intCast(int)); | |
| 403 | 403 | } | |
| 404 | 404 | ||
| 405 | 405 | fn setSockFlags(sock: socket_t, flags: u32) !void { |
| ... | ... | @@ -1008,10 +1008,10 @@ pub fn exit(status: u8) noreturn { | |
| 1008 | 1008 | // exit() is only available if exitBootServices() has not been called yet. | |
| 1009 | 1009 | // This call to exit should not fail, so we catch-ignore errors. | |
| 1010 | 1010 | if (uefi.system_table.boot_services) |bs| { | |
| 1011 | - | bs.exit(uefi.handle, @enumFromInt(status), null) catch {}; | |
| 1011 | + | bs.exit(uefi.handle, @fromBackingInt(@intCast(status)), null) catch {}; | |
| 1012 | 1012 | } | |
| 1013 | 1013 | // If we can't exit, reboot the system instead. | |
| 1014 | - | uefi.system_table.runtime_services.resetSystem(.cold, @enumFromInt(status), null); | |
| 1014 | + | uefi.system_table.runtime_services.resetSystem(.cold, @fromBackingInt(@intCast(status)), null); | |
| 1015 | 1015 | } | |
| 1016 | 1016 | system.exit(status); | |
| 1017 | 1017 | } |
| ... | ... | @@ -1244,7 +1244,7 @@ pub fn poll(fds: []pollfd, timeout: i32) PollError!usize { | |
| 1244 | 1244 | /// and you get an unexpected error. | |
| 1245 | 1245 | fn unexpectedErrno(err: E) UnexpectedError { | |
| 1246 | 1246 | if (unexpected_error_tracing) { | |
| 1247 | - | std.debug.print("unexpected errno: {d}\n", .{@intFromEnum(err)}); | |
| 1247 | + | std.debug.print("unexpected errno: {d}\n", .{@backingInt(err)}); | |
| 1248 | 1248 | std.debug.dumpCurrentStackTrace(std.debug.StackUnwindOptions{}); | |
| 1249 | 1249 | } | |
| 1250 | 1250 | return error.Unexpected; |
| ... | ... | @@ -1255,7 +1255,7 @@ fn unexpectedErrno(err: E) UnexpectedError { | |
| 1255 | 1255 | /// If this happens the fix is to add the error code to the corresponding | |
| 1256 | 1256 | /// switch expression, possibly introduce a new error in the error set, and | |
| 1257 | 1257 | /// send a patch to Zig. | |
| 1258 | - | const unexpected_error_tracing = builtin.mode == .Debug and switch (builtin.zig_backend) { | |
| 1258 | + | const unexpected_error_tracing = builtin.mode == .debug and switch (builtin.zig_backend) { | |
| 1259 | 1259 | .stage2_llvm, .stage2_x86_64 => true, | |
| 1260 | 1260 | else => false, | |
| 1261 | 1261 | }; |
+1,
-1
jump to top
+1,
-1
jump to top
| ... | ... | @@ -21,7 +21,7 @@ pub fn installWakeHandler(sig: u6) void { | |
| 21 | 21 | .mask = lib_posix.sigemptyset(), | |
| 22 | 22 | .flags = lib_posix.SA.SIGINFO, | |
| 23 | 23 | }; | |
| 24 | - | lib_posix.sigaction(@as(lib_posix.SIG, @enumFromInt(sig)), &act, null); | |
| 24 | + | lib_posix.sigaction(@as(lib_posix.SIG, @fromBackingInt(@intCast(sig))), &act, null); | |
| 25 | 25 | } | |
| 26 | 26 | ||
| 27 | 27 | pub fn ignoreSigpipe() void { |
+4,
-4
jump to top
+4,
-4
jump to top
| ... | ... | @@ -181,7 +181,7 @@ test "getSocketPath succeeds for paths within limit" { | |
| 181 | 181 | ||
| 182 | 182 | test "getSocketPath returns NameTooLong when path exceeds limit" { | |
| 183 | 183 | const alloc = std.testing.allocator; | |
| 184 | - | const dir = [_]u8{'d'} ** (max_socket_path_len - 2); | |
| 184 | + | const dir: [max_socket_path_len - 2]u8 = @splat('d'); | |
| 185 | 185 | const dir_slice: []const u8 = &dir; | |
| 186 | 186 | ||
| 187 | 187 | const ok = try getSocketPath(alloc, dir_slice, "x"); |
| ... | ... | @@ -194,7 +194,7 @@ test "getSocketPath returns NameTooLong when path exceeds limit" { | |
| 194 | 194 | ||
| 195 | 195 | test "getSocketPath returns NameTooLong for empty dir with oversized name" { | |
| 196 | 196 | const alloc = std.testing.allocator; | |
| 197 | - | const name = [_]u8{'n'} ** (max_socket_path_len); | |
| 197 | + | const name: [max_socket_path_len]u8 = @splat('n'); | |
| 198 | 198 | const name_slice: []const u8 = &name; | |
| 199 | 199 | const err = getSocketPath(alloc, "", name_slice); | |
| 200 | 200 | try std.testing.expectError(error.NameTooLong, err); |
| ... | ... | @@ -205,11 +205,11 @@ test "maxSessionNameLen computes correct dynamic limit" { | |
| 205 | 205 | const short_max = maxSessionNameLen(short_dir).?; | |
| 206 | 206 | try std.testing.expectEqual(max_socket_path_len - short_dir.len - 1, short_max); | |
| 207 | 207 | ||
| 208 | - | const full_dir = [_]u8{'f'} ** max_socket_path_len; | |
| 208 | + | const full_dir: [max_socket_path_len]u8 = @splat('f'); | |
| 209 | 209 | const full_dir_slice: []const u8 = &full_dir; | |
| 210 | 210 | try std.testing.expectEqual(@as(?usize, null), maxSessionNameLen(full_dir_slice)); | |
| 211 | 211 | ||
| 212 | - | const tight_dir = [_]u8{'t'} ** (max_socket_path_len - 2); | |
| 212 | + | const tight_dir: [max_socket_path_len - 2]u8 = @splat('t'); | |
| 213 | 213 | const tight_dir_slice: []const u8 = &tight_dir; | |
| 214 | 214 | try std.testing.expectEqual(@as(?usize, 1), maxSessionNameLen(tight_dir_slice)); | |
| 215 | 215 | } |
+1,
-1
jump to top
+1,
-1
jump to top
| ... | ... | @@ -104,7 +104,7 @@ fn writeDynamicColor( | |
| 104 | 104 | ) void { | |
| 105 | 105 | const c = dynamic.override orelse return; | |
| 106 | 106 | writer.print("\x1b]{d};rgb:{x:0>2}/{x:0>2}/{x:0>2}\x1b\\", .{ | |
| 107 | - | @intFromEnum(kind), c.r, c.g, c.b, | |
| 107 | + | @backingInt(kind), c.r, c.g, c.b, | |
| 108 | 108 | }) catch |err| { | |
| 109 | 109 | std.log.warn("failed to format dynamic color err={s}", .{@errorName(err)}); | |
| 110 | 110 | }; |
+4,
-4
jump to top
+4,
-4
jump to top
| ... | ... | @@ -8,7 +8,7 @@ pub const serializeTerminal = if (has_daemon) terminal.serializeTerminal else st | |
| 8 | 8 | pub const serializeTerminalRange = if (has_daemon) terminal.serializeTerminalRange else struct {}; | |
| 9 | 9 | const ipc = @import("ipc.zig"); | |
| 10 | 10 | const socket = @import("socket.zig"); | |
| 11 | - | const cross = @import("cross.zig"); | |
| 11 | + | const cross = @import("cross"); | |
| 12 | 12 | const label = @import("label.zig"); | |
| 13 | 13 | const lib_posix = @import("posix.zig"); | |
| 14 | 14 | const testing = std.testing; |
| ... | ... | @@ -1122,11 +1122,11 @@ test "isCtrlBackslash xterm modifyOtherKeys" { | |
| 1122 | 1122 | } | |
| 1123 | 1123 | ||
| 1124 | 1124 | test "isDetachKeyDisabled" { | |
| 1125 | - | _ = cross.c.unsetenv("ZMX_NO_DETACH_KEY"); | |
| 1125 | + | _ = cross.unsetenv("ZMX_NO_DETACH_KEY"); | |
| 1126 | 1126 | try testing.expect(!isDetachKeyDisabled()); | |
| 1127 | 1127 | ||
| 1128 | - | _ = cross.c.setenv("ZMX_NO_DETACH_KEY", "1", 1); | |
| 1129 | - | defer _ = cross.c.unsetenv("ZMX_NO_DETACH_KEY"); | |
| 1128 | + | _ = cross.setenv("ZMX_NO_DETACH_KEY", "1", 1); | |
| 1129 | + | defer _ = cross.unsetenv("ZMX_NO_DETACH_KEY"); | |
| 1130 | 1130 | try testing.expect(isDetachKeyDisabled()); | |
| 1131 | 1131 | } | |
| 1132 | 1132 |