Merge pull request #3968 from daurnimator/sigprocmask

Clean up linux sigprocmask, raise
This commit is contained in:
Andrew Kelley 2019-12-29 18:03:09 -05:00 committed by GitHub
commit 6b960331ee
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
4 changed files with 33 additions and 37 deletions

View File

@ -101,7 +101,7 @@ pub extern "c" fn dup(fd: fd_t) c_int;
pub extern "c" fn dup2(old_fd: fd_t, new_fd: fd_t) c_int;
pub extern "c" fn readlink(noalias path: [*:0]const u8, noalias buf: [*]u8, bufsize: usize) isize;
pub extern "c" fn realpath(noalias file_name: [*:0]const u8, noalias resolved_name: [*]u8) ?[*:0]u8;
pub extern "c" fn sigprocmask(how: c_int, noalias set: *const sigset_t, noalias oset: ?*sigset_t) c_int;
pub extern "c" fn sigprocmask(how: c_int, noalias set: ?*const sigset_t, noalias oset: ?*sigset_t) c_int;
pub extern "c" fn gettimeofday(noalias tv: ?*timeval, noalias tz: ?*timezone) c_int;
pub extern "c" fn sigaction(sig: c_int, noalias act: *const Sigaction, noalias oact: ?*Sigaction) c_int;
pub extern "c" fn nanosleep(rqtp: *const timespec, rmtp: ?*timespec) c_int;

View File

