authorgravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2024-07-23 11:49:43-07:00
committergravatar for noreply@github.comGitHub <noreply@github.com> 2024-07-23 11:49:43-07:00
log718f8d531488866ff3623c83e05d8ad9a8f72659
treec75598db53f62ca4f75a11319998536eed5ac0db
parente8503ecb6552087d6954423e59f3dfa8ca4a1b09
parent2cced8903e07066a724a81257dadae233dd5893f
signaturebadge-check Signed by PGP key B5690EEEBB952194

Merge pull request #20706 from alexrp/sigaction-nosys

`std.posix`: Make `sigaction()` infallible

6 files changed, 22 insertions(+), 29 deletions(-)

lib/std/Progress.zig+1-3
...@@ -414,9 +414,7 @@ pub fn start(options: Options) Node {...@@ -414,9 +414,7 @@ pub fn start(options: Options) Node {
414 .mask = posix.empty_sigset,414 .mask = posix.empty_sigset,
415 .flags = (posix.SA.SIGINFO | posix.SA.RESTART),415 .flags = (posix.SA.SIGINFO | posix.SA.RESTART),
416 };416 };
417 posix.sigaction(posix.SIG.WINCH, &act, null) catch |err| {417 posix.sigaction(posix.SIG.WINCH, &act, null);
418 std.log.warn("failed to install SIGWINCH signal handler for noticing terminal resizes: {s}", .{@errorName(err)});
419 };
420 }418 }
421419
422 if (switch (global_progress.terminal_mode) {420 if (switch (global_progress.terminal_mode) {
lib/std/debug.zig+7-10
...@@ -2601,11 +2601,11 @@ pub fn maybeEnableSegfaultHandler() void {...@@ -2601,11 +2601,11 @@ pub fn maybeEnableSegfaultHandler() void {
26012601
2602var windows_segfault_handle: ?windows.HANDLE = null;2602var windows_segfault_handle: ?windows.HANDLE = null;
26032603
2604pub fn updateSegfaultHandler(act: ?*const posix.Sigaction) error{OperationNotSupported}!void {2604pub fn updateSegfaultHandler(act: ?*const posix.Sigaction) void {
2605 try posix.sigaction(posix.SIG.SEGV, act, null);2605 posix.sigaction(posix.SIG.SEGV, act, null);
2606 try posix.sigaction(posix.SIG.ILL, act, null);2606 posix.sigaction(posix.SIG.ILL, act, null);
2607 try posix.sigaction(posix.SIG.BUS, act, null);2607 posix.sigaction(posix.SIG.BUS, act, null);
2608 try posix.sigaction(posix.SIG.FPE, act, null);2608 posix.sigaction(posix.SIG.FPE, act, null);
2609}2609}
26102610
2611/// Attaches a global SIGSEGV handler which calls `@panic("segmentation fault");`2611/// Attaches a global SIGSEGV handler which calls `@panic("segmentation fault");`
...@@ -2623,9 +2623,7 @@ pub fn attachSegfaultHandler() void {...@@ -2623,9 +2623,7 @@ pub fn attachSegfaultHandler() void {
2623 .flags = (posix.SA.SIGINFO | posix.SA.RESTART | posix.SA.RESETHAND),2623 .flags = (posix.SA.SIGINFO | posix.SA.RESTART | posix.SA.RESETHAND),
2624 };2624 };
26252625
2626 updateSegfaultHandler(&act) catch {2626 updateSegfaultHandler(&act);
2627 @panic("unable to install segfault handler, maybe adjust have_segfault_handling_support in std/debug.zig");
2628 };
2629}2627}
26302628
2631fn resetSegfaultHandler() void {2629fn resetSegfaultHandler() void {
...@@ -2641,8 +2639,7 @@ fn resetSegfaultHandler() void {...@@ -2641,8 +2639,7 @@ fn resetSegfaultHandler() void {
2641 .mask = posix.empty_sigset,2639 .mask = posix.empty_sigset,
2642 .flags = 0,2640 .flags = 0,
2643 };2641 };
2644 // To avoid a double-panic, do nothing if an error happens here.2642 updateSegfaultHandler(&act);
2645 updateSegfaultHandler(&act) catch {};
2646}2643}
26472644
2648fn handleSegfaultPosix(sig: i32, info: *const posix.siginfo_t, ctx_ptr: ?*anyopaque) callconv(.C) noreturn {2645fn handleSegfaultPosix(sig: i32, info: *const posix.siginfo_t, ctx_ptr: ?*anyopaque) callconv(.C) noreturn {
lib/std/posix.zig+6-5
...@@ -685,9 +685,7 @@ pub fn abort() noreturn {...@@ -685,9 +685,7 @@ pub fn abort() noreturn {
685 .mask = empty_sigset,685 .mask = empty_sigset,
686 .flags = 0,686 .flags = 0,
687 };687 };
688 sigaction(SIG.ABRT, &sigact, null) catch |err| switch (err) {688 sigaction(SIG.ABRT, &sigact, null);
689 error.OperationNotSupported => unreachable,
690 };
691689
692 _ = linux.tkill(linux.gettid(), SIG.ABRT);690 _ = linux.tkill(linux.gettid(), SIG.ABRT);
693691
...@@ -5678,10 +5676,13 @@ pub fn sigaltstack(ss: ?*stack_t, old_ss: ?*stack_t) SigaltstackError!void {...@@ -5678,10 +5676,13 @@ pub fn sigaltstack(ss: ?*stack_t, old_ss: ?*stack_t) SigaltstackError!void {
5678}5676}
56795677
5680/// Examine and change a signal action.5678/// Examine and change a signal action.
5681pub fn sigaction(sig: u6, noalias act: ?*const Sigaction, noalias oact: ?*Sigaction) error{OperationNotSupported}!void {5679pub fn sigaction(sig: u6, noalias act: ?*const Sigaction, noalias oact: ?*Sigaction) void {
5682 switch (errno(system.sigaction(sig, act, oact))) {5680 switch (errno(system.sigaction(sig, act, oact))) {
5683 .SUCCESS => return,5681 .SUCCESS => return,
5684 .INVAL, .NOSYS => return error.OperationNotSupported,5682 // EINVAL means the signal is either invalid or some signal that cannot have its action
5683 // changed. For POSIX, this means SIGKILL/SIGSTOP. For e.g. Solaris, this also includes the
5684 // non-standard SIGWAITING, SIGCANCEL, and SIGLWP. Either way, programmer error.
5685 .INVAL => unreachable,
5685 else => unreachable,5686 else => unreachable,
5686 }5687 }
5687}5688}
lib/std/posix/test.zig+6-6
...@@ -862,10 +862,10 @@ test "sigaction" {...@@ -862,10 +862,10 @@ test "sigaction" {
862 var old_sa: posix.Sigaction = undefined;862 var old_sa: posix.Sigaction = undefined;
863863
864 // Install the new signal handler.864 // Install the new signal handler.
865 try posix.sigaction(posix.SIG.USR1, &sa, null);865 posix.sigaction(posix.SIG.USR1, &sa, null);
866866
867 // Check that we can read it back correctly.867 // Check that we can read it back correctly.
868 try posix.sigaction(posix.SIG.USR1, null, &old_sa);868 posix.sigaction(posix.SIG.USR1, null, &old_sa);
869 try testing.expectEqual(&S.handler, old_sa.handler.sigaction.?);869 try testing.expectEqual(&S.handler, old_sa.handler.sigaction.?);
870 try testing.expect((old_sa.flags & posix.SA.SIGINFO) != 0);870 try testing.expect((old_sa.flags & posix.SA.SIGINFO) != 0);
871871
...@@ -874,26 +874,26 @@ test "sigaction" {...@@ -874,26 +874,26 @@ test "sigaction" {
874 try testing.expect(S.handler_called_count == 1);874 try testing.expect(S.handler_called_count == 1);
875875
876 // Check if passing RESETHAND correctly reset the handler to SIG_DFL876 // Check if passing RESETHAND correctly reset the handler to SIG_DFL
877 try posix.sigaction(posix.SIG.USR1, null, &old_sa);877 posix.sigaction(posix.SIG.USR1, null, &old_sa);
878 try testing.expectEqual(posix.SIG.DFL, old_sa.handler.handler);878 try testing.expectEqual(posix.SIG.DFL, old_sa.handler.handler);
879879
880 // Reinstall the signal w/o RESETHAND and re-raise880 // Reinstall the signal w/o RESETHAND and re-raise
881 sa.flags = posix.SA.SIGINFO;881 sa.flags = posix.SA.SIGINFO;
882 try posix.sigaction(posix.SIG.USR1, &sa, null);882 posix.sigaction(posix.SIG.USR1, &sa, null);
883 try posix.raise(posix.SIG.USR1);883 try posix.raise(posix.SIG.USR1);
884 try testing.expect(S.handler_called_count == 2);884 try testing.expect(S.handler_called_count == 2);
885885
886 // Now set the signal to ignored886 // Now set the signal to ignored
887 sa.handler = .{ .handler = posix.SIG.IGN };887 sa.handler = .{ .handler = posix.SIG.IGN };
888 sa.flags = 0;888 sa.flags = 0;
889 try posix.sigaction(posix.SIG.USR1, &sa, null);889 posix.sigaction(posix.SIG.USR1, &sa, null);
890890
891 // Re-raise to ensure handler is actually ignored891 // Re-raise to ensure handler is actually ignored
892 try posix.raise(posix.SIG.USR1);892 try posix.raise(posix.SIG.USR1);
893 try testing.expect(S.handler_called_count == 2);893 try testing.expect(S.handler_called_count == 2);
894894
895 // Ensure that ignored state is returned when querying895 // Ensure that ignored state is returned when querying
896 try posix.sigaction(posix.SIG.USR1, null, &old_sa);896 posix.sigaction(posix.SIG.USR1, null, &old_sa);
897 try testing.expectEqual(posix.SIG.IGN, old_sa.handler.handler.?);897 try testing.expectEqual(posix.SIG.IGN, old_sa.handler.handler.?);
898}898}
899899
lib/std/start.zig+1-2
...@@ -638,8 +638,7 @@ fn maybeIgnoreSigpipe() void {...@@ -638,8 +638,7 @@ fn maybeIgnoreSigpipe() void {
638 .mask = posix.empty_sigset,638 .mask = posix.empty_sigset,
639 .flags = 0,639 .flags = 0,
640 };640 };
641 posix.sigaction(posix.SIG.PIPE, &act, null) catch |err|641 posix.sigaction(posix.SIG.PIPE, &act, null);
642 std.debug.panic("failed to set noop SIGPIPE handler: {s}", .{@errorName(err)});
643 }642 }
644}643}
645644
src/crash_report.zig+1-3
...@@ -163,9 +163,7 @@ pub fn attachSegfaultHandler() void {...@@ -163,9 +163,7 @@ pub fn attachSegfaultHandler() void {
163 .flags = (posix.SA.SIGINFO | posix.SA.RESTART | posix.SA.RESETHAND),163 .flags = (posix.SA.SIGINFO | posix.SA.RESTART | posix.SA.RESETHAND),
164 };164 };
165165
166 debug.updateSegfaultHandler(&act) catch {166 debug.updateSegfaultHandler(&act);
167 @panic("unable to install segfault handler, maybe adjust have_segfault_handling_support in std/debug.zig");
168 };
169}167}
170168
171fn handleSegfaultPosix(sig: i32, info: *const posix.siginfo_t, ctx_ptr: ?*anyopaque) callconv(.C) noreturn {169fn handleSegfaultPosix(sig: i32, info: *const posix.siginfo_t, ctx_ptr: ?*anyopaque) callconv(.C) noreturn {