authorgravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2019-07-08 14:26:40-04:00
committergravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2019-07-08 14:42:28-04:00
logfc9e28ea37e0110836d6958c39ffe78ea6cad0f3
tree0245c64ed4119fa2054cbed785abc9a90695391e
parent4953e84902df3467b6d7491532e48bf33b5e56b9
signaturelock-open Commit is signed but in an unrecognized format.

std.os.getrandom does a libc version check

closes #397

3 files changed, 35 insertions(+), 4 deletions(-)

src/ir.cpp+1-1
...@@ -11191,7 +11191,7 @@ static IrBasicBlock *ir_get_new_bb_runtime(IrAnalyze *ira, IrBasicBlock *old_bb,...@@ -11191,7 +11191,7 @@ static IrBasicBlock *ir_get_new_bb_runtime(IrAnalyze *ira, IrBasicBlock *old_bb,
11191}11191}
1119211192
11193static void ir_start_bb(IrAnalyze *ira, IrBasicBlock *old_bb, IrBasicBlock *const_predecessor_bb) {11193static void ir_start_bb(IrAnalyze *ira, IrBasicBlock *old_bb, IrBasicBlock *const_predecessor_bb) {
11194 assert(!old_bb->suspended);11194 ir_assert(!old_bb->suspended, old_bb->instruction_list.at(0));
11195 ira->instruction_index = 0;11195 ira->instruction_index = 0;
11196 ira->old_irb.current_basic_block = old_bb;11196 ira->old_irb.current_basic_block = old_bb;
11197 ira->const_predecessor_bb = const_predecessor_bb;11197 ira->const_predecessor_bb = const_predecessor_bb;
std/c.zig+27
...@@ -21,6 +21,33 @@ pub fn getErrno(rc: var) u16 {...@@ -21,6 +21,33 @@ pub fn getErrno(rc: var) u16 {
21 }21 }
22}22}
2323
24/// The return type is `type` to force comptime function call execution.
25/// TODO: https://github.com/ziglang/zig/issues/425
26/// If not linking libc, returns struct{pub const ok = false;}
27/// If linking musl libc, returns struct{pub const ok = true;}
28/// If linking gnu libc (glibc), the `ok` value will be true if the target
29/// version is greater than or equal to `glibc_version`.
30/// If linking a libc other than these, returns `false`.
31pub fn versionCheck(glibc_version: builtin.Version) type {
32 return struct {
33 pub const ok = blk: {
34 if (!builtin.link_libc) break :blk false;
35 switch (builtin.abi) {
36 .musl, .musleabi, .musleabihf => break :blk true,
37 .gnu, .gnuabin32, .gnuabi64, .gnueabi, .gnueabihf, .gnux32 => {
38 const ver = builtin.glibc_version orelse break :blk false;
39 if (ver.major < glibc_version.major) break :blk false;
40 if (ver.major > glibc_version.major) break :blk true;
41 if (ver.minor < glibc_version.minor) break :blk false;
42 if (ver.minor > glibc_version.minor) break :blk true;
43 break :blk ver.patch >= glibc_version.patch;
44 },
45 else => break :blk false,
46 }
47 };
48 };
49}
50
24// TODO https://github.com/ziglang/zig/issues/265 on this whole file51// TODO https://github.com/ziglang/zig/issues/265 on this whole file
2552
26pub extern "c" fn fopen(filename: [*]const u8, modes: [*]const u8) ?*FILE;53pub extern "c" fn fopen(filename: [*]const u8, modes: [*]const u8) ?*FILE;
std/os.zig+7-3
...@@ -105,14 +105,18 @@ pub fn getrandom(buf: []u8) GetRandomError!void {...@@ -105,14 +105,18 @@ pub fn getrandom(buf: []u8) GetRandomError!void {
105 }105 }
106 if (linux.is_the_target) {106 if (linux.is_the_target) {
107 while (true) {107 while (true) {
108 // Bypass libc because it's missing on even relatively new versions.108 const err = if (std.c.versionCheck(builtin.Version{ .major = 2, .minor = 25, .patch = 0 }).ok) blk: {
109 switch (linux.getErrno(linux.getrandom(buf.ptr, buf.len, 0))) {109 break :blk errno(std.c.getrandom(buf.ptr, buf.len, 0));
110 } else blk: {
111 break :blk linux.getErrno(linux.getrandom(buf.ptr, buf.len, 0));
112 };
113 switch (err) {
110 0 => return,114 0 => return,
111 EINVAL => unreachable,115 EINVAL => unreachable,
112 EFAULT => unreachable,116 EFAULT => unreachable,
113 EINTR => continue,117 EINTR => continue,
114 ENOSYS => return getRandomBytesDevURandom(buf),118 ENOSYS => return getRandomBytesDevURandom(buf),
115 else => |err| return unexpectedErrno(err),119 else => return unexpectedErrno(err),
116 }120 }
117 }121 }
118 }122 }