@ -225,10 +225,15 @@ pub fn raise(sig: u8) RaiseError!void {
if (builtin.os == .linux) {
var set: linux.sigset_t = undefined;
linux.blockAppSignals(&set);
const tid = linux.syscall0(linux.SYS_gettid);
const rc = linux.syscall2(linux.SYS_tkill, tid, sig);
linux.restoreSignals(&set);
// block application signals
_ = linux.sigprocmask(SIG_BLOCK, &linux.app_mask, &set);
const tid = linux.gettid();
const rc = linux.tkill(tid, sig);
// restore signal mask
_ = linux.sigprocmask(SIG_SETMASK, &set, null);
switch (errno(rc)) {
0 => return,
else => |err| return unexpectedErrno(err),

View File

@ -764,19 +764,14 @@ pub const winsize = extern struct {
ws_ypixel: u16,
};
/// NSIG is the total number of signals defined.
/// As signal numbers are sequential, NSIG is one greater than the largest defined signal number.
pub const NSIG = if (is_mips) 128 else 65;
pub const sigset_t = [128 / @sizeOf(usize)]usize;
pub usingnamespace if (NSIG == 65)
struct {
pub const all_mask = [2]u32{ 0xffffffff, 0xffffffff };
pub const app_mask = [2]u32{ 0xfffffffc, 0x7fffffff };
}
else
struct {
pub const all_mask = [4]u32{ 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff };
pub const app_mask = [4]u32{ 0xfffffffc, 0x7fffffff, 0xffffffff, 0xffffffff };
};
pub const sigset_t = [1024 / 32]u32;
pub const all_mask: sigset_t = [_]u32{0xffffffff} ** sigset_t.len;
pub const app_mask: sigset_t = [2]u32{ 0xfffffffc, 0x7fffffff } ++ [_]u32{0xffffffff} ** 30;
pub const k_sigaction = if (is_mips)
extern struct {
@ -804,7 +799,7 @@ pub const Sigaction = extern struct {
pub const SIG_ERR = @intToPtr(extern fn (i32, *siginfo_t, *c_void) void, maxInt(usize));
pub const SIG_DFL = @intToPtr(?extern fn (i32, *siginfo_t, *c_void) void, 0);
pub const SIG_IGN = @intToPtr(extern fn (i32, *siginfo_t, *c_void) void, 1);
pub const empty_sigset = [_]usize{0} ** sigset_t.len;
pub const empty_sigset = [_]u32{0} ** sigset_t.len;
pub const in_port_t = u16;
pub const sa_family_t = u16;

View File

@ -464,10 +464,18 @@ pub fn getrandom(buf: [*]u8, count: usize, flags: u32) usize {
return syscall3(SYS_getrandom, @ptrToInt(buf), count, flags);
}
pub fn kill(pid: i32, sig: i32) usize {
pub fn kill(pid: pid_t, sig: i32) usize {
return syscall2(SYS_kill, @bitCast(usize, @as(isize, pid)), @bitCast(usize, @as(isize, sig)));
}
pub fn tkill(tid: pid_t, sig: i32) usize {
return syscall2(SYS_tkill, @bitCast(usize, @as(isize, tid)), @bitCast(usize, @as(isize, sig)));
}
pub fn tgkill(tgid: pid_t, tid: pid_t, sig: i32) usize {
return syscall2(SYS_tgkill, @bitCast(usize, @as(isize, tgid)), @bitCast(usize, @as(isize, tid)), @bitCast(usize, @as(isize, sig)));
}
pub fn unlink(path: [*:0]const u8) usize {
if (@hasDecl(@This(), "SYS_unlink")) {
return syscall1(SYS_unlink, @ptrToInt(path));
@ -480,7 +488,7 @@ pub fn unlinkat(dirfd: i32, path: [*:0]const u8, flags: u32) usize {
return syscall3(SYS_unlinkat, @bitCast(usize, @as(isize, dirfd)), @ptrToInt(path), flags);
}
pub fn waitpid(pid: i32, status: *u32, flags: u32) usize {
pub fn waitpid(pid: pid_t, status: *u32, flags: u32) usize {
return syscall4(SYS_wait4, @bitCast(usize, @as(isize, pid)), @ptrToInt(status), flags, 0);
}
@ -657,15 +665,15 @@ pub fn setgroups(size: usize, list: *const u32) usize {
}
}
pub fn getpid() i32 {
return @bitCast(i32, @truncate(u32, syscall0(SYS_getpid)));
pub fn getpid() pid_t {
return @bitCast(pid_t, @truncate(u32, syscall0(SYS_getpid)));
}
pub fn gettid() i32 {
return @bitCast(i32, @truncate(u32, syscall0(SYS_gettid)));
pub fn gettid() pid_t {
return @bitCast(pid_t, @truncate(u32, syscall0(SYS_gettid)));
}
pub fn sigprocmask(flags: u32, noalias set: *const sigset_t, noalias oldset: ?*sigset_t) usize {
pub fn sigprocmask(flags: u32, noalias set: ?*const sigset_t, noalias oldset: ?*sigset_t) usize {
return syscall4(SYS_rt_sigprocmask, flags, @ptrToInt(set), @ptrToInt(oldset), NSIG / 8);
}
@ -697,18 +705,6 @@ pub fn sigaction(sig: u6, noalias act: *const Sigaction, noalias oact: ?*Sigacti
return 0;
}
pub fn blockAllSignals(set: *sigset_t) void {
_ = syscall4(SYS_rt_sigprocmask, SIG_BLOCK, @ptrToInt(&all_mask), @ptrToInt(set), NSIG / 8);
}
pub fn blockAppSignals(set: *sigset_t) void {
_ = syscall4(SYS_rt_sigprocmask, SIG_BLOCK, @ptrToInt(&app_mask), @ptrToInt(set), NSIG / 8);
}
pub fn restoreSignals(set: *sigset_t) void {
_ = syscall4(SYS_rt_sigprocmask, SIG_SETMASK, @ptrToInt(set), 0, NSIG / 8);
}
pub fn sigaddset(set: *sigset_t, sig: u6) void {
const s = sig - 1;
(set.*)[@intCast(usize, s) / usize.bit_count] |= @intCast(usize, 1) << (s & (usize.bit_count - 1));
@ -969,7 +965,7 @@ pub fn sched_yield() usize {
return syscall0(SYS_sched_yield);
}
pub fn sched_getaffinity(pid: i32, size: usize, set: *cpu_set_t) usize {
pub fn sched_getaffinity(pid: pid_t, size: usize, set: *cpu_set_t) usize {
const rc = syscall3(SYS_sched_getaffinity, @bitCast(usize, @as(isize, pid)), size, @ptrToInt(set));
if (@bitCast(isize, rc) < 0) return rc;
if (rc < size) @memset(@ptrCast([*]u8, set) + rc, 0, size - rc);