| ... | ... | @@ -203,47 +203,6 @@ pub extern "c" fn mach_timebase_info(tinfo: ?*mach_timebase_info_data) kern_retu |
| 203 | 203 | pub extern "c" fn malloc_size(?*const anyopaque) usize; |
| 204 | 204 | pub extern "c" fn posix_memalign(memptr: *?*anyopaque, alignment: usize, size: usize) c_int; |
| 205 | 205 | |
| 206 | | pub const posix_spawnattr_t = *opaque {}; |
| 207 | | pub const posix_spawn_file_actions_t = *opaque {}; |
| 208 | | pub extern "c" fn posix_spawnattr_init(attr: *posix_spawnattr_t) c_int; |
| 209 | | pub extern "c" fn posix_spawnattr_destroy(attr: *posix_spawnattr_t) c_int; |
| 210 | | pub extern "c" fn posix_spawnattr_setflags(attr: *posix_spawnattr_t, flags: c_short) c_int; |
| 211 | | pub extern "c" fn posix_spawnattr_getflags(attr: *const posix_spawnattr_t, flags: *c_short) c_int; |
| 212 | | pub extern "c" fn posix_spawn_file_actions_init(actions: *posix_spawn_file_actions_t) c_int; |
| 213 | | pub extern "c" fn posix_spawn_file_actions_destroy(actions: *posix_spawn_file_actions_t) c_int; |
| 214 | | pub extern "c" fn posix_spawn_file_actions_addclose(actions: *posix_spawn_file_actions_t, filedes: fd_t) c_int; |
| 215 | | pub extern "c" fn posix_spawn_file_actions_addopen( |
| 216 | | actions: *posix_spawn_file_actions_t, |
| 217 | | filedes: fd_t, |
| 218 | | path: [*:0]const u8, |
| 219 | | oflag: c_int, |
| 220 | | mode: mode_t, |
| 221 | | ) c_int; |
| 222 | | pub extern "c" fn posix_spawn_file_actions_adddup2( |
| 223 | | actions: *posix_spawn_file_actions_t, |
| 224 | | filedes: fd_t, |
| 225 | | newfiledes: fd_t, |
| 226 | | ) c_int; |
| 227 | | pub extern "c" fn posix_spawn_file_actions_addinherit_np(actions: *posix_spawn_file_actions_t, filedes: fd_t) c_int; |
| 228 | | pub extern "c" fn posix_spawn_file_actions_addchdir_np(actions: *posix_spawn_file_actions_t, path: [*:0]const u8) c_int; |
| 229 | | pub extern "c" fn posix_spawn_file_actions_addfchdir_np(actions: *posix_spawn_file_actions_t, filedes: fd_t) c_int; |
| 230 | | pub extern "c" fn posix_spawn( |
| 231 | | pid: *pid_t, |
| 232 | | path: [*:0]const u8, |
| 233 | | actions: ?*const posix_spawn_file_actions_t, |
| 234 | | attr: ?*const posix_spawnattr_t, |
| 235 | | argv: [*:null]?[*:0]const u8, |
| 236 | | env: [*:null]?[*:0]const u8, |
| 237 | | ) c_int; |
| 238 | | pub extern "c" fn posix_spawnp( |
| 239 | | pid: *pid_t, |
| 240 | | path: [*:0]const u8, |
| 241 | | actions: ?*const posix_spawn_file_actions_t, |
| 242 | | attr: ?*const posix_spawnattr_t, |
| 243 | | argv: [*:null]?[*:0]const u8, |
| 244 | | env: [*:null]?[*:0]const u8, |
| 245 | | ) c_int; |
| 246 | | |
| 247 | 206 | pub extern "c" fn kevent64( |
| 248 | 207 | kq: c_int, |
| 249 | 208 | changelist: [*]const kevent64_s, |
| ... | ... | @@ -2176,18 +2135,6 @@ pub const E = enum(u16) { |
| 2176 | 2135 | _, |
| 2177 | 2136 | }; |
| 2178 | 2137 | |
| 2179 | | pub fn getKernError(err: kern_return_t) KernE { |
| 2180 | | return @intToEnum(KernE, @truncate(u32, @intCast(usize, err))); |
| 2181 | | } |
| 2182 | | |
| 2183 | | pub fn unexpectedKernError(err: KernE) std.os.UnexpectedError { |
| 2184 | | if (std.os.unexpected_error_tracing) { |
| 2185 | | std.debug.print("unexpected errno: {d}\n", .{@enumToInt(err)}); |
| 2186 | | std.debug.dumpCurrentStackTrace(null); |
| 2187 | | } |
| 2188 | | return error.Unexpected; |
| 2189 | | } |
| 2190 | | |
| 2191 | 2138 | /// Kernel return values |
| 2192 | 2139 | pub const KernE = enum(u32) { |
| 2193 | 2140 | SUCCESS = 0, |
| ... | ... | @@ -3063,6 +3010,29 @@ pub const CPUFAMILY = enum(u32) { |
| 3063 | 3010 | _, |
| 3064 | 3011 | }; |
| 3065 | 3012 | |
| 3013 | pub const PT = struct { |
| 3014 | pub const TRACE_ME = 0; |
| 3015 | pub const READ_I = 1; |
| 3016 | pub const READ_D = 2; |
| 3017 | pub const READ_U = 3; |
| 3018 | pub const WRITE_I = 4; |
| 3019 | pub const WRITE_D = 5; |
| 3020 | pub const WRITE_U = 6; |
| 3021 | pub const CONTINUE = 7; |
| 3022 | pub const KILL = 8; |
| 3023 | pub const STEP = 9; |
| 3024 | pub const DETACH = 11; |
| 3025 | pub const SIGEXC = 12; |
| 3026 | pub const THUPDATE = 13; |
| 3027 | pub const ATTACHEXC = 14; |
| 3028 | pub const FORCEQUOTA = 30; |
| 3029 | pub const DENY_ATTACH = 31; |
| 3030 | }; |
| 3031 | |
| 3032 | pub const caddr_t = ?[*]u8; |
| 3033 | |
| 3034 | pub extern "c" fn ptrace(request: c_int, pid: pid_t, addr: caddr_t, data: c_int) c_int; |
| 3035 | |
| 3066 | 3036 | pub const POSIX_SPAWN_RESETIDS = 0x0001; |
| 3067 | 3037 | pub const POSIX_SPAWN_SETPGROUP = 0x0002; |
| 3068 | 3038 | pub const POSIX_SPAWN_SETSIGDEF = 0x0004; |
| ... | ... | @@ -3074,26 +3044,283 @@ pub const POSIX_SPAWN_SETSID = 0x0400; |
| 3074 | 3044 | pub const _POSIX_SPAWN_RESLIDE = 0x0800; |
| 3075 | 3045 | pub const POSIX_SPAWN_CLOEXEC_DEFAULT = 0x4000; |
| 3076 | 3046 | |
| 3077 | | pub const PT_TRACE_ME = 0; |
| 3078 | | pub const PT_READ_I = 1; |
| 3079 | | pub const PT_READ_D = 2; |
| 3080 | | pub const PT_READ_U = 3; |
| 3081 | | pub const PT_WRITE_I = 4; |
| 3082 | | pub const PT_WRITE_D = 5; |
| 3083 | | pub const PT_WRITE_U = 6; |
| 3084 | | pub const PT_CONTINUE = 7; |
| 3085 | | pub const PT_KILL = 8; |
| 3086 | | pub const PT_STEP = 9; |
| 3087 | | pub const PT_DETACH = 11; |
| 3088 | | pub const PT_SIGEXC = 12; |
| 3089 | | pub const PT_THUPDATE = 13; |
| 3090 | | pub const PT_ATTACHEXC = 14; |
| 3091 | | pub const PT_FORCEQUOTA = 30; |
| 3092 | | pub const PT_DENY_ATTACH = 31; |
| 3047 | pub const posix_spawnattr_t = *opaque {}; |
| 3048 | pub const posix_spawn_file_actions_t = *opaque {}; |
| 3049 | pub extern "c" fn posix_spawnattr_init(attr: *posix_spawnattr_t) c_int; |
| 3050 | pub extern "c" fn posix_spawnattr_destroy(attr: *posix_spawnattr_t) c_int; |
| 3051 | pub extern "c" fn posix_spawnattr_setflags(attr: *posix_spawnattr_t, flags: c_short) c_int; |
| 3052 | pub extern "c" fn posix_spawnattr_getflags(attr: *const posix_spawnattr_t, flags: *c_short) c_int; |
| 3053 | pub extern "c" fn posix_spawn_file_actions_init(actions: *posix_spawn_file_actions_t) c_int; |
| 3054 | pub extern "c" fn posix_spawn_file_actions_destroy(actions: *posix_spawn_file_actions_t) c_int; |
| 3055 | pub extern "c" fn posix_spawn_file_actions_addclose(actions: *posix_spawn_file_actions_t, filedes: fd_t) c_int; |
| 3056 | pub extern "c" fn posix_spawn_file_actions_addopen( |
| 3057 | actions: *posix_spawn_file_actions_t, |
| 3058 | filedes: fd_t, |
| 3059 | path: [*:0]const u8, |
| 3060 | oflag: c_int, |
| 3061 | mode: mode_t, |
| 3062 | ) c_int; |
| 3063 | pub extern "c" fn posix_spawn_file_actions_adddup2( |
| 3064 | actions: *posix_spawn_file_actions_t, |
| 3065 | filedes: fd_t, |
| 3066 | newfiledes: fd_t, |
| 3067 | ) c_int; |
| 3068 | pub extern "c" fn posix_spawn_file_actions_addinherit_np(actions: *posix_spawn_file_actions_t, filedes: fd_t) c_int; |
| 3069 | pub extern "c" fn posix_spawn_file_actions_addchdir_np(actions: *posix_spawn_file_actions_t, path: [*:0]const u8) c_int; |
| 3070 | pub extern "c" fn posix_spawn_file_actions_addfchdir_np(actions: *posix_spawn_file_actions_t, filedes: fd_t) c_int; |
| 3071 | pub extern "c" fn posix_spawn( |
| 3072 | pid: *pid_t, |
| 3073 | path: [*:0]const u8, |
| 3074 | actions: ?*const posix_spawn_file_actions_t, |
| 3075 | attr: ?*const posix_spawnattr_t, |
| 3076 | argv: [*:null]?[*:0]const u8, |
| 3077 | env: [*:null]?[*:0]const u8, |
| 3078 | ) c_int; |
| 3079 | pub extern "c" fn posix_spawnp( |
| 3080 | pid: *pid_t, |
| 3081 | path: [*:0]const u8, |
| 3082 | actions: ?*const posix_spawn_file_actions_t, |
| 3083 | attr: ?*const posix_spawnattr_t, |
| 3084 | argv: [*:null]?[*:0]const u8, |
| 3085 | env: [*:null]?[*:0]const u8, |
| 3086 | ) c_int; |
| 3087 | |
| 3088 | pub const PosixSpawn = struct { |
| 3089 | const errno = std.os.errno; |
| 3090 | const unexpectedErrno = std.os.unexpectedErrno; |
| 3091 | |
| 3092 | pub const Error = error{ |
| 3093 | SystemResources, |
| 3094 | InvalidFileDescriptor, |
| 3095 | NameTooLong, |
| 3096 | TooBig, |
| 3097 | PermissionDenied, |
| 3098 | InputOutput, |
| 3099 | FileSystem, |
| 3100 | FileNotFound, |
| 3101 | InvalidExe, |
| 3102 | NotDir, |
| 3103 | FileBusy, |
| 3104 | /// Returned when the child fails to execute either in the pre-exec() initialization step, or |
| 3105 | /// when exec(3) is invoked. |
| 3106 | ChildExecFailed, |
| 3107 | } || std.os.UnexpectedError; |
| 3108 | |
| 3109 | pub const Attr = struct { |
| 3110 | attr: posix_spawnattr_t, |
| 3111 | |
| 3112 | pub fn init() Error!Attr { |
| 3113 | var attr: posix_spawnattr_t = undefined; |
| 3114 | switch (errno(posix_spawnattr_init(&attr))) { |
| 3115 | .SUCCESS => return Attr{ .attr = attr }, |
| 3116 | .NOMEM => return error.SystemResources, |
| 3117 | .INVAL => unreachable, |
| 3118 | else => |err| return unexpectedErrno(err), |
| 3119 | } |
| 3120 | } |
| 3093 | 3121 | |
| 3094 | | pub const caddr_t = ?[*]u8; |
| 3122 | pub fn deinit(self: *Attr) void { |
| 3123 | defer self.* = undefined; |
| 3124 | switch (errno(posix_spawnattr_destroy(&self.attr))) { |
| 3125 | .SUCCESS => return, |
| 3126 | .INVAL => unreachable, // Invalid parameters. |
| 3127 | else => unreachable, |
| 3128 | } |
| 3129 | } |
| 3095 | 3130 | |
| 3096 | | pub extern "c" fn ptrace(request: c_int, pid: pid_t, addr: caddr_t, data: c_int) c_int; |
| 3131 | pub fn get(self: Attr) Error!u16 { |
| 3132 | var flags: c_short = undefined; |
| 3133 | switch (errno(posix_spawnattr_getflags(&self.attr, &flags))) { |
| 3134 | .SUCCESS => return @bitCast(u16, flags), |
| 3135 | .INVAL => unreachable, |
| 3136 | else => |err| return unexpectedErrno(err), |
| 3137 | } |
| 3138 | } |
| 3139 | |
| 3140 | pub fn set(self: *Attr, flags: u16) Error!void { |
| 3141 | switch (errno(posix_spawnattr_setflags(&self.attr, @bitCast(c_short, flags)))) { |
| 3142 | .SUCCESS => return, |
| 3143 | .INVAL => unreachable, |
| 3144 | else => |err| return unexpectedErrno(err), |
| 3145 | } |
| 3146 | } |
| 3147 | }; |
| 3148 | |
| 3149 | pub const Actions = struct { |
| 3150 | actions: posix_spawn_file_actions_t, |
| 3151 | |
| 3152 | pub fn init() Error!Actions { |
| 3153 | var actions: posix_spawn_file_actions_t = undefined; |
| 3154 | switch (errno(posix_spawn_file_actions_init(&actions))) { |
| 3155 | .SUCCESS => return Actions{ .actions = actions }, |
| 3156 | .NOMEM => return error.SystemResources, |
| 3157 | .INVAL => unreachable, |
| 3158 | else => |err| return unexpectedErrno(err), |
| 3159 | } |
| 3160 | } |
| 3161 | |
| 3162 | pub fn deinit(self: *Actions) void { |
| 3163 | defer self.* = undefined; |
| 3164 | switch (errno(posix_spawn_file_actions_destroy(&self.actions))) { |
| 3165 | .SUCCESS => return, |
| 3166 | .INVAL => unreachable, // Invalid parameters. |
| 3167 | else => unreachable, |
| 3168 | } |
| 3169 | } |
| 3170 | |
| 3171 | pub fn open(self: *Actions, fd: fd_t, path: []const u8, flags: u32, mode: mode_t) Error!void { |
| 3172 | const posix_path = try std.os.toPosixPath(path); |
| 3173 | return self.openZ(fd, &posix_path, flags, mode); |
| 3174 | } |
| 3175 | |
| 3176 | pub fn openZ(self: *Actions, fd: fd_t, path: [*:0]const u8, flags: u32, mode: mode_t) Error!void { |
| 3177 | switch (errno(posix_spawn_file_actions_addopen(&self.actions, fd, path, @bitCast(c_int, flags), mode))) { |
| 3178 | .SUCCESS => return, |
| 3179 | .BADF => return error.InvalidFileDescriptor, |
| 3180 | .NOMEM => return error.SystemResources, |
| 3181 | .NAMETOOLONG => return error.NameTooLong, |
| 3182 | .INVAL => unreachable, // the value of file actions is invalid |
| 3183 | else => |err| return unexpectedErrno(err), |
| 3184 | } |
| 3185 | } |
| 3186 | |
| 3187 | pub fn close(self: *Actions, fd: fd_t) Error!void { |
| 3188 | switch (errno(posix_spawn_file_actions_addclose(&self.actions, fd))) { |
| 3189 | .SUCCESS => return, |
| 3190 | .BADF => return error.InvalidFileDescriptor, |
| 3191 | .NOMEM => return error.SystemResources, |
| 3192 | .INVAL => unreachable, // the value of file actions is invalid |
| 3193 | .NAMETOOLONG => unreachable, |
| 3194 | else => |err| return unexpectedErrno(err), |
| 3195 | } |
| 3196 | } |
| 3197 | |
| 3198 | pub fn dup2(self: *Actions, fd: fd_t, newfd: fd_t) Error!void { |
| 3199 | switch (errno(posix_spawn_file_actions_adddup2(&self.actions, fd, newfd))) { |
| 3200 | .SUCCESS => return, |
| 3201 | .BADF => return error.InvalidFileDescriptor, |
| 3202 | .NOMEM => return error.SystemResources, |
| 3203 | .INVAL => unreachable, // the value of file actions is invalid |
| 3204 | .NAMETOOLONG => unreachable, |
| 3205 | else => |err| return unexpectedErrno(err), |
| 3206 | } |
| 3207 | } |
| 3208 | |
| 3209 | pub fn inherit(self: *Actions, fd: fd_t) Error!void { |
| 3210 | switch (errno(posix_spawn_file_actions_addinherit_np(&self.actions, fd))) { |
| 3211 | .SUCCESS => return, |
| 3212 | .BADF => return error.InvalidFileDescriptor, |
| 3213 | .NOMEM => return error.SystemResources, |
| 3214 | .INVAL => unreachable, // the value of file actions is invalid |
| 3215 | .NAMETOOLONG => unreachable, |
| 3216 | else => |err| return unexpectedErrno(err), |
| 3217 | } |
| 3218 | } |
| 3219 | |
| 3220 | pub fn chdir(self: *Actions, path: []const u8) Error!void { |
| 3221 | const posix_path = try std.os.toPosixPath(path); |
| 3222 | return self.chdirZ(&posix_path); |
| 3223 | } |
| 3224 | |
| 3225 | pub fn chdirZ(self: *Actions, path: [*:0]const u8) Error!void { |
| 3226 | switch (errno(posix_spawn_file_actions_addchdir_np(&self.actions, path))) { |
| 3227 | .SUCCESS => return, |
| 3228 | .NOMEM => return error.SystemResources, |
| 3229 | .NAMETOOLONG => return error.NameTooLong, |
| 3230 | .BADF => unreachable, |
| 3231 | .INVAL => unreachable, // the value of file actions is invalid |
| 3232 | else => |err| return unexpectedErrno(err), |
| 3233 | } |
| 3234 | } |
| 3235 | |
| 3236 | pub fn fchdir(self: *Actions, fd: fd_t) Error!void { |
| 3237 | switch (errno(posix_spawn_file_actions_addfchdir_np(&self.actions, fd))) { |
| 3238 | .SUCCESS => return, |
| 3239 | .BADF => return error.InvalidFileDescriptor, |
| 3240 | .NOMEM => return error.SystemResources, |
| 3241 | .INVAL => unreachable, // the value of file actions is invalid |
| 3242 | .NAMETOOLONG => unreachable, |
| 3243 | else => |err| return unexpectedErrno(err), |
| 3244 | } |
| 3245 | } |
| 3246 | }; |
| 3247 | |
| 3248 | pub fn spawn( |
| 3249 | path: []const u8, |
| 3250 | actions: ?Actions, |
| 3251 | attr: ?Attr, |
| 3252 | argv: [*:null]?[*:0]const u8, |
| 3253 | envp: [*:null]?[*:0]const u8, |
| 3254 | ) Error!pid_t { |
| 3255 | const posix_path = try std.os.toPosixPath(path); |
| 3256 | return spawnZ(&posix_path, actions, attr, argv, envp); |
| 3257 | } |
| 3258 | |
| 3259 | pub fn spawnZ( |
| 3260 | path: [*:0]const u8, |
| 3261 | actions: ?Actions, |
| 3262 | attr: ?Attr, |
| 3263 | argv: [*:null]?[*:0]const u8, |
| 3264 | envp: [*:null]?[*:0]const u8, |
| 3265 | ) Error!pid_t { |
| 3266 | var pid: pid_t = undefined; |
| 3267 | switch (errno(posix_spawn( |
| 3268 | &pid, |
| 3269 | path, |
| 3270 | if (actions) |a| &a.actions else null, |
| 3271 | if (attr) |a| &a.attr else null, |
| 3272 | argv, |
| 3273 | envp, |
| 3274 | ))) { |
| 3275 | .SUCCESS => return pid, |
| 3276 | .@"2BIG" => return error.TooBig, |
| 3277 | .NOMEM => return error.SystemResources, |
| 3278 | .BADF => return error.InvalidFileDescriptor, |
| 3279 | .ACCES => return error.PermissionDenied, |
| 3280 | .IO => return error.InputOutput, |
| 3281 | .LOOP => return error.FileSystem, |
| 3282 | .NAMETOOLONG => return error.NameTooLong, |
| 3283 | .NOENT => return error.FileNotFound, |
| 3284 | .NOEXEC => return error.InvalidExe, |
| 3285 | .NOTDIR => return error.NotDir, |
| 3286 | .TXTBSY => return error.FileBusy, |
| 3287 | .BADARCH => return error.InvalidExe, |
| 3288 | .BADEXEC => return error.InvalidExe, |
| 3289 | .FAULT => unreachable, |
| 3290 | .INVAL => unreachable, |
| 3291 | else => |err| return unexpectedErrno(err), |
| 3292 | } |
| 3293 | } |
| 3294 | |
| 3295 | pub fn waitpid(pid: pid_t, flags: u32) Error!std.os.WaitPidResult { |
| 3296 | var status: c_int = undefined; |
| 3297 | while (true) { |
| 3298 | const rc = waitpid(pid, &status, @intCast(c_int, flags)); |
| 3299 | switch (errno(rc)) { |
| 3300 | .SUCCESS => return std.os.WaitPidResult{ |
| 3301 | .pid = @intCast(pid_t, rc), |
| 3302 | .status = @bitCast(u32, status), |
| 3303 | }, |
| 3304 | .INTR => continue, |
| 3305 | .CHILD => return error.ChildExecFailed, |
| 3306 | .INVAL => unreachable, // Invalid flags. |
| 3307 | else => unreachable, |
| 3308 | } |
| 3309 | } |
| 3310 | } |
| 3311 | }; |
| 3312 | |
| 3313 | pub fn getKernError(err: kern_return_t) KernE { |
| 3314 | return @intToEnum(KernE, @truncate(u32, @intCast(usize, err))); |
| 3315 | } |
| 3316 | |
| 3317 | pub fn unexpectedKernError(err: KernE) std.os.UnexpectedError { |
| 3318 | if (std.os.unexpected_error_tracing) { |
| 3319 | std.debug.print("unexpected errno: {d}\n", .{@enumToInt(err)}); |
| 3320 | std.debug.dumpCurrentStackTrace(null); |
| 3321 | } |
| 3322 | return error.Unexpected; |
| 3323 | } |
| 3097 | 3324 | |
| 3098 | 3325 | pub const MachError = error{ |
| 3099 | 3326 | /// Not enough permissions held to perform the requested kernel |