Zig 0.17.0-dev (Split by item)
This is an example of documentation generated by
ZigDoc , an alternative to Zig's built-in
Auto Doc feature. See also
examples in other modes/formats . The project being documented here (as the example) is the Zig library itself.
Zig › std/ › Io/ › Threaded.zig › getRandomFd
getRandomFd
Threaded.getRandomFd
fn getRandomFd (t : *Threaded ) Io .RandomSecureError !posix .fd_t
File
Code
fn getRandomFd (t : *Threaded ) Io .RandomSecureError !posix .fd_t {
{
mutexLock (&t .mutex );
defer mutexUnlock (&t .mutex );
if (t .random_file .fd == -2 ) return error .EntropyUnavailable ;
if (t .random_file .fd != -1 ) return t .random_file .fd ;
}
const mode : posix .mode_t = 0 ;
const fd : posix .fd_t = fd : {
const syscall : Syscall = try .start ();
while (true ) {
const rc = openat_sym (posix .AT .FDCWD , "/dev/urandom" , .{
.ACCMODE = .RDONLY ,
.CLOEXEC = true ,
}, mode );
switch (posix .errno (rc )) {
.SUCCESS => {
syscall .finish ();
break :fd @intCast (rc );
},
.INTR => {
try syscall .checkCancel ();
continue ;
},
else => return syscall .fail (error .EntropyUnavailable ),
}
}
};
errdefer closeFd (fd );
switch (native_os ) {
.linux => {
const sys = if (statx_use_c ) std .c else std .os .linux ;
const syscall : Syscall = try .start ();
while (true ) {
var statx = std .mem .zeroes (std .os .linux .Statx );
switch (sys .errno (sys .statx (fd , "" , std .os .linux .AT .EMPTY_PATH , .{ .TYPE = true }, &statx ))) {
.SUCCESS => {
syscall .finish ();
if (!statx .mask .TYPE ) return error .EntropyUnavailable ;
mutexLock (&t .mutex );
defer mutexUnlock (&t .mutex );
if (t .random_file .fd >= 0 ) {
closeFd (fd );
return t .random_file .fd ;
} else if (!posix .S .ISCHR (statx .mode )) {
t .random_file .fd = -2 ;
return error .EntropyUnavailable ;
} else {
t .random_file .fd = fd ;
return fd ;
}
},
.INTR => {
try syscall .checkCancel ();
continue ;
},
else => return syscall .fail (error .EntropyUnavailable ),
}
}
},
else => {
const syscall : Syscall = try .start ();
while (true ) {
var stat = std .mem .zeroes (posix .Stat );
switch (posix .errno (fstat_sym (fd , &stat ))) {
.SUCCESS => {
syscall .finish ();
mutexLock (&t .mutex );
defer mutexUnlock (&t .mutex );
if (t .random_file .fd >= 0 ) {
closeFd (fd );
return t .random_file .fd ;
} else if (!posix .S .ISCHR (stat .mode )) {
t .random_file .fd = -2 ;
return error .EntropyUnavailable ;
} else {
t .random_file .fd = fd ;
return fd ;
}
},
.INTR => {
try syscall .checkCancel ();
continue ;
},
else => return syscall .fail (error .EntropyUnavailable ),
}
}
},
}
}