authorgravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2026-01-06 17:17:38-08:00
committergravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2026-01-07 11:03:37-08:00
log0529fe34119fe82c82867bfebde00c96f4509b1b
treef836e27c005a37ebfbeff873ccca7c6986072009
parent1eddc1737c959e187070a7ddd470e8c2d22ac46d

std.Io.Threaded: fix implementation of getRandomFd


1 files changed, 17 insertions(+), 19 deletions(-)

lib/std/Io/Threaded.zig+17-19
......@@ -1755,7 +1755,7 @@ const getrandom_use_libc = @TypeOf(posix.system.getrandom) != void and (native_o
17551755 .patch = 0,
17561756 }));
17571757
1758const use_dev_urandom = getrandom_use_libc and native_os == .linux;
1758const use_dev_urandom = !getrandom_use_libc and native_os == .linux;
17591759
17601760fn async(
17611761 userdata: ?*anyopaque,
......@@ -3711,10 +3711,12 @@ fn dirOpenFilePosix(
37113711 },
37123712 };
37133713
3714 const mode: posix.mode_t = 0;
3715
37143716 const fd: posix.fd_t = fd: {
37153717 const syscall: Syscall = try .start();
37163718 while (true) {
3717 const rc = openat_sym(dir.handle, sub_path_posix, os_flags, @as(posix.mode_t, 0));
3719 const rc = openat_sym(dir.handle, sub_path_posix, os_flags, mode);
37183720 switch (posix.errno(rc)) {
37193721 .SUCCESS => {
37203722 syscall.finish();
......@@ -4143,9 +4145,11 @@ fn dirOpenDirPosix(
41434145 if (@hasField(posix.O, "PATH") and !options.iterate)
41444146 flags.PATH = true;
41454147
4148 const mode: posix.mode_t = 0;
4149
41464150 const syscall: Syscall = try .start();
41474151 while (true) {
4148 const rc = openat_sym(dir.handle, sub_path_posix, flags, @as(usize, 0));
4152 const rc = openat_sym(dir.handle, sub_path_posix, flags, mode);
41494153 switch (posix.errno(rc)) {
41504154 .SUCCESS => {
41514155 syscall.finish();
......@@ -15270,7 +15274,7 @@ fn randomSecure(userdata: ?*anyopaque, buffer: []u8) Io.RandomSecureError!void {
1527015274 }
1527115275}
1527215276
15273fn getRandomFd(t: *Threaded) posix.fd_t {
15277fn getRandomFd(t: *Threaded) Io.RandomSecureError!posix.fd_t {
1527415278 {
1527515279 t.mutex.lock();
1527615280 defer t.mutex.unlock();
......@@ -15279,13 +15283,15 @@ fn getRandomFd(t: *Threaded) posix.fd_t {
1527915283 if (t.random_file.fd != -1) return t.random_file.fd;
1528015284 }
1528115285
15286 const mode: posix.mode_t = 0;
15287
1528215288 const fd: posix.fd_t = fd: {
1528315289 const syscall: Syscall = try .start();
1528415290 while (true) {
1528515291 const rc = openat_sym(posix.AT.FDCWD, "/dev/urandom", .{
1528615292 .ACCMODE = .RDONLY,
1528715293 .CLOEXEC = true,
15288 }, 0);
15294 }, mode);
1528915295 switch (posix.errno(rc)) {
1529015296 .SUCCESS => {
1529115297 syscall.finish();
......@@ -15295,11 +15301,7 @@ fn getRandomFd(t: *Threaded) posix.fd_t {
1529515301 try syscall.checkCancel();
1529615302 continue;
1529715303 },
15298 else => {
15299 syscall.endSyscall();
15300 t.random_file.fd = -2;
15301 return error.EntropyUnavailable;
15302 },
15304 else => return syscall.fail(error.EntropyUnavailable),
1530315305 }
1530415306 }
1530515307 };
......@@ -15314,7 +15316,7 @@ fn getRandomFd(t: *Threaded) posix.fd_t {
1531415316 switch (sys.errno(sys.statx(fd, "", std.os.linux.AT.EMPTY_PATH, .{ .TYPE = true }, &statx))) {
1531515317 .SUCCESS => {
1531615318 syscall.finish();
15317 if (!statx.mask.TYPE) return error.Unexpected;
15319 if (!statx.mask.TYPE) return error.EntropyUnavailable;
1531815320 t.mutex.lock(); // Another thread might have won the race.
1531915321 defer t.mutex.unlock();
1532015322 if (t.random_file.fd >= 0) {
......@@ -15332,10 +15334,7 @@ fn getRandomFd(t: *Threaded) posix.fd_t {
1533215334 try syscall.checkCancel();
1533315335 continue;
1533415336 },
15335 else => {
15336 t.random_file.fd = -2;
15337 return error.EntropyUnavailable;
15338 },
15337 else => return syscall.fail(error.EntropyUnavailable),
1533915338 }
1534015339 }
1534115340 },
......@@ -15346,6 +15345,8 @@ fn getRandomFd(t: *Threaded) posix.fd_t {
1534615345 switch (posix.errno(fstat_sym(fd, &stat))) {
1534715346 .SUCCESS => {
1534815347 syscall.finish();
15348 t.mutex.lock(); // Another thread might have won the race.
15349 defer t.mutex.unlock();
1534915350 if (t.random_file.fd >= 0) {
1535015351 posix.close(fd);
1535115352 return t.random_file.fd;
......@@ -15361,10 +15362,7 @@ fn getRandomFd(t: *Threaded) posix.fd_t {
1536115362 try syscall.checkCancel();
1536215363 continue;
1536315364 },
15364 else => {
15365 t.random_file.fd = -2;
15366 return error.EntropyUnavailable;
15367 },
15365 else => return syscall.fail(error.EntropyUnavailable),
1536815366 }
1536915367 }
1537015368 },