commit a23ef3783bb5357376acdce12f73b0285636d6cf (tree)
parent 2ac8d90df05fdbb59a0ee9ff6609a058185f66ff
Author: Jakub Konka <kubkon@jakubkonka.com>
Date: Thu, 16 Mar 2023 12:13:19 +0100
os.zig: expose ptrace wrapper for darwin and linux
Diffstat:
| M | lib/std/os.zig | | | 53 | ++++++++++++++++++++++++++++++++++++++++------------- |
1 file changed, 40 insertions(+), 13 deletions(-)
diff --git a/lib/std/os.zig b/lib/std/os.zig
@@ -7129,22 +7129,49 @@ pub fn timerfd_gettime(fd: i32) TimerFdGetError!linux.itimerspec {
pub const PtraceError = error{
DeviceBusy,
+ InputOutput,
+ Overflow,
ProcessNotFound,
PermissionDenied,
} || UnexpectedError;
-/// TODO on other OSes
-pub fn ptrace(request: i32, pid: pid_t, addr: ?[*]u8, signal: i32) PtraceError!void {
- switch (builtin.os.tag) {
- .macos, .ios, .tvos, .watchos => {},
- else => @compileError("TODO implement ptrace"),
- }
- return switch (errno(system.ptrace(request, pid, addr, signal))) {
- .SUCCESS => {},
- .SRCH => error.ProcessNotFound,
- .INVAL => unreachable,
- .PERM => error.PermissionDenied,
- .BUSY => error.DeviceBusy,
- else => |err| return unexpectedErrno(err),
+pub fn ptrace(request: u32, pid: pid_t, addr: usize, signal: usize) PtraceError!void {
+ if (builtin.os.tag == .windows or builtin.os.tag == .wasi)
+ @compileError("Unsupported OS");
+
+ return switch (builtin.os.tag) {
+ .linux => switch (errno(linux.ptrace(request, pid, addr, signal, 0))) {
+ .SUCCESS => {},
+ .SRCH => error.ProcessNotFound,
+ .FAULT => unreachable,
+ .INVAL => unreachable,
+ .IO => return error.InputOutput,
+ .PERM => error.PermissionDenied,
+ .BUSY => error.DeviceBusy,
+ else => |err| return unexpectedErrno(err),
+ },
+
+ .macos, .ios, .tvos, .watchos => switch (errno(darwin.ptrace(
+ math.cast(i32, request) orelse return error.Overflow,
+ pid,
+ @intToPtr(?[*]u8, addr),
+ math.cast(i32, signal) orelse return error.Overflow,
+ ))) {
+ .SUCCESS => {},
+ .SRCH => error.ProcessNotFound,
+ .INVAL => unreachable,
+ .PERM => error.PermissionDenied,
+ .BUSY => error.DeviceBusy,
+ else => |err| return unexpectedErrno(err),
+ },
+
+ else => switch (errno(system.ptrace(request, pid, addr, signal))) {
+ .SUCCESS => {},
+ .SRCH => error.ProcessNotFound,
+ .INVAL => unreachable,
+ .PERM => error.PermissionDenied,
+ .BUSY => error.DeviceBusy,
+ else => |err| return unexpectedErrno(err),
+ },
};
}