This commit adds `dup2` and `dup3` based on musl. Zig already has
wrappers for the syscalls, but musl's implementation checks for a rare,
temporary race condition with dup2/3 and `open`. Like musl, this
implementation adds a fallback for dup3 if the syscall isn't available.
Contributes to: #30978
Before:
* test-zigc: run libzigc unit tests (part of test-modules)
* test-libc: run libc-test cases
Now:
* test-libc: run libc API unit tests (part of test-modules)
* test-libc-nsz: run libc-test cases
libc API unit tests (previously referred to as libzigc unit tests) now run for
all supported targets, even those we don't provide libzigc for. The idea is that
this will help us catch bad assumptions in the unit tests, as well as bugs in
other libcs.
I considered this setup:
* test-c: run libc API unit tests (part of test-modules)
* test-libc-nsz: run libc-test cases
* test-libc: both of the above
However, I do not like it because it gives a false sense of security; the full
module and C ABI test suites are still liable to catch libzigc bugs that test-c
and test-libc-nsz might not. So contributors should just run the test steps
outlined in https://codeberg.org/ziglang/zig/issues/30978.
Co-authored-by: rpkak <rpkak@noreply.codeberg.org>
This required a thorough audit of every syscall wrapper in std.os.linux, so
while I was here, I fixed some minor arch-specific bugs, improved some types,
simplified some casts, and deleted some dead code.
Note that lseek() in particular is still broken for n32 and x32 after this
commit; this wrapper will require some special-casing in the arch bits due to
its unusual return type width.
closes https://github.com/ziglang/zig/issues/22464
closes https://codeberg.org/ziglang/zig/issues/31597
For some of these functions and most targets this changes nothing,
either because long double and double are not equivalent or because
llvm did function deduplication.
But e.g. on aarch64-windows-gnu, ucrt provides hypot, but not hypotl.
Now hypotl calls hypot from ucrt instead of including the std.math.hypot
implementation in zigc.
Very trivial functions (like nanl) are not changed, because a function call would probably make this function more complex.
mingw,musl,wasi-libc: remove c files, that only provide functions already included in zigc
mingw: remove c files, that only provide functions, which are in ucrt
mingw: do not include mingw files/zigc functions on targets on which they in ucrt
Seems like it was missed when implementing `rint`.
This was checked by running:
```
$ ./build/stage3/bin/zig build -p stage4 -Denable-llvm -Dno-lib
$ stage4/bin/zig build test-libc -Dlibc-test-path=<LIBC-TEST-PATH> -Dtest-filter=rint -fqemu -fwasmtime --summary line
Build Summary: 2209/2209 steps succeeded
```
The implementation was ported from `musl` to Zig code, and the `rint`
unit tests were generalized so they could be used for `rintf` as well.
This was checked both through unit tests and running `libc-test` suite:
```
$ ./build/stage3/bin/zig build -p stage4 -Denable-llvm -Dno-lib
$ stage4/bin/zig build test-libc -Dlibc-test-path=<LIBC-TEST-PATH> -Dtest-filter=rintf -fqemu -fwasmtime --summary line
Build Summary: 1657/1657 steps succeeded
```
The behaviour of `libc` `finite` functions is the same as Zig std's, so
the function basically delegates to `math.isFinite` and no new tests were
added. These functions are obsolete, but still part of `musl`.
No results are attached in this case as `libc-test` doesn't have tests for them.
The `frexp` implementation was generalized so it can be used for `f32`
and `c_longdouble` types as well.
The changes were tested by running:
```
$ ./build/stage3/bin/zig build -p stage4 -Denable-llvm -Dno-lib
$ stage4/bin/zig build test-libc -Dlibc-test-path=<LIBC-TEST-PATH> -Dtest-filter=frexp -fqemu -fwasmtime --summary line
Build Summary: 737/737 steps succeeded
$ stage4/bin/zig build test-libc -Dlibc-test-path=<LIBC-TEST-PATH> -Dtest-filter=frexpf -fqemu -fwasmtime --summary line
Build Summary: 369/369 steps succeeded
```
The changes were tested by running:
```
$ ./build/stage3/bin/zig build -p stage4 -Denable-llvm -Dno-lib
$ stage4/bin/zig build test-libc -Dlibc-test-path=<LIBC-TEST-PATH> -Dtest-filter=frexp -fqemu -fwasmtime --summary line
Build Summary: 737/737 steps succeeded
```
The tests were passing even when it was a straightforward calling of Zig
std library, but I wanted the `x is NaN` special case to match the
behaviour described in `libc` manpages, and for it to be consistent
with how infinities as arguments are handled in Zig.
`isastream` is an old, deprecated function for the STREAMS framework.
Linux doesn't even support this natively, and so the musl implementation
just returns 0 (not a STREAMS file) for valid file descriptors or -1
(for bad file descriptors).
`modf` function was generalized and renamed to `modfGeneric`, `modf` and
`modff` provide the appropriate type while calling that function. The
unit tests were also generalized so they can be reused for different
float types.
Both `modf` and `modff` were tested after making these changes:
```
$ stage4/bin/zig build test-libc -Dlibc-test-path=<LIBC-TEST-PATH> -Dtest-filter=modf -fqemu -fwasmtime --summary line
Build Summary: 921/921 steps succeeded
```
```
stage4/bin/zig build test-libc -Dlibc-test-path=<LIBC-TEST-PATH> -Dtest-filter=modff -fqemu -fwasmtime --summary line
Build Summary: 369/369 steps succeeded
```
The behaviour regarding special cases differs between `libc` and Zig's
`stdlib` for `modf`, so the implementation couldn't be a straightforward
calling of `stdlib` function.
Other than the obvious documented differences, I also had problems with
the `INVALID` flag being raised while running `libc-test` suite on riscv
arch through qemu. The solution was to test if the argument is `NaN`,
and then return a quiet `NaN` if so.
Passing tests, that should include all the special cases to be wary of,
were also added.
Test results:
```
$ stage4/bin/zig build test-libc -Dlibc-test-path=<LIBC-TEST-PATH> -Dtest-filter=modf -fqemu -fwasmtime --summary line
Build Summary: 921/921 steps succeeded
```
This commit removes `posix_fadvise`, `posix_fallocate`, and `fallocate`
from the bundled musl by forwarding to Zig's wrappers. `musl`'s
implemenation does not use `__syscall_cp`, so I assume trivially
replacing these functions is okay.
For `posix_fadvise`, `musl` notes that the arguments are reordered
for ARM and other architectures. Zig's wrapper already handles this
case.
Contributes toward: #30978
The functions were sorted alphabetically for easier navigation, and less
confusion where to add a new one. The sorting of comptime exports was
done within the visual "blocks".
Instead of padding, use static entropy to detect corrupted header.
* 64-bit, safe modes: 10 canary bits
* 64-bit, unsafe modes: 0 canary bits
* 32-bit: 27 canary bits
A further enhancement, not done here, would be to upgrade from canary to
parity.
These functions can only be exported when external libc components are
available due to the errno location dependency. Note that even when zig
libc is complete, on Windows, errno location will always be external (in
ucrtbase.dll).