Compare commits

...

3 Commits

Author SHA1 Message Date
Wooster
bc4ce55613
Merge 88e957e2b1 into f845fa04a0 2024-11-21 11:21:36 +11:00
Alex Rønne Petersen
f845fa04a0 std.debug: Gracefully handle process_vm_readv() EPERM in MemoryAccessor.read().
Closes #21815.
2024-11-20 23:07:46 +01:00
wooster0
88e957e2b1 std.io.tty: add setInterruptSignalHandler
Same as #20644 but without usage in the compiler.

The proposing issue #13045 is not marked as accepted but maybe this can
be merged anyway to see how it plays out and then it can still be
removed later.

Closes #13045.
2024-11-19 21:39:46 +09:00
2 changed files with 42 additions and 1 deletions

View File

@ -48,7 +48,8 @@ fn read(ma: *MemoryAccessor, address: usize, buf: []u8) bool {
switch (linux.E.init(bytes_read)) {
.SUCCESS => return bytes_read == buf.len,
.FAULT => return false,
.INVAL, .PERM, .SRCH => unreachable, // own pid is always valid
.INVAL, .SRCH => unreachable, // own pid is always valid
.PERM => {}, // Known to happen in containers.
.NOMEM => {},
.NOSYS => {}, // QEMU is known not to implement this syscall.
else => unreachable, // unexpected

View File

@ -133,3 +133,43 @@ pub const Config = union(enum) {
};
}
};
/// Registers a global handler function to run if an interrupt signal is catched.
/// An interrupt signal is usually fired if Ctrl+C is pressed in the terminal that controls the process.
///
/// Because this handler won't run if Ctrl+C isn't pressed by the user, registering this handler failed,
/// or the handler was overwritten by another setInterruptSignalHandler call,
/// this should be used only for non-critical cleanups or resets of terminal state and such.
///
/// A program can only have one handler at a time.
///
/// The handler will not exit the program after it runs.
pub fn setInterruptSignalHandler(comptime handler: fn () void) error{Unexpected}!void {
if (builtin.os.tag == .windows) {
const handler_routine = struct {
fn handler_routine(dwCtrlType: windows.DWORD) callconv(windows.WINAPI) windows.BOOL {
if (dwCtrlType == windows.CTRL_C_EVENT) {
handler();
return windows.TRUE;
} else {
// Ignore this event.
return windows.FALSE;
}
}
}.handler_routine;
try windows.SetConsoleCtrlHandler(handler_routine, true);
} else {
const internal_handler = struct {
fn internal_handler(sig: c_int) callconv(.C) void {
std.debug.assert(sig == std.posix.SIG.INT);
handler();
}
}.internal_handler;
const act = std.posix.Sigaction{
.handler = .{ .handler = internal_handler },
.mask = std.posix.empty_sigset,
.flags = 0,
};
std.posix.sigaction(std.posix.SIG.INT, &act, null);
}
}