authorgravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2019-05-29 19:38:01-04:00
committergravatar for noreply@github.comGitHub <noreply@github.com> 2019-05-29 19:38:01-04:00
logc66a747045e660a7e8b8146f9ee28c89f3960940
tree6e9ccacd35f42d22f337d21b4e45ce1ffa6106b0
parentbfc86776d501dc317737be09e8ed8d13da18f67c
parentb8d1060f0a240a3907033490a3e6615f78334a97
signaturebadge-question-mark Signed by PGP key 4AEE18F83AFDEB23

Merge pull request #2546 from LemonBoy/sigaltstack

Add sigaltstack syscall for Linux

12 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
54pub fn sigaddset(set: *sigset_t, signo: u5) void {54pub fn sigaddset(set: *sigset_t, signo: u5) void {
55 set.* |= u32(1) << (signo - 1);55 set.* |= u32(1) << (signo - 1);
56}56}
57
58pub 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 @@
1const std = @import("../std.zig");
2use std.c;
3
1extern "c" fn __error() *c_int;4extern "c" fn __error() *c_int;
2pub const _errno = __error;5pub const _errno = __error;
36
4pub extern "c" fn getdents(fd: c_int, buf_ptr: [*]u8, nbytes: usize) usize;7pub extern "c" fn getdents(fd: c_int, buf_ptr: [*]u8, nbytes: usize) usize;
8pub 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;
2525
26pub const dl_iterate_phdr_callback = extern fn (info: *dl_phdr_info, size: usize, data: ?*c_void) c_int;26pub const dl_iterate_phdr_callback = extern fn (info: *dl_phdr_info, size: usize, data: ?*c_void) c_int;
27pub extern "c" fn dl_iterate_phdr(callback: dl_iterate_phdr_callback, data: ?*c_void) c_int;27pub extern "c" fn dl_iterate_phdr(callback: dl_iterate_phdr_callback, data: ?*c_void) c_int;
28
29pub 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 @@
1const std = @import("../std.zig");
2use std.c;
3
1extern "c" fn __errno() *c_int;4extern "c" fn __errno() *c_int;
2pub const _errno = __errno;5pub const _errno = __errno;
36
4pub extern "c" fn getdents(fd: c_int, buf_ptr: [*]u8, nbytes: usize) usize;7pub extern "c" fn getdents(fd: c_int, buf_ptr: [*]u8, nbytes: usize) usize;
8pub 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}
24442444
2445pub 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
2454pub 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
2445test "" {2468test "" {
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;
10781078
1079/// Must be equal largest errno1079/// Must be equal largest errno
1080pub const ELAST = 106;1080pub const ELAST = 106;
1081
1082pub const SIGSTKSZ = 131072;
1083pub const MINSIGSTKSZ = 32768;
1084
1085pub const SS_ONSTACK = 1;
1086pub const SS_DISABLE = 4;
1087
1088pub 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
835pub const EOWNERDEAD = 96; // Previous owner died835pub const EOWNERDEAD = 96; // Previous owner died
836836
837pub const ELAST = 96; // Must be equal largest errno837pub const ELAST = 96; // Must be equal largest errno
838
839pub const MINSIGSTKSZ = switch (builtin.arch) {
840 .i386, .x86_64 => 2048,
841 .arm, .aarch64 => 4096,
842 else => @compileError("MINSIGSTKSZ not defined for this architecture"),
843};
844pub const SIGSTKSZ = MINSIGSTKSZ + 32768;
845
846pub const SS_ONSTACK = 1;
847pub const SS_DISABLE = 4;
848
849pub 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
933pub const MINSIGSTKSZ = switch (builtin.arch) {
934 .i386, .x86_64, .arm => 2048,
935 .aarch64 => 5120,
936 else => @compileError("MINSIGSTKSZ not defined for this architecture"),
937};
938pub 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
944pub const SS_ONSTACK = 1;
945pub const SS_DISABLE = 2;
946pub const SS_AUTODISARM = 1 << 31;
947
948pub 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
723pub const EPROTO = 96; // Protocol error723pub const EPROTO = 96; // Protocol error
724724
725pub const ELAST = 96; // Must equal largest errno725pub const ELAST = 96; // Must equal largest errno
726
727pub const MINSIGSTKSZ = 8192;
728pub const SIGSTKSZ = MINSIGSTKSZ + 32768;
729
730pub const SS_ONSTACK = 1;
731pub const SS_DISABLE = 4;
732
733pub 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}
820820
821pub 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 weak825// XXX: This should be weak
822extern const __ehdr_start: elf.Ehdr = undefined;826extern const __ehdr_start: elf.Ehdr = undefined;
823827
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
153test "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, see1// TODO this is where the extern declarations go. For example, see
2// inc/efilib.h in gnu-efi-code2// inc/efilib.h in gnu-efi-code
3
4const builtin = @import("builtin");
5
6pub const is_the_target = builtin.os == .uefi;