Can't wait for Zig team to adopt this over libc, citing concerns about "libc not existing on certain configurations"[1]
Disappointing that errors are still signaled by assigning to `errno` (you can apparently override this to some other global, but it has to be a global or global-like lvalue).
The kernel actually signals errors by returning a negative error code (on most arches), which seems like a better calling convention. Storing errors in something like `errno` opens a whole can of worms around thread safety and signal safety, while seemingly providing very little benefit beyond following tradition.
> We try to hide some of the differences between arches when reasonably feasible. e.g. Newer architectures no longer provide an open syscall, but do provide openat. We will still expose a sys_open helper by default that calls into openat instead.
Sometimes you actually want to make sure that the exact syscall is called; e.g. you're writing a little program protected by strict seccomp rules. If the layer can magically call some other syscall under the hood this won't work anymore.
You have to be pretty careful when using syscalls directly, at least in the presence of some libc. For example, from what I have gathered from random tidbits here and there, it's not a good idea to use any of the fork-like calls (fork, clone, etc.) if you have any threads that were created using glibc.
I've been using my own version of this. Maybe I'll switch over, this looks more complete.
Using go is a nice way to do that by default as it also directly uses syscalls (see the sys package)
Just a friendly reminder that syscall() is a vararg function. Meaning, you can't just go throwing arguments at it (so maybe it's better to use this wrapper to avoid problems instead).
For example, on a 64-bit arch, this code would be sus.
syscall(__NR_syscall_taking_6_args, 1, 2, 3, 4, 5, 6);
Quiz: why
PS: it's a common mistake, so I thought I'd save you a trip down the debugging rabbit hole.
0-Day incoming
See also Linux's nolibc headers, which allows one to write C software that completely bypass libc, but instead directly operate through syscalls.
https://github.com/torvalds/linux/tree/master/tools/include/...
A sample use-case? I was developing an Erlang-like actor platform that should operate under Linux as well as a bare-metal microkernel, and all I needed is a light layer over syscalls instead of pulling the entire glibc. Also it provides a simple implementation for standard C functions (memcpy, printf) so I don't have to write them myself.