Merge pull request #2546 from LemonBoy/sigaltstack
Add sigaltstack syscall for Linux
This commit is contained in:
commit
c66a747045
|
@ -54,3 +54,5 @@ pub extern "c" fn mach_port_deallocate(task: ipc_space_t, name: mach_port_name_t
|
|||
pub fn sigaddset(set: *sigset_t, signo: u5) void {
|
||||
set.* |= u32(1) << (signo - 1);
|
||||
}
|
||||
|
||||
pub extern "c" fn sigaltstack(ss: ?*stack_t, old_ss: ?*stack_t) c_int;
|
||||
|
|
|
@ -1,4 +1,8 @@
|
|||
const std = @import("../std.zig");
|
||||
use std.c;
|
||||
|
||||
extern "c" fn __error() *c_int;
|
||||
pub const _errno = __error;
|
||||
|
||||
pub extern "c" fn getdents(fd: c_int, buf_ptr: [*]u8, nbytes: usize) usize;
|
||||
pub extern "c" fn sigaltstack(ss: ?*stack_t, old_ss: ?*stack_t) c_int;
|
||||
|
|
|
@ -25,3 +25,5 @@ pub extern "c" fn getauxval(__type: c_ulong) c_ulong;
|
|||
|
||||
pub const dl_iterate_phdr_callback = extern fn (info: *dl_phdr_info, size: usize, data: ?*c_void) c_int;
|
||||
pub extern "c" fn dl_iterate_phdr(callback: dl_iterate_phdr_callback, data: ?*c_void) c_int;
|
||||
|
||||
pub extern "c" fn sigaltstack(ss: ?*stack_t, old_ss: ?*stack_t) c_int;
|
||||
|
|
|
@ -1,4 +1,8 @@
|
|||
const std = @import("../std.zig");
|
||||
use std.c;
|
||||
|
||||
extern "c" fn __errno() *c_int;
|
||||
pub const _errno = __errno;
|
||||
|
||||
pub extern "c" fn getdents(fd: c_int, buf_ptr: [*]u8, nbytes: usize) usize;
|
||||
pub extern "c" fn sigaltstack(ss: ?*stack_t, old_ss: ?*stack_t) c_int;
|
||||
|
|
23
std/os.zig
23
std/os.zig
|
@ -2442,6 +2442,29 @@ pub fn unexpectedErrno(err: usize) UnexpectedError {
|
|||
return error.Unexpected;
|
||||
}
|
||||
|
||||
pub const SigaltstackError = error{
|
||||
/// The supplied stack size was less than MINSIGSTKSZ.
|
||||
SizeTooSmall,
|
||||
|
||||
/// Attempted to change the signal stack while it was active.
|
||||
PermissionDenied,
|
||||
Unexpected,
|
||||
};
|
||||
|
||||
pub fn sigaltstack(ss: ?*stack_t, old_ss: ?*stack_t) SigaltstackError!void {
|
||||
if (windows.is_the_target or uefi.is_the_target or wasi.is_the_target)
|
||||
@compileError("std.os.sigaltstack not available for this target");
|
||||
|
||||
switch (errno(system.sigaltstack(ss, old_ss))) {
|
||||
0 => return,
|
||||
EFAULT => unreachable,
|
||||
EINVAL => unreachable,
|
||||
ENOMEM => return error.SizeTooSmall,
|
||||
EPERM => return error.PermissionDenied,
|
||||
else => |err| return unexpectedErrno(err),
|
||||
}
|
||||
}
|
||||
|
||||
test "" {
|
||||
_ = @import("os/darwin.zig");
|
||||
_ = @import("os/freebsd.zig");
|
||||
|
|
|
@ -1078,3 +1078,15 @@ pub const EQFULL = 106;
|
|||
|
||||
/// Must be equal largest errno
|
||||
pub const ELAST = 106;
|
||||
|
||||
pub const SIGSTKSZ = 131072;
|
||||
pub const MINSIGSTKSZ = 32768;
|
||||
|
||||
pub const SS_ONSTACK = 1;
|
||||
pub const SS_DISABLE = 4;
|
||||
|
||||
pub const stack_t = extern struct {
|
||||
ss_sp: [*]u8,
|
||||
ss_size: isize,
|
||||
ss_flags: i32,
|
||||
};
|
||||
|
|
|
@ -835,3 +835,19 @@ pub const ENOTRECOVERABLE = 95; // State not recoverable
|
|||
pub const EOWNERDEAD = 96; // Previous owner died
|
||||
|
||||
pub const ELAST = 96; // Must be equal largest errno
|
||||
|
||||
pub const MINSIGSTKSZ = switch (builtin.arch) {
|
||||
.i386, .x86_64 => 2048,
|
||||
.arm, .aarch64 => 4096,
|
||||
else => @compileError("MINSIGSTKSZ not defined for this architecture"),
|
||||
};
|
||||
pub const SIGSTKSZ = MINSIGSTKSZ + 32768;
|
||||
|
||||
pub const SS_ONSTACK = 1;
|
||||
pub const SS_DISABLE = 4;
|
||||
|
||||
pub const stack_t = extern struct {
|
||||
ss_sp: [*]u8,
|
||||
ss_size: isize,
|
||||
ss_flags: i32,
|
||||
};
|
||||
|
|
|
@ -929,3 +929,24 @@ pub fn CPU_COUNT(set: cpu_set_t) cpu_count_t {
|
|||
//#define CPU_COUNT(set) CPU_COUNT_S(sizeof(cpu_set_t),set)
|
||||
//#define CPU_ZERO(set) CPU_ZERO_S(sizeof(cpu_set_t),set)
|
||||
//#define CPU_EQUAL(s1,s2) CPU_EQUAL_S(sizeof(cpu_set_t),s1,s2)
|
||||
|
||||
pub const MINSIGSTKSZ = switch (builtin.arch) {
|
||||
.i386, .x86_64, .arm => 2048,
|
||||
.aarch64 => 5120,
|
||||
else => @compileError("MINSIGSTKSZ not defined for this architecture"),
|
||||
};
|
||||
pub const SIGSTKSZ = switch (builtin.arch) {
|
||||
.i386, .x86_64, .arm => 8192,
|
||||
.aarch64 => 16384,
|
||||
else => @compileError("SIGSTKSZ not defined for this architecture"),
|
||||
};
|
||||
|
||||
pub const SS_ONSTACK = 1;
|
||||
pub const SS_DISABLE = 2;
|
||||
pub const SS_AUTODISARM = 1 << 31;
|
||||
|
||||
pub const stack_t = extern struct {
|
||||
ss_sp: [*]u8,
|
||||
ss_flags: i32,
|
||||
ss_size: isize,
|
||||
};
|
||||
|
|
|
@ -723,3 +723,15 @@ pub const ENOLINK = 95; // Link has been severed
|
|||
pub const EPROTO = 96; // Protocol error
|
||||
|
||||
pub const ELAST = 96; // Must equal largest errno
|
||||
|
||||
pub const MINSIGSTKSZ = 8192;
|
||||
pub const SIGSTKSZ = MINSIGSTKSZ + 32768;
|
||||
|
||||
pub const SS_ONSTACK = 1;
|
||||
pub const SS_DISABLE = 4;
|
||||
|
||||
pub const stack_t = extern struct {
|
||||
ss_sp: [*]u8,
|
||||
ss_size: isize,
|
||||
ss_flags: i32,
|
||||
};
|
||||
|
|
|
@ -818,6 +818,10 @@ pub fn capset(hdrp: *cap_user_header_t, datap: *const cap_user_data_t) usize {
|
|||
return syscall2(SYS_capset, @ptrToInt(hdrp), @ptrToInt(datap));
|
||||
}
|
||||
|
||||
pub fn sigaltstack(ss: ?*stack_t, old_ss: ?*stack_t) usize {
|
||||
return syscall2(SYS_sigaltstack, @ptrToInt(ss), @ptrToInt(old_ss));
|
||||
}
|
||||
|
||||
// XXX: This should be weak
|
||||
extern const __ehdr_start: elf.Ehdr = undefined;
|
||||
|
||||
|
|
|
@ -149,3 +149,14 @@ test "realpath" {
|
|||
var buf: [std.fs.MAX_PATH_BYTES]u8 = undefined;
|
||||
testing.expectError(error.FileNotFound, fs.realpath("definitely_bogus_does_not_exist1234", &buf));
|
||||
}
|
||||
|
||||
test "sigaltstack" {
|
||||
if (builtin.os == .windows or builtin.os == .wasi) return error.SkipZigTest;
|
||||
|
||||
var st: os.stack_t = undefined;
|
||||
try os.sigaltstack(null, &st);
|
||||
// Setting a stack size less than MINSIGSTKSZ returns ENOMEM
|
||||
st.ss_flags = 0;
|
||||
st.ss_size = 1;
|
||||
testing.expectError(error.SizeTooSmall, os.sigaltstack(&st, null));
|
||||
}
|
||||
|
|
|
@ -1,2 +1,6 @@
|
|||
// TODO this is where the extern declarations go. For example, see
|
||||
// inc/efilib.h in gnu-efi-code
|
||||
|
||||
const builtin = @import("builtin");
|
||||
|
||||
pub const is_the_target = builtin.os == .uefi;
|
||||
|
|
Loading…
Reference in New Issue
Block a user