0

I have the following code

const std = @import("std");
const stdio = @cImport({
    @cInclude("stdio.h");
});

const ioctl = @cImport({
    @cInclude("sys/ioctl.h");
    @cInclude("stdio.h");
    @cInclude("unistd.h");
    @cInclude("errno.h");
    @cInclude("termios.h");
});


pub fn main() !void {

    var t = ioctl.termios {

    };

    const is_terminal = ioctl.ioctl(0, ioctl.TIOCGETA, t);
    if (is_terminal == 0) {
        t.c_iflag &= @intCast(@as(c_long, @intCast(~(ioctl.IGNBRK
            | ioctl.BRKINT
            | ioctl.PARMRK
            | ioctl.ISTRIP
            | ioctl.INLCR
            | ioctl.IGNCR
            | ioctl.ICRNL
            | ioctl.IXON))));

        t.c_oflag &= ~ioctl.OPOST;
        t.c_lflag &= ~(ioctl.ECHO | ioctl.ECHONL | ioctl.ICANON | ioctl.ISIG | ioctl.IEXTEN);
        t.c_cflag &= ~(ioctl.CSIZE | ioctl.PARENB);
        t.c_cflag |= ioctl.CS8;
        t.c_cc[ioctl.VMIN] = 1;
        t.c_cc[ioctl.VTIME] = 0;


        ioctl.ioctl(0, ioctl.TIOCSETA, t);
    }



    std.debug.print("Hello {any}.", .{ is_terminal });
}

The goal is to put the terminal into raw mode. Problem is: I can't make zig accept the code. I've done the same call in Java through jextract generated code so I know its right (or should be). Is there something I am missing?

main.zig:46:31: error: type 'c_ulong' cannot represent integer value '-1004'
        t.c_iflag &= @intCast(@as(c_long, @intCast(~(ioctl.IGNBRK
                              ^~~
referenced by:
    main: /Users/emccue/Library/zig/0.15.0-dev.375+8f8f37fb0/lib/std/start.zig:671:37
    comptime: /Users/emccue/Library/zig/0.15.0-dev.375+8f8f37fb0/lib/std/start.zig:58:30
    2 reference(s) hidden; use '-freference-trace=4' to see all references

2 Answers 2

0

I believe you're looking for @bitCast instead of @intCast.

Sign up to request clarification or add additional context in comments.

2 Comments

That gets me a different error ``` main.zig:46:35: error: @bitCast size mismatch: destination type 'c_ulong' has 64 bits but source type 'c_int' has 32 bits t.c_iflag &= @as(c_ulong, @bitCast(~(ioctl.IGNBRK ^~~~~~~~ ```
@EthanMcCue It works for me for what I've tried. Can you create a minimal reproducible example and attach it to the question?
0

If you have a positive number on a signed int.

const i: i32 = 123;

~i will be negative.

assert(~i < 0)

this could be solved with a @bitCast() since @intCast() does not allow to change the sign.

const u: u32 = @bitCast(~i)

The second problem is that c_ulong and c_int have different bitsizes

@bitCast only works if they have the same size.

You can either:

  • First use @intCast() and then use ~ that way you don't cast a negative number.

  • or use a @bitCast() to change the type from c_int to c_uint. and then use intCast() from c_uint to c_ulong.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.