| author | |
| committer | |
| log | 91e8be385cdcc53bb8703f317e6f1f7fd4239e4f |
| tree | 15ea052a2567d9eb9acd8bc3c778bacc9522830f |
| parent | a471a57560401c5562c4dc3e588227b689bf9487 |
| parent | d9e9390550e8290c1959ad2a8940e94d56f3ae1e |
| signature |
std: Improve sigaction interface11 files changed, 219 insertions(+), 72 deletions(-)
lib/std/c.zig+3-3| ... | @@ -200,7 +200,7 @@ pub usingnamespace switch (builtin.os.tag) { | ... | @@ -200,7 +200,7 @@ pub usingnamespace switch (builtin.os.tag) { |
| 200 | pub extern "c" fn gettimeofday(noalias tv: ?*timeval, noalias tz: ?*timezone) c_int; | 200 | pub extern "c" fn gettimeofday(noalias tv: ?*timeval, noalias tz: ?*timezone) c_int; |
| 201 | pub extern "c" fn nanosleep(rqtp: *const timespec, rmtp: ?*timespec) c_int; | 201 | pub extern "c" fn nanosleep(rqtp: *const timespec, rmtp: ?*timespec) c_int; |
| 202 | pub extern "c" fn sched_yield() c_int; | 202 | pub extern "c" fn sched_yield() c_int; |
| 203 | pub extern "c" fn sigaction(sig: c_int, noalias act: *const Sigaction, noalias oact: ?*Sigaction) c_int; | 203 | pub extern "c" fn sigaction(sig: c_int, noalias act: ?*const Sigaction, noalias oact: ?*Sigaction) c_int; |
| 204 | pub extern "c" fn sigprocmask(how: c_int, noalias set: ?*const sigset_t, noalias oset: ?*sigset_t) c_int; | 204 | pub extern "c" fn sigprocmask(how: c_int, noalias set: ?*const sigset_t, noalias oset: ?*sigset_t) c_int; |
| 205 | pub extern "c" fn socket(domain: c_uint, sock_type: c_uint, protocol: c_uint) c_int; | 205 | pub extern "c" fn socket(domain: c_uint, sock_type: c_uint, protocol: c_uint) c_int; |
| 206 | pub extern "c" fn stat(noalias path: [*:0]const u8, noalias buf: *libc_stat) c_int; | 206 | pub extern "c" fn stat(noalias path: [*:0]const u8, noalias buf: *libc_stat) c_int; |
| ... | @@ -215,7 +215,7 @@ pub usingnamespace switch (builtin.os.tag) { | ... | @@ -215,7 +215,7 @@ pub usingnamespace switch (builtin.os.tag) { |
| 215 | pub extern "c" fn gettimeofday(noalias tv: ?*timeval, noalias tz: ?*timezone) c_int; | 215 | pub extern "c" fn gettimeofday(noalias tv: ?*timeval, noalias tz: ?*timezone) c_int; |
| 216 | pub extern "c" fn nanosleep(rqtp: *const timespec, rmtp: ?*timespec) c_int; | 216 | pub extern "c" fn nanosleep(rqtp: *const timespec, rmtp: ?*timespec) c_int; |
| 217 | pub extern "c" fn sched_yield() c_int; | 217 | pub extern "c" fn sched_yield() c_int; |
| 218 | pub extern "c" fn sigaction(sig: c_int, noalias act: *const Sigaction, noalias oact: ?*Sigaction) c_int; | 218 | pub extern "c" fn sigaction(sig: c_int, noalias act: ?*const Sigaction, noalias oact: ?*Sigaction) c_int; |
| 219 | pub extern "c" fn sigprocmask(how: c_int, noalias set: ?*const sigset_t, noalias oset: ?*sigset_t) c_int; | 219 | pub extern "c" fn sigprocmask(how: c_int, noalias set: ?*const sigset_t, noalias oset: ?*sigset_t) c_int; |
| 220 | pub extern "c" fn stat(noalias path: [*:0]const u8, noalias buf: *libc_stat) c_int; | 220 | pub extern "c" fn stat(noalias path: [*:0]const u8, noalias buf: *libc_stat) c_int; |
| 221 | }, | 221 | }, |
| ... | @@ -227,7 +227,7 @@ pub usingnamespace switch (builtin.os.tag) { | ... | @@ -227,7 +227,7 @@ pub usingnamespace switch (builtin.os.tag) { |
| 227 | pub extern "c" fn gettimeofday(noalias tv: ?*timeval, noalias tz: ?*timezone) c_int; | 227 | pub extern "c" fn gettimeofday(noalias tv: ?*timeval, noalias tz: ?*timezone) c_int; |
| 228 | pub extern "c" fn nanosleep(rqtp: *const timespec, rmtp: ?*timespec) c_int; | 228 | pub extern "c" fn nanosleep(rqtp: *const timespec, rmtp: ?*timespec) c_int; |
| 229 | pub extern "c" fn sched_yield() c_int; | 229 | pub extern "c" fn sched_yield() c_int; |
| 230 | pub extern "c" fn sigaction(sig: c_int, noalias act: *const Sigaction, noalias oact: ?*Sigaction) c_int; | 230 | pub extern "c" fn sigaction(sig: c_int, noalias act: ?*const Sigaction, noalias oact: ?*Sigaction) c_int; |
| 231 | pub extern "c" fn sigprocmask(how: c_int, noalias set: ?*const sigset_t, noalias oset: ?*sigset_t) c_int; | 231 | pub extern "c" fn sigprocmask(how: c_int, noalias set: ?*const sigset_t, noalias oset: ?*sigset_t) c_int; |
| 232 | pub extern "c" fn socket(domain: c_uint, sock_type: c_uint, protocol: c_uint) c_int; | 232 | pub extern "c" fn socket(domain: c_uint, sock_type: c_uint, protocol: c_uint) c_int; |
| 233 | pub extern "c" fn stat(noalias path: [*:0]const u8, noalias buf: *libc_stat) c_int; | 233 | pub extern "c" fn stat(noalias path: [*:0]const u8, noalias buf: *libc_stat) c_int; |
lib/std/debug.zig+2-2| ... | @@ -1721,7 +1721,7 @@ pub fn attachSegfaultHandler() void { | ... | @@ -1721,7 +1721,7 @@ pub fn attachSegfaultHandler() void { |
| 1721 | return; | 1721 | return; |
| 1722 | } | 1722 | } |
| 1723 | var act = os.Sigaction{ | 1723 | var act = os.Sigaction{ |
| 1724 | .sigaction = handleSegfaultLinux, | 1724 | .handler = .{ .sigaction = handleSegfaultLinux }, |
| 1725 | .mask = os.empty_sigset, | 1725 | .mask = os.empty_sigset, |
| 1726 | .flags = (os.SA_SIGINFO | os.SA_RESTART | os.SA_RESETHAND), | 1726 | .flags = (os.SA_SIGINFO | os.SA_RESTART | os.SA_RESETHAND), |
| 1727 | }; | 1727 | }; |
| ... | @@ -1740,7 +1740,7 @@ fn resetSegfaultHandler() void { | ... | @@ -1740,7 +1740,7 @@ fn resetSegfaultHandler() void { |
| 1740 | return; | 1740 | return; |
| 1741 | } | 1741 | } |
| 1742 | var act = os.Sigaction{ | 1742 | var act = os.Sigaction{ |
| 1743 | .sigaction = os.SIG_DFL, | 1743 | .handler = .{ .sigaction = os.SIG_DFL }, |
| 1744 | .mask = os.empty_sigset, | 1744 | .mask = os.empty_sigset, |
| 1745 | .flags = 0, | 1745 | .flags = 0, |
| 1746 | }; | 1746 | }; |
lib/std/os.zig+1-1| ... | @@ -4592,7 +4592,7 @@ pub fn sigaltstack(ss: ?*stack_t, old_ss: ?*stack_t) SigaltstackError!void { | ... | @@ -4592,7 +4592,7 @@ pub fn sigaltstack(ss: ?*stack_t, old_ss: ?*stack_t) SigaltstackError!void { |
| 4592 | } | 4592 | } |
| 4593 | 4593 | ||
| 4594 | /// Examine and change a signal action. | 4594 | /// Examine and change a signal action. |
| 4595 | pub fn sigaction(sig: u6, act: *const Sigaction, oact: ?*Sigaction) void { | 4595 | pub fn sigaction(sig: u6, act: ?*const Sigaction, oact: ?*Sigaction) void { |
| 4596 | switch (errno(system.sigaction(sig, act, oact))) { | 4596 | switch (errno(system.sigaction(sig, act, oact))) { |
| 4597 | 0 => return, | 4597 | 0 => return, |
| 4598 | EFAULT => unreachable, | 4598 | EFAULT => unreachable, |
lib/std/os/bits/darwin.zig+31-4| ... | @@ -124,13 +124,40 @@ pub const timespec = extern struct { | ... | @@ -124,13 +124,40 @@ pub const timespec = extern struct { |
| 124 | }; | 124 | }; |
| 125 | 125 | ||
| 126 | pub const sigset_t = u32; | 126 | pub const sigset_t = u32; |
| 127 | pub const empty_sigset = sigset_t(0); | 127 | pub const empty_sigset: sigset_t = 0; |
| 128 | |||
| 129 | pub const SIG_ERR = @intToPtr(?Sigaction.sigaction_fn, maxInt(usize)); | ||
| 130 | pub const SIG_DFL = @intToPtr(?Sigaction.sigaction_fn, 0); | ||
| 131 | pub const SIG_IGN = @intToPtr(?Sigaction.sigaction_fn, 1); | ||
| 132 | pub const SIG_HOLD = @intToPtr(?Sigaction.sigaction_fn, 5); | ||
| 133 | |||
| 134 | pub const siginfo_t = extern struct { | ||
| 135 | signo: c_int, | ||
| 136 | errno: c_int, | ||
| 137 | code: c_int, | ||
| 138 | pid: pid_t, | ||
| 139 | uid: uid_t, | ||
| 140 | status: c_int, | ||
| 141 | addr: *c_void, | ||
| 142 | value: extern union { | ||
| 143 | int: c_int, | ||
| 144 | ptr: *c_void, | ||
| 145 | }, | ||
| 146 | si_band: c_long, | ||
| 147 | _pad: [7]c_ulong, | ||
| 148 | }; | ||
| 128 | 149 | ||
| 129 | /// Renamed from `sigaction` to `Sigaction` to avoid conflict with function name. | 150 | /// Renamed from `sigaction` to `Sigaction` to avoid conflict with function name. |
| 130 | pub const Sigaction = extern struct { | 151 | pub const Sigaction = extern struct { |
| 131 | handler: fn (c_int) callconv(.C) void, | 152 | pub const handler_fn = fn (c_int) callconv(.C) void; |
| 132 | sa_mask: sigset_t, | 153 | pub const sigaction_fn = fn (c_int, *const siginfo_t, ?*const c_void) callconv(.C) void; |
| 133 | sa_flags: c_int, | 154 | |
| 155 | handler: extern union { | ||
| 156 | handler: ?handler_fn, | ||
| 157 | sigaction: ?sigaction_fn, | ||
| 158 | }, | ||
| 159 | mask: sigset_t, | ||
| 160 | flags: c_uint, | ||
| 134 | }; | 161 | }; |
| 135 | 162 | ||
| 136 | pub const dirent = extern struct { | 163 | pub const dirent = extern struct { |
lib/std/os/bits/dragonfly.zig+9-5| ... | @@ -530,12 +530,16 @@ pub const sigset_t = extern struct { | ... | @@ -530,12 +530,16 @@ pub const sigset_t = extern struct { |
| 530 | }; | 530 | }; |
| 531 | pub const sig_atomic_t = c_int; | 531 | pub const sig_atomic_t = c_int; |
| 532 | pub const Sigaction = extern struct { | 532 | pub const Sigaction = extern struct { |
| 533 | __sigaction_u: extern union { | 533 | pub const handler_fn = fn (c_int) callconv(.C) void; |
| 534 | __sa_handler: ?fn (c_int) callconv(.C) void, | 534 | pub const sigaction_fn = fn (c_int, *const siginfo_t, ?*const c_void) callconv(.C) void; |
| 535 | __sa_sigaction: ?fn (c_int, [*c]siginfo_t, ?*c_void) callconv(.C) void, | 535 | |
| 536 | /// signal handler | ||
| 537 | handler: extern union { | ||
| 538 | handler: ?handler_fn, | ||
| 539 | sigaction: ?sigaction_fn, | ||
| 536 | }, | 540 | }, |
| 537 | sa_flags: c_int, | 541 | flags: c_uint, |
| 538 | sa_mask: sigset_t, | 542 | mask: sigset_t, |
| 539 | }; | 543 | }; |
| 540 | pub const sig_t = [*c]fn (c_int) callconv(.C) void; | 544 | pub const sig_t = [*c]fn (c_int) callconv(.C) void; |
| 541 | 545 |
lib/std/os/bits/freebsd.zig+48-8| ... | @@ -736,23 +736,61 @@ pub const winsize = extern struct { | ... | @@ -736,23 +736,61 @@ pub const winsize = extern struct { |
| 736 | 736 | ||
| 737 | const NSIG = 32; | 737 | const NSIG = 32; |
| 738 | 738 | ||
| 739 | pub const SIG_ERR = @intToPtr(fn (i32) callconv(.C) void, maxInt(usize)); | 739 | pub const SIG_ERR = @intToPtr(?Sigaction.sigaction_fn, maxInt(usize)); |
| 740 | pub const SIG_DFL = @intToPtr(fn (i32) callconv(.C) void, 0); | 740 | pub const SIG_DFL = @intToPtr(?Sigaction.sigaction_fn, 0); |
| 741 | pub const SIG_IGN = @intToPtr(fn (i32) callconv(.C) void, 1); | 741 | pub const SIG_IGN = @intToPtr(?Sigaction.sigaction_fn, 1); |
| 742 | 742 | ||
| 743 | /// Renamed from `sigaction` to `Sigaction` to avoid conflict with the syscall. | 743 | /// Renamed from `sigaction` to `Sigaction` to avoid conflict with the syscall. |
| 744 | pub const Sigaction = extern struct { | 744 | pub const Sigaction = extern struct { |
| 745 | pub const handler_fn = fn (c_int) callconv(.C) void; | ||
| 746 | pub const sigaction_fn = fn (c_int, *const siginfo_t, ?*const c_void) callconv(.C) void; | ||
| 747 | |||
| 745 | /// signal handler | 748 | /// signal handler |
| 746 | __sigaction_u: extern union { | 749 | handler: extern union { |
| 747 | __sa_handler: fn (i32) callconv(.C) void, | 750 | handler: ?handler_fn, |
| 748 | __sa_sigaction: fn (i32, *__siginfo, usize) callconv(.C) void, | 751 | sigaction: ?sigaction_fn, |
| 749 | }, | 752 | }, |
| 750 | 753 | ||
| 751 | /// see signal options | 754 | /// see signal options |
| 752 | sa_flags: u32, | 755 | flags: c_uint, |
| 753 | 756 | ||
| 754 | /// signal mask to apply | 757 | /// signal mask to apply |
| 755 | sa_mask: sigset_t, | 758 | mask: sigset_t, |
| 759 | }; | ||
| 760 | |||
| 761 | pub const siginfo_t = extern struct { | ||
| 762 | signo: c_int, | ||
| 763 | errno: c_int, | ||
| 764 | code: c_int, | ||
| 765 | pid: pid_t, | ||
| 766 | uid: uid_t, | ||
| 767 | status: c_int, | ||
| 768 | addr: ?*c_void, | ||
| 769 | value: sigval, | ||
| 770 | reason: extern union { | ||
| 771 | fault: extern struct { | ||
| 772 | trapno: c_int, | ||
| 773 | }, | ||
| 774 | timer: extern struct { | ||
| 775 | timerid: c_int, | ||
| 776 | overrun: c_int, | ||
| 777 | }, | ||
| 778 | mesgq: extern struct { | ||
| 779 | mqd: c_int, | ||
| 780 | }, | ||
| 781 | poll: extern struct { | ||
| 782 | band: c_long, | ||
| 783 | }, | ||
| 784 | spare: extern struct { | ||
| 785 | spare1: c_long, | ||
| 786 | spare2: [7]c_int, | ||
| 787 | }, | ||
| 788 | }, | ||
| 789 | }; | ||
| 790 | |||
| 791 | pub const sigval = extern union { | ||
| 792 | int: c_int, | ||
| 793 | ptr: ?*c_void, | ||
| 756 | }; | 794 | }; |
| 757 | 795 | ||
| 758 | pub const _SIG_WORDS = 4; | 796 | pub const _SIG_WORDS = 4; |
| ... | @@ -775,6 +813,8 @@ pub const sigset_t = extern struct { | ... | @@ -775,6 +813,8 @@ pub const sigset_t = extern struct { |
| 775 | __bits: [_SIG_WORDS]u32, | 813 | __bits: [_SIG_WORDS]u32, |
| 776 | }; | 814 | }; |
| 777 | 815 | ||
| 816 | pub const empty_sigset = sigset_t{ .__bits = [_]u32{0} ** _SIG_WORDS }; | ||
| 817 | |||
| 778 | pub const EPERM = 1; // Operation not permitted | 818 | pub const EPERM = 1; // Operation not permitted |
| 779 | pub const ENOENT = 2; // No such file or directory | 819 | pub const ENOENT = 2; // No such file or directory |
| 780 | pub const ESRCH = 3; // No such process | 820 | pub const ESRCH = 3; // No such process |
lib/std/os/bits/linux.zig+26-15| ... | @@ -864,27 +864,38 @@ pub const sigset_t = [1024 / 32]u32; | ... | @@ -864,27 +864,38 @@ pub const sigset_t = [1024 / 32]u32; |
| 864 | pub const all_mask: sigset_t = [_]u32{0xffffffff} ** sigset_t.len; | 864 | pub const all_mask: sigset_t = [_]u32{0xffffffff} ** sigset_t.len; |
| 865 | pub const app_mask: sigset_t = [2]u32{ 0xfffffffc, 0x7fffffff } ++ [_]u32{0xffffffff} ** 30; | 865 | pub const app_mask: sigset_t = [2]u32{ 0xfffffffc, 0x7fffffff } ++ [_]u32{0xffffffff} ** 30; |
| 866 | 866 | ||
| 867 | pub const k_sigaction = if (is_mips) | 867 | pub const k_sigaction = switch (builtin.arch) { |
| 868 | extern struct { | 868 | .mips, .mipsel => extern struct { |
| 869 | flags: usize, | 869 | flags: c_uint, |
| 870 | sigaction: ?fn (i32, *siginfo_t, ?*c_void) callconv(.C) void, | 870 | handler: ?fn (c_int) callconv(.C) void, |
| 871 | mask: [4]u32, | 871 | mask: [4]c_ulong, |
| 872 | restorer: fn () callconv(.C) void, | 872 | restorer: fn () callconv(.C) void, |
| 873 | } | 873 | }, |
| 874 | else | 874 | .mips64, .mips64el => extern struct { |
| 875 | extern struct { | 875 | flags: c_uint, |
| 876 | sigaction: ?fn (i32, *siginfo_t, ?*c_void) callconv(.C) void, | 876 | handler: ?fn (c_int) callconv(.C) void, |
| 877 | flags: usize, | 877 | mask: [2]c_ulong, |
| 878 | restorer: fn () callconv(.C) void, | 878 | restorer: fn () callconv(.C) void, |
| 879 | mask: [2]u32, | 879 | }, |
| 880 | }; | 880 | else => extern struct { |
| 881 | handler: ?fn (c_int) callconv(.C) void, | ||
| 882 | flags: c_ulong, | ||
| 883 | restorer: fn () callconv(.C) void, | ||
| 884 | mask: [2]c_uint, | ||
| 885 | }, | ||
| 886 | }; | ||
| 881 | 887 | ||
| 882 | /// Renamed from `sigaction` to `Sigaction` to avoid conflict with the syscall. | 888 | /// Renamed from `sigaction` to `Sigaction` to avoid conflict with the syscall. |
| 883 | pub const Sigaction = extern struct { | 889 | pub const Sigaction = extern struct { |
| 884 | pub const sigaction_fn = fn (i32, *siginfo_t, ?*c_void) callconv(.C) void; | 890 | pub const handler_fn = fn (c_int) callconv(.C) void; |
| 885 | sigaction: ?sigaction_fn, | 891 | pub const sigaction_fn = fn (c_int, *const siginfo_t, ?*const c_void) callconv(.C) void; |
| 892 | |||
| 893 | handler: extern union { | ||
| 894 | handler: ?handler_fn, | ||
| 895 | sigaction: ?sigaction_fn, | ||
| 896 | }, | ||
| 886 | mask: sigset_t, | 897 | mask: sigset_t, |
| 887 | flags: u32, | 898 | flags: c_uint, |
| 888 | restorer: ?fn () callconv(.C) void = null, | 899 | restorer: ?fn () callconv(.C) void = null, |
| 889 | }; | 900 | }; |
| 890 | 901 |
lib/std/os/bits/netbsd.zig+12-3| ... | @@ -716,13 +716,18 @@ pub const SIG_IGN = @intToPtr(?Sigaction.sigaction_fn, 1); | ... | @@ -716,13 +716,18 @@ pub const SIG_IGN = @intToPtr(?Sigaction.sigaction_fn, 1); |
| 716 | 716 | ||
| 717 | /// Renamed from `sigaction` to `Sigaction` to avoid conflict with the syscall. | 717 | /// Renamed from `sigaction` to `Sigaction` to avoid conflict with the syscall. |
| 718 | pub const Sigaction = extern struct { | 718 | pub const Sigaction = extern struct { |
| 719 | pub const sigaction_fn = fn (i32, *siginfo_t, ?*c_void) callconv(.C) void; | 719 | pub const handler_fn = fn (c_int) callconv(.C) void; |
| 720 | pub const sigaction_fn = fn (c_int, *const siginfo_t, ?*const c_void) callconv(.C) void; | ||
| 721 | |||
| 720 | /// signal handler | 722 | /// signal handler |
| 721 | sigaction: ?sigaction_fn, | 723 | handler: extern union { |
| 724 | handler: ?handler_fn, | ||
| 725 | sigaction: ?sigaction_fn, | ||
| 726 | }, | ||
| 722 | /// signal mask to apply | 727 | /// signal mask to apply |
| 723 | mask: sigset_t, | 728 | mask: sigset_t, |
| 724 | /// signal options | 729 | /// signal options |
| 725 | flags: u32, | 730 | flags: c_uint, |
| 726 | }; | 731 | }; |
| 727 | 732 | ||
| 728 | pub const sigval_t = extern union { | 733 | pub const sigval_t = extern union { |
| ... | @@ -800,6 +805,10 @@ pub const sigset_t = extern struct { | ... | @@ -800,6 +805,10 @@ pub const sigset_t = extern struct { |
| 800 | __bits: [_SIG_WORDS]u32, | 805 | __bits: [_SIG_WORDS]u32, |
| 801 | }; | 806 | }; |
| 802 | 807 | ||
| 808 | pub const SIG_ERR = @intToPtr(?Sigaction.sigaction_fn, maxInt(usize)); | ||
| 809 | pub const SIG_DFL = @intToPtr(?Sigaction.sigaction_fn, 0); | ||
| 810 | pub const SIG_IGN = @intToPtr(?Sigaction.sigaction_fn, 1); | ||
| 811 | |||
| 803 | pub const empty_sigset = sigset_t{ .__bits = [_]u32{0} ** _SIG_WORDS }; | 812 | pub const empty_sigset = sigset_t{ .__bits = [_]u32{0} ** _SIG_WORDS }; |
| 804 | 813 | ||
| 805 | // XXX x86_64 specific | 814 | // XXX x86_64 specific |
lib/std/os/bits/openbsd.zig+22-11| ... | @@ -750,16 +750,23 @@ const NSIG = 33; | ... | @@ -750,16 +750,23 @@ const NSIG = 33; |
| 750 | pub const SIG_ERR = @intToPtr(?Sigaction.sigaction_fn, maxInt(usize)); | 750 | pub const SIG_ERR = @intToPtr(?Sigaction.sigaction_fn, maxInt(usize)); |
| 751 | pub const SIG_DFL = @intToPtr(?Sigaction.sigaction_fn, 0); | 751 | pub const SIG_DFL = @intToPtr(?Sigaction.sigaction_fn, 0); |
| 752 | pub const SIG_IGN = @intToPtr(?Sigaction.sigaction_fn, 1); | 752 | pub const SIG_IGN = @intToPtr(?Sigaction.sigaction_fn, 1); |
| 753 | pub const SIG_CATCH = @intToPtr(?Sigaction.sigaction_fn, 2); | ||
| 754 | pub const SIG_HOLD = @intToPtr(?Sigaction.sigaction_fn, 3); | ||
| 753 | 755 | ||
| 754 | /// Renamed from `sigaction` to `Sigaction` to avoid conflict with the syscall. | 756 | /// Renamed from `sigaction` to `Sigaction` to avoid conflict with the syscall. |
| 755 | pub const Sigaction = extern struct { | 757 | pub const Sigaction = extern struct { |
| 756 | pub const sigaction_fn = fn (c_int, *siginfo_t, ?*c_void) callconv(.C) void; | 758 | pub const handler_fn = fn (c_int) callconv(.C) void; |
| 759 | pub const sigaction_fn = fn (c_int, *const siginfo_t, ?*const c_void) callconv(.C) void; | ||
| 760 | |||
| 757 | /// signal handler | 761 | /// signal handler |
| 758 | sigaction: ?sigaction_fn, | 762 | handler: extern union { |
| 763 | handler: ?handler_fn, | ||
| 764 | sigaction: ?sigaction_fn, | ||
| 765 | }, | ||
| 759 | /// signal mask to apply | 766 | /// signal mask to apply |
| 760 | mask: sigset_t, | 767 | mask: sigset_t, |
| 761 | /// signal options | 768 | /// signal options |
| 762 | flags: c_int, | 769 | flags: c_uint, |
| 763 | }; | 770 | }; |
| 764 | 771 | ||
| 765 | pub const sigval = extern union { | 772 | pub const sigval = extern union { |
| ... | @@ -767,12 +774,7 @@ pub const sigval = extern union { | ... | @@ -767,12 +774,7 @@ pub const sigval = extern union { |
| 767 | ptr: ?*c_void, | 774 | ptr: ?*c_void, |
| 768 | }; | 775 | }; |
| 769 | 776 | ||
| 770 | pub const siginfo_t = extern union { | 777 | pub const siginfo_t = extern struct { |
| 771 | pad: [128]u8, | ||
| 772 | info: _ksiginfo, | ||
| 773 | }; | ||
| 774 | |||
| 775 | pub const _ksiginfo = extern struct { | ||
| 776 | signo: c_int, | 778 | signo: c_int, |
| 777 | code: c_int, | 779 | code: c_int, |
| 778 | errno: c_int, | 780 | errno: c_int, |
| ... | @@ -789,11 +791,20 @@ pub const _ksiginfo = extern struct { | ... | @@ -789,11 +791,20 @@ pub const _ksiginfo = extern struct { |
| 789 | addr: ?*c_void, | 791 | addr: ?*c_void, |
| 790 | trapno: c_int, | 792 | trapno: c_int, |
| 791 | }, | 793 | }, |
| 792 | } align(@sizeOf(usize)), | 794 | __pad: [128 - 3 * @sizeOf(c_int)]u8, |
| 795 | }, | ||
| 793 | }; | 796 | }; |
| 794 | 797 | ||
| 798 | comptime { | ||
| 799 | if (@sizeOf(usize) == 4) | ||
| 800 | std.debug.assert(@sizeOf(siginfo_t) == 128) | ||
| 801 | else | ||
| 802 | // Take into account the padding between errno and data fields. | ||
| 803 | std.debug.assert(@sizeOf(siginfo_t) == 136); | ||
| 804 | } | ||
| 805 | |||
| 795 | pub const sigset_t = c_uint; | 806 | pub const sigset_t = c_uint; |
| 796 | pub const empty_sigset = sigset_t(0); | 807 | pub const empty_sigset: sigset_t = 0; |
| 797 | 808 | ||
| 798 | pub const EPERM = 1; // Operation not permitted | 809 | pub const EPERM = 1; // Operation not permitted |
| 799 | pub const ENOENT = 2; // No such file or directory | 810 | pub const ENOENT = 2; // No such file or directory |
lib/std/os/linux.zig+27-20| ... | @@ -857,35 +857,42 @@ pub fn sigprocmask(flags: u32, noalias set: ?*const sigset_t, noalias oldset: ?* | ... | @@ -857,35 +857,42 @@ pub fn sigprocmask(flags: u32, noalias set: ?*const sigset_t, noalias oldset: ?* |
| 857 | return syscall4(.rt_sigprocmask, flags, @ptrToInt(set), @ptrToInt(oldset), NSIG / 8); | 857 | return syscall4(.rt_sigprocmask, flags, @ptrToInt(set), @ptrToInt(oldset), NSIG / 8); |
| 858 | } | 858 | } |
| 859 | 859 | ||
| 860 | pub fn sigaction(sig: u6, noalias act: *const Sigaction, noalias oact: ?*Sigaction) usize { | 860 | pub fn sigaction(sig: u6, noalias act: ?*const Sigaction, noalias oact: ?*Sigaction) usize { |
| 861 | assert(sig >= 1); | 861 | assert(sig >= 1); |
| 862 | assert(sig != SIGKILL); | 862 | assert(sig != SIGKILL); |
| 863 | assert(sig != SIGSTOP); | 863 | assert(sig != SIGSTOP); |
| 864 | 864 | ||
| 865 | const restorer_fn = if ((act.flags & SA_SIGINFO) != 0) restore_rt else restore; | 865 | var ksa: k_sigaction = undefined; |
| 866 | var ksa = k_sigaction{ | 866 | var oldksa: k_sigaction = undefined; |
| 867 | .sigaction = act.sigaction, | 867 | const mask_size = @sizeOf(@TypeOf(ksa.mask)); |
| 868 | .flags = act.flags | SA_RESTORER, | 868 | |
| 869 | .mask = undefined, | 869 | if (act) |new| { |
| 870 | .restorer = @ptrCast(fn () callconv(.C) void, restorer_fn), | 870 | const restorer_fn = if ((new.flags & SA_SIGINFO) != 0) restore_rt else restore; |
| 871 | }; | 871 | ksa = k_sigaction{ |
| 872 | var ksa_old: k_sigaction = undefined; | 872 | .handler = new.handler.handler, |
| 873 | const ksa_mask_size = @sizeOf(@TypeOf(ksa_old.mask)); | 873 | .flags = new.flags | SA_RESTORER, |
| 874 | @memcpy(@ptrCast([*]u8, &ksa.mask), @ptrCast([*]const u8, &act.mask), ksa_mask_size); | 874 | .mask = undefined, |
| 875 | .restorer = @ptrCast(fn () callconv(.C) void, restorer_fn), | ||
| 876 | }; | ||
| 877 | @memcpy(@ptrCast([*]u8, &ksa.mask), @ptrCast([*]const u8, &new.mask), mask_size); | ||
| 878 | } | ||
| 879 | |||
| 880 | const ksa_arg = if (act != null) @ptrToInt(&ksa) else 0; | ||
| 881 | const oldksa_arg = if (oact != null) @ptrToInt(&oldksa) else 0; | ||
| 882 | |||
| 875 | const result = switch (builtin.arch) { | 883 | const result = switch (builtin.arch) { |
| 876 | // The sparc version of rt_sigaction needs the restorer function to be passed as an argument too. | 884 | // The sparc version of rt_sigaction needs the restorer function to be passed as an argument too. |
| 877 | .sparc, .sparcv9 => syscall5(.rt_sigaction, sig, @ptrToInt(&ksa), @ptrToInt(&ksa_old), @ptrToInt(ksa.restorer), ksa_mask_size), | 885 | .sparc, .sparcv9 => syscall5(.rt_sigaction, sig, ksa_arg, oldksa_arg, @ptrToInt(ksa.restorer), mask_size), |
| 878 | else => syscall4(.rt_sigaction, sig, @ptrToInt(&ksa), @ptrToInt(&ksa_old), ksa_mask_size), | 886 | else => syscall4(.rt_sigaction, sig, ksa_arg, oldksa_arg, mask_size), |
| 879 | }; | 887 | }; |
| 880 | const err = getErrno(result); | 888 | if (getErrno(result) != 0) return result; |
| 881 | if (err != 0) { | 889 | |
| 882 | return result; | ||
| 883 | } | ||
| 884 | if (oact) |old| { | 890 | if (oact) |old| { |
| 885 | old.sigaction = ksa_old.sigaction; | 891 | old.handler.handler = oldksa.handler; |
| 886 | old.flags = @truncate(u32, ksa_old.flags); | 892 | old.flags = @truncate(c_uint, oldksa.flags); |
| 887 | @memcpy(@ptrCast([*]u8, &old.mask), @ptrCast([*]const u8, &ksa_old.mask), ksa_mask_size); | 893 | @memcpy(@ptrCast([*]u8, &old.mask), @ptrCast([*]const u8, &oldksa.mask), mask_size); |
| 888 | } | 894 | } |
| 895 | |||
| 889 | return 0; | 896 | return 0; |
| 890 | } | 897 | } |
| 891 | 898 |
lib/std/os/test.zig+38| ... | @@ -646,3 +646,41 @@ test "shutdown socket" { | ... | @@ -646,3 +646,41 @@ test "shutdown socket" { |
| 646 | }; | 646 | }; |
| 647 | os.closeSocket(sock); | 647 | os.closeSocket(sock); |
| 648 | } | 648 | } |
| 649 | |||
| 650 | var signal_test_failed = true; | ||
| 651 | |||
| 652 | test "sigaction" { | ||
| 653 | if (builtin.os.tag == .wasi or builtin.os.tag == .windows) | ||
| 654 | return error.SkipZigTest; | ||
| 655 | |||
| 656 | // https://github.com/ziglang/zig/issues/7427 | ||
| 657 | if (builtin.os.tag == .linux and builtin.arch == .i386) | ||
| 658 | return error.SkipZigTest; | ||
| 659 | |||
| 660 | const S = struct { | ||
| 661 | fn handler(sig: i32, info: *const os.siginfo_t, ctx_ptr: ?*const c_void) callconv(.C) void { | ||
| 662 | // Check that we received the correct signal. | ||
| 663 | if (sig == os.SIGUSR1 and sig == info.signo) | ||
| 664 | signal_test_failed = false; | ||
| 665 | } | ||
| 666 | }; | ||
| 667 | |||
| 668 | var sa = os.Sigaction{ | ||
| 669 | .handler = .{ .sigaction = S.handler }, | ||
| 670 | .mask = os.empty_sigset, | ||
| 671 | .flags = os.SA_SIGINFO | os.SA_RESETHAND, | ||
| 672 | }; | ||
| 673 | var old_sa: os.Sigaction = undefined; | ||
| 674 | // Install the new signal handler. | ||
| 675 | os.sigaction(os.SIGUSR1, &sa, null); | ||
| 676 | // Check that we can read it back correctly. | ||
| 677 | os.sigaction(os.SIGUSR1, null, &old_sa); | ||
| 678 | testing.expectEqual(S.handler, old_sa.handler.sigaction.?); | ||
| 679 | testing.expect((old_sa.flags & os.SA_SIGINFO) != 0); | ||
| 680 | // Invoke the handler. | ||
| 681 | try os.raise(os.SIGUSR1); | ||
| 682 | testing.expect(signal_test_failed == false); | ||
| 683 | // Check if the handler has been correctly reset to SIG_DFL | ||
| 684 | os.sigaction(os.SIGUSR1, null, &old_sa); | ||
| 685 | testing.expectEqual(os.SIG_DFL, old_sa.handler.sigaction); | ||
| 686 | } |