I use kqueue(2) on macOS, FreeBSD, NetBSD, OpenBSD, DragonflyBSD.
The kevent structure is defined as follow. Specifically, the field udata is a pointer for some user-specific data structure.
struct kevent {
uintptr_t ident; /* identifier for this event */
short filter; /* filter for event */
u_short flags;
u_int fflags;
intptr_t data;
void *udata; /* opaque user data identifier */
};
This is true on all the above-mentioned systems, except for NetBSD where the documentation and the system headers are inconsistent.
$ uname -a
NetBSD vminetbsd 10.1 NetBSD 10.1 (GENERIC) #0: Mon Dec 16 13:08:11 UTC 2024 mkrepro@mkrepro.NetBSD.org:/usr/src/sys/arch/amd64/compile/GENERIC amd64
$ grep udata /usr/include/sys/event.h
intptr_t udata; /* opaque user data identifier */
Here, the udata field is an integer and the compilation of the application fails when passing the address of a user data structure. Of course, it is possible to use some type cast in some #ifdef structure to make the application portable, although much less readable.
However, this is not so simple.
On the very same NetBSD system, man kqueue also displays intptr_t udata. However, the NetBSD web site documents the opposite.
On https://man.netbsd.org/kqueue.2, the title is "kqueue(2) - NetBSD Manual Pages" and the content says "void *udata", not integer.
The NetBSD web site also contains a nice kqueue tutorial in https://wiki.netbsd.org/tutorials/kqueue_tutorial/ which also says "void *udata", not integer.
So, it seems that NetBSD is somewhat inconsistent. The website and official documentation pretend to be "standard", or at least like all other BSD. But a real system with the latest version (10.1) contains something different, both in the header and the man page.
Can we say that this is a bug in NetBSD? And where should we report those bugs?
Using a type cast in the application code with #ifdef on NetBSD will then become incorrect later if they fix the issue.