| author | |
| committer | |
| log | 6eb5e56306620e72ae80d7ad6626f8d0ceb24af5 |
| tree | 2ca4383369165a41814d3b95f148e86f46627920 |
| parent | 85a6b75e18248bad83437323cab14fe1973057ec |
For C code the macros SIGRTMIN and SIGRTMAX provide these values. In
practice what looks like a constant is actually provided by a libc call.
So the Zig implementations are explicitly function calls.
glibc (and Musl) export a run-time minimum "real-time" signal number,
based on how many signals are reserved for internal implementation details
(generally threading). In practice, on Linux, sigrtmin() is 35 on glibc
with the older LinuxThread and 34 with the newer NPTL-based
implementation. Musl always returns 35. The maximum "real-time" signal
number is NSIG - 1 (64 on most Linux kernels, but 128 on MIPS).
When not linking a C Library, Zig can report the full range of "rt"
signals (none are reserved by Zig).
Fixes #211894 files changed, 44 insertions(+), 2 deletions(-)
lib/std/c.zig+13| ... | @@ -10347,6 +10347,16 @@ pub const sigaction = switch (native_os) { | ... | @@ -10347,6 +10347,16 @@ pub const sigaction = switch (native_os) { |
| 10347 | else => private.sigaction, | 10347 | else => private.sigaction, |
| 10348 | }; | 10348 | }; |
| 10349 | 10349 | ||
| 10350 | /// Zig's version of SIGRTMIN. Actually a function. | ||
| 10351 | pub fn sigrtmin() u8 { | ||
| 10352 | return @truncate(@as(c_uint, @bitCast(private.__libc_current_sigrtmin()))); | ||
| 10353 | } | ||
| 10354 | |||
| 10355 | /// Zig's version of SIGRTMAX. Actually a function. | ||
| 10356 | pub fn sigrtmax() u8 { | ||
| 10357 | return @truncate(@as(c_uint, @bitCast(private.__libc_current_sigrtmax()))); | ||
| 10358 | } | ||
| 10359 | |||
| 10350 | pub const sigfillset = switch (native_os) { | 10360 | pub const sigfillset = switch (native_os) { |
| 10351 | .netbsd => private.__sigfillset14, | 10361 | .netbsd => private.__sigfillset14, |
| 10352 | else => private.sigfillset, | 10362 | else => private.sigfillset, |
| ... | @@ -11213,6 +11223,9 @@ const private = struct { | ... | @@ -11213,6 +11223,9 @@ const private = struct { |
| 11213 | extern "c" fn __getdents30(fd: c_int, buf_ptr: [*]u8, nbytes: usize) c_int; | 11223 | extern "c" fn __getdents30(fd: c_int, buf_ptr: [*]u8, nbytes: usize) c_int; |
| 11214 | extern "c" fn __sigaltstack14(ss: ?*stack_t, old_ss: ?*stack_t) c_int; | 11224 | extern "c" fn __sigaltstack14(ss: ?*stack_t, old_ss: ?*stack_t) c_int; |
| 11215 | 11225 | ||
| 11226 | extern "c" fn __libc_current_sigrtmin() c_int; | ||
| 11227 | extern "c" fn __libc_current_sigrtmax() c_int; | ||
| 11228 | |||
| 11216 | // Don't forget to add another clown when an OS picks yet another unique | 11229 | // Don't forget to add another clown when an OS picks yet another unique |
| 11217 | // symbol name for errno location! | 11230 | // symbol name for errno location! |
| 11218 | // 🤡🤡🤡🤡🤡🤡 | 11231 | // 🤡🤡🤡🤡🤡🤡 |
lib/std/os/linux.zig+13| ... | @@ -1801,6 +1801,19 @@ const SigsetElement = c_ulong; | ... | @@ -1801,6 +1801,19 @@ const SigsetElement = c_ulong; |
| 1801 | 1801 | ||
| 1802 | const sigset_len = @typeInfo(sigset_t).array.len; | 1802 | const sigset_len = @typeInfo(sigset_t).array.len; |
| 1803 | 1803 | ||
| 1804 | /// Zig's SIGRTMIN, but is a function for compatibility with glibc | ||
| 1805 | pub fn sigrtmin() u8 { | ||
| 1806 | // Default is 32 in the kernel UAPI: https://github.com/torvalds/linux/blob/78109c591b806e41987e0b83390e61d675d1f724/include/uapi/asm-generic/signal.h#L50 | ||
| 1807 | // AFAICT, all architectures that override this also set it to 32: | ||
| 1808 | // https://github.com/search?q=repo%3Atorvalds%2Flinux+sigrtmin+path%3Auapi&type=code | ||
| 1809 | return 32; | ||
| 1810 | } | ||
| 1811 | |||
| 1812 | /// Zig's SIGRTMAX, but is a function for compatibility with glibc | ||
| 1813 | pub fn sigrtmax() u8 { | ||
| 1814 | return NSIG - 1; | ||
| 1815 | } | ||
| 1816 | |||
| 1804 | /// Zig's version of sigemptyset. Returns initialized sigset_t. | 1817 | /// Zig's version of sigemptyset. Returns initialized sigset_t. |
| 1805 | pub fn sigemptyset() sigset_t { | 1818 | pub fn sigemptyset() sigset_t { |
| 1806 | return [_]SigsetElement{0} ** sigset_len; | 1819 | return [_]SigsetElement{0} ** sigset_len; |
lib/std/posix.zig+2| ... | @@ -151,6 +151,8 @@ pub const rusage = system.rusage; | ... | @@ -151,6 +151,8 @@ pub const rusage = system.rusage; |
| 151 | pub const sa_family_t = system.sa_family_t; | 151 | pub const sa_family_t = system.sa_family_t; |
| 152 | pub const siginfo_t = system.siginfo_t; | 152 | pub const siginfo_t = system.siginfo_t; |
| 153 | pub const sigset_t = system.sigset_t; | 153 | pub const sigset_t = system.sigset_t; |
| 154 | pub const sigrtmin = system.sigrtmin; | ||
| 155 | pub const sigrtmax = system.sigrtmax; | ||
| 154 | pub const sockaddr = system.sockaddr; | 156 | pub const sockaddr = system.sockaddr; |
| 155 | pub const socklen_t = system.socklen_t; | 157 | pub const socklen_t = system.socklen_t; |
| 156 | pub const stack_t = system.stack_t; | 158 | pub const stack_t = system.stack_t; |
lib/std/posix/test.zig+16-2| ... | @@ -859,6 +859,17 @@ test "shutdown socket" { | ... | @@ -859,6 +859,17 @@ test "shutdown socket" { |
| 859 | std.net.Stream.close(.{ .handle = sock }); | 859 | std.net.Stream.close(.{ .handle = sock }); |
| 860 | } | 860 | } |
| 861 | 861 | ||
| 862 | test "sigrtmin/max" { | ||
| 863 | if (native_os == .wasi or native_os == .windows or native_os == .macos) { | ||
| 864 | return error.SkipZigTest; | ||
| 865 | } | ||
| 866 | |||
| 867 | try std.testing.expect(posix.sigrtmin() >= 32); | ||
| 868 | try std.testing.expect(posix.sigrtmin() >= posix.system.sigrtmin()); | ||
| 869 | try std.testing.expect(posix.sigrtmin() < posix.system.sigrtmax()); | ||
| 870 | try std.testing.expect(posix.sigrtmax() < posix.NSIG); | ||
| 871 | } | ||
| 872 | |||
| 862 | test "sigset empty/full" { | 873 | test "sigset empty/full" { |
| 863 | if (native_os == .wasi or native_os == .windows) | 874 | if (native_os == .wasi or native_os == .windows) |
| 864 | return error.SkipZigTest; | 875 | return error.SkipZigTest; |
| ... | @@ -875,10 +886,13 @@ test "sigset empty/full" { | ... | @@ -875,10 +886,13 @@ test "sigset empty/full" { |
| 875 | try expectEqual(true, posix.sigismember(&set, @truncate(posix.SIG.INT))); | 886 | try expectEqual(true, posix.sigismember(&set, @truncate(posix.SIG.INT))); |
| 876 | } | 887 | } |
| 877 | 888 | ||
| 878 | // Some signals (32 - 34 on glibc/musl) are not allowed to be added to a | 889 | // Some signals (i.e., 32 - 34 on glibc/musl) are not allowed to be added to a |
| 879 | // sigset by the C library, so avoid testing them. | 890 | // sigset by the C library, so avoid testing them. |
| 880 | fn reserved_signo(i: usize) bool { | 891 | fn reserved_signo(i: usize) bool { |
| 881 | return builtin.link_libc and (i >= 32 and i <= 34); | 892 | if (native_os == .macos) { |
| 893 | return false; | ||
| 894 | } | ||
| 895 | return builtin.link_libc and (i >= 32 and i < posix.sigrtmin()); | ||
| 882 | } | 896 | } |
| 883 | 897 | ||
| 884 | test "sigset add/del" { | 898 | test "sigset add/del" { |