Issues with std.os.linux.tcgetattr

Code:

var tty: std.fs.File = try std.fs.cwd().openFile("/dev/tty", .{});
defer tty.close();
var thing: os.linux.termios = undefined;
_ = std.os.linux.tcgetattr(tty.handle, &thing);
std.debug.print("{}\n", .{thing});

Gives: panic: invalid enum value when printing

However using _ = std.c.tcgetattr(tty.handle, &thing); works perfectly fine.

New to Zig so I might be making a basic mistake, but I’ve been trying to make it work for a while now and I can’t wrap my head around it.

Welcome to Ziggit @bradwiggo!

I am not really familar with the details of tcgetattr, but is it possible that the ignored return value would indicate that tcgetattr failed and thus didn’t write anything to &thing for some reason?

I think you should check the value of the result and if it indicates an error, check errno according to the Result section on https://linux.die.net/man/3/tcgetattr and how this is implemented: https://ziglang.org/documentation/master/std/#std.posix.tcgetattr

Basically it seems like you aren’t guaranteed to successfully read the result and may even need to poll/retry a bunch of times based on what is indicated by the errno value. (If I interprete the implementation within the posix namespace correctly)

I think instead of doing that manually, you can use std.posix.tcgetattr, which is a more abstracted/ziggified interface to the lower level os specific implementation.

3 Likes

You should check that return value from the function instead of discarding it.