The following program compiles and runs as expected on Linux ( Ubuntu 22.04, Intel I5):
const std = @import("std");
pub fn main() !void {
const maxnr: usize = 1024;
var buf: [maxnr]u8 = undefined;
const len = std.os.linux.getcwd(&buf, maxnr);
std.debug.print("len {}\n", .{ len });
}
On macOS the above compiles and sometimes runs:
test/getcwd » zigdev version
0.17.0-dev.1158+1d1193aa7
test/getcwd » zigdev build-exe -O Debug getcwd.zig && ./getcwd
len 22
test/getcwd » zigdev build-exe -O ReleaseFast getcwd.zig && ./getcwd
len 14
test/getcwd » zigdev build-exe -O ReleaseSafe getcwd.zig && ./getcwd
[1] 59508 invalid system call ./getcwd
If you print out the content of buf after the getcwd on macOS you see that the \xaa are not changed. I have not been able to trace where the value 22 (or 14 come from).
If I am not mistaken this ends up calling syscall2 in lib/std/os/linux/aarch64.zig, but IMO it, and other system calls, should give a compile error instead, when compiling on macOS. It seems potentially dangerous to have the syscall invoked, and AFAICT it can be remedied without affecting (performance) on Linux systems.
I came across this because I needed to know the current directory "depth", and got both std.c.getcwd and std.linux.getcwd searching on https://ziglang.org/documentation/master/std/, and mistakenly thought macOS and Linux were compatible at this level. Since I am compiling on my Intel server (10x faster) everything worked find, and my code also worked for macOS due to faulty logic and limited testing.
As pointed out on ziggit, the correct way is to use std.process.currentPath(io, &buf), and it would be nice if documentation system would show that function if searching for getcwd.