| author | |
| committer | |
| log | c66a747045e660a7e8b8146f9ee28c89f3960940 |
| tree | 6e9ccacd35f42d22f337d21b4e45ce1ffa6106b0 |
| parent | bfc86776d501dc317737be09e8ed8d13da18f67c |
| parent | b8d1060f0a240a3907033490a3e6615f78334a97 |
| signature |
Add sigaltstack syscall for Linux12 files changed, 115 insertions(+), 0 deletions(-)
std/c/darwin.zig+2| ... | @@ -54,3 +54,5 @@ pub extern "c" fn mach_port_deallocate(task: ipc_space_t, name: mach_port_name_t | ... | @@ -54,3 +54,5 @@ pub extern "c" fn mach_port_deallocate(task: ipc_space_t, name: mach_port_name_t |
| 54 | pub fn sigaddset(set: *sigset_t, signo: u5) void { | 54 | pub fn sigaddset(set: *sigset_t, signo: u5) void { |
| 55 | set.* |= u32(1) << (signo - 1); | 55 | set.* |= u32(1) << (signo - 1); |
| 56 | } | 56 | } |
| 57 | |||
| 58 | pub extern "c" fn sigaltstack(ss: ?*stack_t, old_ss: ?*stack_t) c_int; |
std/c/freebsd.zig+4| ... | @@ -1,4 +1,8 @@ | ... | @@ -1,4 +1,8 @@ |
| 1 | const std = @import("../std.zig"); | ||
| 2 | use std.c; | ||
| 3 | |||
| 1 | extern "c" fn __error() *c_int; | 4 | extern "c" fn __error() *c_int; |
| 2 | pub const _errno = __error; | 5 | pub const _errno = __error; |
| 3 | 6 | ||
| 4 | pub extern "c" fn getdents(fd: c_int, buf_ptr: [*]u8, nbytes: usize) usize; | 7 | pub extern "c" fn getdents(fd: c_int, buf_ptr: [*]u8, nbytes: usize) usize; |
| 8 | pub extern "c" fn sigaltstack(ss: ?*stack_t, old_ss: ?*stack_t) c_int; |
std/c/linux.zig+2| ... | @@ -25,3 +25,5 @@ pub extern "c" fn getauxval(__type: c_ulong) c_ulong; | ... | @@ -25,3 +25,5 @@ pub extern "c" fn getauxval(__type: c_ulong) c_ulong; |
| 25 | 25 | ||
| 26 | pub const dl_iterate_phdr_callback = extern fn (info: *dl_phdr_info, size: usize, data: ?*c_void) c_int; | 26 | pub const dl_iterate_phdr_callback = extern fn (info: *dl_phdr_info, size: usize, data: ?*c_void) c_int; |
| 27 | pub extern "c" fn dl_iterate_phdr(callback: dl_iterate_phdr_callback, data: ?*c_void) c_int; | 27 | pub extern "c" fn dl_iterate_phdr(callback: dl_iterate_phdr_callback, data: ?*c_void) c_int; |
| 28 | |||
| 29 | pub extern "c" fn sigaltstack(ss: ?*stack_t, old_ss: ?*stack_t) c_int; |
std/c/netbsd.zig+4| ... | @@ -1,4 +1,8 @@ | ... | @@ -1,4 +1,8 @@ |
| 1 | const std = @import("../std.zig"); | ||
| 2 | use std.c; | ||
| 3 | |||
| 1 | extern "c" fn __errno() *c_int; | 4 | extern "c" fn __errno() *c_int; |
| 2 | pub const _errno = __errno; | 5 | pub const _errno = __errno; |
| 3 | 6 | ||
| 4 | pub extern "c" fn getdents(fd: c_int, buf_ptr: [*]u8, nbytes: usize) usize; | 7 | pub extern "c" fn getdents(fd: c_int, buf_ptr: [*]u8, nbytes: usize) usize; |
| 8 | pub extern "c" fn sigaltstack(ss: ?*stack_t, old_ss: ?*stack_t) c_int; |
std/os.zig+23| ... | @@ -2442,6 +2442,29 @@ pub fn unexpectedErrno(err: usize) UnexpectedError { | ... | @@ -2442,6 +2442,29 @@ pub fn unexpectedErrno(err: usize) UnexpectedError { |
| 2442 | return error.Unexpected; | 2442 | return error.Unexpected; |
| 2443 | } | 2443 | } |
| 2444 | 2444 | ||
| 2445 | pub const SigaltstackError = error{ | ||
| 2446 | /// The supplied stack size was less than MINSIGSTKSZ. | ||
| 2447 | SizeTooSmall, | ||
| 2448 | |||
| 2449 | /// Attempted to change the signal stack while it was active. | ||
| 2450 | PermissionDenied, | ||
| 2451 | Unexpected, | ||
| 2452 | }; | ||
| 2453 | |||
| 2454 | pub fn sigaltstack(ss: ?*stack_t, old_ss: ?*stack_t) SigaltstackError!void { | ||
| 2455 | if (windows.is_the_target or uefi.is_the_target or wasi.is_the_target) | ||
| 2456 | @compileError("std.os.sigaltstack not available for this target"); | ||
| 2457 | |||
| 2458 | switch (errno(system.sigaltstack(ss, old_ss))) { | ||
| 2459 | 0 => return, | ||
| 2460 | EFAULT => unreachable, | ||
| 2461 | EINVAL => unreachable, | ||
| 2462 | ENOMEM => return error.SizeTooSmall, | ||
| 2463 | EPERM => return error.PermissionDenied, | ||
| 2464 | else => |err| return unexpectedErrno(err), | ||
| 2465 | } | ||
| 2466 | } | ||
| 2467 | |||
| 2445 | test "" { | 2468 | test "" { |
| 2446 | _ = @import("os/darwin.zig"); | 2469 | _ = @import("os/darwin.zig"); |
| 2447 | _ = @import("os/freebsd.zig"); | 2470 | _ = @import("os/freebsd.zig"); |
std/os/bits/darwin.zig+12| ... | @@ -1078,3 +1078,15 @@ pub const EQFULL = 106; | ... | @@ -1078,3 +1078,15 @@ pub const EQFULL = 106; |
| 1078 | 1078 | ||
| 1079 | /// Must be equal largest errno | 1079 | /// Must be equal largest errno |
| 1080 | pub const ELAST = 106; | 1080 | pub const ELAST = 106; |
| 1081 | |||
| 1082 | pub const SIGSTKSZ = 131072; | ||
| 1083 | pub const MINSIGSTKSZ = 32768; | ||
| 1084 | |||
| 1085 | pub const SS_ONSTACK = 1; | ||
| 1086 | pub const SS_DISABLE = 4; | ||
| 1087 | |||
| 1088 | pub const stack_t = extern struct { | ||
| 1089 | ss_sp: [*]u8, | ||
| 1090 | ss_size: isize, | ||
| 1091 | ss_flags: i32, | ||
| 1092 | }; |
std/os/bits/freebsd.zig+16| ... | @@ -835,3 +835,19 @@ pub const ENOTRECOVERABLE = 95; // State not recoverable | ... | @@ -835,3 +835,19 @@ pub const ENOTRECOVERABLE = 95; // State not recoverable |
| 835 | pub const EOWNERDEAD = 96; // Previous owner died | 835 | pub const EOWNERDEAD = 96; // Previous owner died |
| 836 | 836 | ||
| 837 | pub const ELAST = 96; // Must be equal largest errno | 837 | pub const ELAST = 96; // Must be equal largest errno |
| 838 | |||
| 839 | pub const MINSIGSTKSZ = switch (builtin.arch) { | ||
| 840 | .i386, .x86_64 => 2048, | ||
| 841 | .arm, .aarch64 => 4096, | ||
| 842 | else => @compileError("MINSIGSTKSZ not defined for this architecture"), | ||
| 843 | }; | ||
| 844 | pub const SIGSTKSZ = MINSIGSTKSZ + 32768; | ||
| 845 | |||
| 846 | pub const SS_ONSTACK = 1; | ||
| 847 | pub const SS_DISABLE = 4; | ||
| 848 | |||
| 849 | pub const stack_t = extern struct { | ||
| 850 | ss_sp: [*]u8, | ||
| 851 | ss_size: isize, | ||
| 852 | ss_flags: i32, | ||
| 853 | }; |
std/os/bits/linux.zig+21| ... | @@ -929,3 +929,24 @@ pub fn CPU_COUNT(set: cpu_set_t) cpu_count_t { | ... | @@ -929,3 +929,24 @@ pub fn CPU_COUNT(set: cpu_set_t) cpu_count_t { |
| 929 | //#define CPU_COUNT(set) CPU_COUNT_S(sizeof(cpu_set_t),set) | 929 | //#define CPU_COUNT(set) CPU_COUNT_S(sizeof(cpu_set_t),set) |
| 930 | //#define CPU_ZERO(set) CPU_ZERO_S(sizeof(cpu_set_t),set) | 930 | //#define CPU_ZERO(set) CPU_ZERO_S(sizeof(cpu_set_t),set) |
| 931 | //#define CPU_EQUAL(s1,s2) CPU_EQUAL_S(sizeof(cpu_set_t),s1,s2) | 931 | //#define CPU_EQUAL(s1,s2) CPU_EQUAL_S(sizeof(cpu_set_t),s1,s2) |
| 932 | |||
| 933 | pub const MINSIGSTKSZ = switch (builtin.arch) { | ||
| 934 | .i386, .x86_64, .arm => 2048, | ||
| 935 | .aarch64 => 5120, | ||
| 936 | else => @compileError("MINSIGSTKSZ not defined for this architecture"), | ||
| 937 | }; | ||
| 938 | pub const SIGSTKSZ = switch (builtin.arch) { | ||
| 939 | .i386, .x86_64, .arm => 8192, | ||
| 940 | .aarch64 => 16384, | ||
| 941 | else => @compileError("SIGSTKSZ not defined for this architecture"), | ||
| 942 | }; | ||
| 943 | |||
| 944 | pub const SS_ONSTACK = 1; | ||
| 945 | pub const SS_DISABLE = 2; | ||
| 946 | pub const SS_AUTODISARM = 1 << 31; | ||
| 947 | |||
| 948 | pub const stack_t = extern struct { | ||
| 949 | ss_sp: [*]u8, | ||
| 950 | ss_flags: i32, | ||
| 951 | ss_size: isize, | ||
| 952 | }; |
std/os/bits/netbsd.zig+12| ... | @@ -723,3 +723,15 @@ pub const ENOLINK = 95; // Link has been severed | ... | @@ -723,3 +723,15 @@ pub const ENOLINK = 95; // Link has been severed |
| 723 | pub const EPROTO = 96; // Protocol error | 723 | pub const EPROTO = 96; // Protocol error |
| 724 | 724 | ||
| 725 | pub const ELAST = 96; // Must equal largest errno | 725 | pub const ELAST = 96; // Must equal largest errno |
| 726 | |||
| 727 | pub const MINSIGSTKSZ = 8192; | ||
| 728 | pub const SIGSTKSZ = MINSIGSTKSZ + 32768; | ||
| 729 | |||
| 730 | pub const SS_ONSTACK = 1; | ||
| 731 | pub const SS_DISABLE = 4; | ||
| 732 | |||
| 733 | pub const stack_t = extern struct { | ||
| 734 | ss_sp: [*]u8, | ||
| 735 | ss_size: isize, | ||
| 736 | ss_flags: i32, | ||
| 737 | }; |
std/os/linux.zig+4| ... | @@ -818,6 +818,10 @@ pub fn capset(hdrp: *cap_user_header_t, datap: *const cap_user_data_t) usize { | ... | @@ -818,6 +818,10 @@ pub fn capset(hdrp: *cap_user_header_t, datap: *const cap_user_data_t) usize { |
| 818 | return syscall2(SYS_capset, @ptrToInt(hdrp), @ptrToInt(datap)); | 818 | return syscall2(SYS_capset, @ptrToInt(hdrp), @ptrToInt(datap)); |
| 819 | } | 819 | } |
| 820 | 820 | ||
| 821 | pub fn sigaltstack(ss: ?*stack_t, old_ss: ?*stack_t) usize { | ||
| 822 | return syscall2(SYS_sigaltstack, @ptrToInt(ss), @ptrToInt(old_ss)); | ||
| 823 | } | ||
| 824 | |||
| 821 | // XXX: This should be weak | 825 | // XXX: This should be weak |
| 822 | extern const __ehdr_start: elf.Ehdr = undefined; | 826 | extern const __ehdr_start: elf.Ehdr = undefined; |
| 823 | 827 |
std/os/test.zig+11| ... | @@ -149,3 +149,14 @@ test "realpath" { | ... | @@ -149,3 +149,14 @@ test "realpath" { |
| 149 | var buf: [std.fs.MAX_PATH_BYTES]u8 = undefined; | 149 | var buf: [std.fs.MAX_PATH_BYTES]u8 = undefined; |
| 150 | testing.expectError(error.FileNotFound, fs.realpath("definitely_bogus_does_not_exist1234", &buf)); | 150 | testing.expectError(error.FileNotFound, fs.realpath("definitely_bogus_does_not_exist1234", &buf)); |
| 151 | } | 151 | } |
| 152 | |||
| 153 | test "sigaltstack" { | ||
| 154 | if (builtin.os == .windows or builtin.os == .wasi) return error.SkipZigTest; | ||
| 155 | |||
| 156 | var st: os.stack_t = undefined; | ||
| 157 | try os.sigaltstack(null, &st); | ||
| 158 | // Setting a stack size less than MINSIGSTKSZ returns ENOMEM | ||
| 159 | st.ss_flags = 0; | ||
| 160 | st.ss_size = 1; | ||
| 161 | testing.expectError(error.SizeTooSmall, os.sigaltstack(&st, null)); | ||
| 162 | } |
std/os/uefi.zig+4| ... | @@ -1,2 +1,6 @@ | ... | @@ -1,2 +1,6 @@ |
| 1 | // TODO this is where the extern declarations go. For example, see | 1 | // TODO this is where the extern declarations go. For example, see |
| 2 | // inc/efilib.h in gnu-efi-code | 2 | // inc/efilib.h in gnu-efi-code |
| 3 | |||
| 4 | const builtin = @import("builtin"); | ||
| 5 | |||
| 6 | pub const is_the_target = builtin.os == .uefi; |