64bit ioctl on Darwin?

(Using zig 0.13.0 on aarch64-macos)

TLDR; How do I call a Darwin ioctl with a 64bit opcode?

I have some terminal code where I’m successfully reading the terminal size, using

var ws: std.posix.winsize = undefined;
const err = std.posix.system.ioctl(stdin_reader.handle, std.posix.T.IOCGWINSZ, @intFromPtr(&ws));

Now, I am trying to call the set size version IOCSWINSZ. This isn’t defined in std/c/darwin.zig.
So, I searched around and found that the actual op code is 0x80087467. However, if I put this into std.posix.system.ioctl() I get error: type 'c_int' cannot represent integer value '2148037735'

std.c.ioctl defines

pub extern "c" fn ioctl(fd: fd_t, request: c_int, ...) c_int

But, darwin-xnu/bsd/sys/ioctl.h defines

int ioctl(int, unsigned long, ...);

Do I need to define a specific darwin ioctl fn in the zig library to accept 64 bit opcodes?

That request code will fit in 32 bits, you’ll just need to @bitCast from unsigned to signed.

Not pretty, but it works, thanks.

const IOCSWINSZ:u64 = 0x80087467;
const TIOCSWINSZ = if (std.Target.Os.Tag.isDarwin(builtin.target.os.tag)) @as(c_int, @truncate(@as(i64, @bitCast(IOCSWINSZ)))) else std.posix.T.IOCSWINSZ;
const err = std.posix.system.ioctl(master_pt.handle, TIOCSWINSZ, @intFromPtr(&ws));
2 Likes