diff --git a/lib/std/c/darwin.zig b/lib/std/c/darwin.zig index 2aa05e1cc7..ab352844db 100644 --- a/lib/std/c/darwin.zig +++ b/lib/std/c/darwin.zig @@ -897,7 +897,35 @@ pub extern "c" fn pthread_attr_get_qos_class_np(attr: *pthread_attr_t, qos_class pub extern "c" fn pthread_set_qos_class_self_np(qos_class: qos_class_t, relative_priority: c_int) c_int; pub extern "c" fn pthread_get_qos_class_np(pthread: std.c.pthread_t, qos_class: *qos_class_t, relative_priority: *c_int) c_int; +pub const CCryptorStatus = enum(i32) { + /// Operation completed + kCCSuccess = 0, + /// Illegal parameter + kCCParamError = -4300, + /// Provided buffer too small + kCCBufferTooSmall = -4301, + /// Failed memory allocation + kCCMemoryFailure = -4302, + /// Size alignment issue + kCCAlignmentError = -4303, + /// Decoding issue + kCCDecodeError = -4304, + /// Call not implemented + kCCUnimplemented = -4305, + kCCOverflow = -4306, + kCCRNGFailure = -4307, + /// Unspecified error + kCCUnspecifiedError = -4308, + kCCCallSequenceError = -4309, + kCCKeySizeError = -4310, + /// Invalid key + kCCInvalidKey = -4311, +}; + +pub const CCRNGStatus = CCryptorStatus; + pub extern "c" fn arc4random_buf(buf: [*]u8, len: usize) void; +pub extern "c" fn CCRandomGenerateBytes(bytes: ?*anyopaque, count: usize) CCRNGStatus; // Grand Central Dispatch is exposed by libSystem. pub extern "c" fn dispatch_release(object: *anyopaque) void; diff --git a/lib/std/os.zig b/lib/std/os.zig index 7759f1403f..c8dca0b785 100644 --- a/lib/std/os.zig +++ b/lib/std/os.zig @@ -512,7 +512,18 @@ pub fn getrandom(buffer: []u8) GetRandomError!void { return; } switch (builtin.os.tag) { - .netbsd, .openbsd, .macos, .ios, .tvos, .watchos => { + .macos, .ios => { + const rc = darwin.CCRandomGenerateBytes(buffer.ptr, buffer.len); + if (rc != darwin.CCRNGStatus.kCCSuccess) { + if (rc == darwin.CCRNGStatus.kCCParamError or rc == darwin.CCRNGStatus.kCCBufferTooSmall) { + return error.InvalidHandle; + } else { + return error.SystemResources; + } + } + return; + }, + .netbsd, .openbsd, .tvos, .watchos => { system.arc4random_buf(buffer.ptr, buffer.len); return; }, @@ -991,7 +1002,7 @@ pub fn preadv(fd: fd_t, iov: []const iovec, offset: u64) PReadError!usize { if (have_pread_but_not_preadv) { // We could loop here; but proper usage of `preadv` must handle partial reads anyway. // So we simply read into the first vector only. - if (iov.len == 0) return @as(usize, 0); + if (iov.len == 0) return @intCast(usize, 0); const first = iov[0]; return pread(fd, first.iov_base[0..first.iov_len], offset); }