Os.linux.epoll_create1 compile error

$ /opt/zig-0.12/zig build
└─ install xjiss
   └─ zig build-exe xjiss Debug native 1 errors
error: expected error union type, found 'usize'
            .fd = try epollCreate(0),
referenced by:
    onStack: src/engine/message-queue.zig:122:39
    main: src/main.zig:30:35

src/engine/event-capture.zig:33 is .fd = try epollCreate(0),

What is the definition of fn epollCreate(?) ? {

const epollCreate = os.linux.epoll_create1;

There is no need for try since both 0.11.0 and 0.12.0 versions return usize without errors.

If you used std.os.epoll_create1 the correct replacement is std.posix.epoll_create1, since package os became posix.

I think this is wrong for a number of reasons, here is an excerpt from man epoll_create1:

       EINVAL size is not positive.

       EINVAL (epoll_create1()) Invalid value specified in flags.

       EMFILE The per-user limit on the number of epoll instances  imposed  by
              /proc/sys/fs/epoll/max_user_instances   was   encountered.   See
              epoll(7) for further details.

       EMFILE The per-process limit on the number of open file descriptors has
              been reached.

       ENFILE The system-wide limit on the total number of open files has been

       ENOMEM There was insufficient memory to create the kernel object.

Since when did epoll became posix compliant?
It’s a feature of linux, akin FreeBSD kqueue or Solaris /dev/poll (do not remember an exact name, sorry)


the further into the forest the thicker the partisans :slight_smile:

$ /opt/zig-0.12/zig build
└─ install xjiss
   └─ zig build-exe xjiss Debug native 2 errors
        error: root struct of file 'os' has no member named 'getenv'
        sd.device = os.getenv("XJIS_PLAYBACK_DEVICE") orelse default_device;
rc/state-machines/client.zig:146:15: error: 'posix' is not marked 'pub'
/opt/zig-0.12/lib/std/os.zig:25:1: note: declared here
const posix = std.posix;

I am standing on asphalt
With the skis on my feet
Either skis aren’t running
Or I’m moron indeed.

The call is not in the package std.os.posix it is in the std.posix.

ok, but posix means “Portable OS (operating system) interface” (with an X at the end for the purpose of coolness) , does not it?

And if so, I would place “universal” (POSIX compliant) syscalls into os.posix.

1 Like

gor… :frowning:

opt/zig-0.12/lib/std/os.zig:1:1: note: struct declared here
//! This file contains thin wrappers around OS-specific APIs, with these
src/engine/event-sources.zig:177:28: error: 'TFD_TIMER' is not marked 'pub'
        const tid: os.linux.TFD_TIMER = 0;
/opt/zig-0.12/lib/std/os/linux.zig:4251:1: note: declared here
const TFD_TIMER = packed struct(u32) {

What’s the differnet between std.os.linux and std.posix at this point?

What’s the differnet between std.os.linux and std.posix at this point?

I still think there should be std.os.posix and a some number of std.os.<os-name>.

see std.os.linux.TFD_TIMER

    const tid: os.linux.TFDTIMER = os.linux.TFDTIMER{};

and then instead of tid |= ABSTIME; you call tid.ABSTIME = true;

std.os.linux (or other operating systems) are specific calls for linux.
These are direct system calls and may not return zig errors.

std.posix is derived from the older std.os.
std.os was trying to create an zig friendly abstraction.
Posix is a standard that defines unix API.

1 Like

That’s kind of the point. When I think POSIX, I think this:


Epoll isn’t part of POSIX so I wouldn’t expect it t be there.

I didn’t know std.os.linux was just mostly 1 liner syscall wrrappers. That’s really nice to know.


… and as it appeared, such an abstraction is not so easy to implement, right?..

see: Eliminate the POSIX API layer #6600

I’m on that team 100%

The Handle abstraction floating around a lot of those function isn’t very useful and detrimental as other code tries to use it. Like much of the posix namespace, it exists is the leaky halfway abstraction between std.os.* and std.{fs,net,...}.* that should be mostly ditched.

Ok, I will mark this as solution,
but it’s strange to see epoll_create1, epoll_ctl, epoll_wait, timerfd_create inside std.posix. they all should be in std.os.linux or something like this.

Moreover, we have (as an example):

/opt/zig-0.12/lib/std/posix.zig:pub fn timerfd_create(clokid: i32, flags: linux.TFD) TimerFdCreateError!fd_t {
/opt/zig-0.12/lib/std/os/linux.zig:pub fn timerfd_create(clockid: i32, flags: TFD) usize {

The first is a wrapper for the second, ok.


$ grep -rI "const itimerspec" /opt/zig-0.12/
/opt/zig-0.12/lib/std/os/linux.zig:pub const itimerspec = extern struct {
/opt/zig-0.12/lib/std/os/linux.zig:pub fn timerfd_settime(fd: i32, flags: TFD.TIMER, new_value: *const itimerspec, old_value: ?*itimerspec) usize {
/opt/zig-0.12/lib/std/os/linux.zig:pub fn setitimer(which: i32, new_value: *const itimerspec, old_value: ?*itimerspec) usize {
/opt/zig-0.12/lib/std/c/haiku.zig:pub const itimerspec = extern struct {

So some OS facility, specific to Linux (timerfd) is in std.posix, but data structures for this facility are still in std.os.linux… it is confusing, at least.

1 Like