Commit fc9e28ea37

Andrew Kelley <andrew@ziglang.org>
2019-07-08 20:26:40
std.os.getrandom does a libc version check
closes #397
1 parent 4953e84
Changed files (3)
src/ir.cpp
@@ -11191,7 +11191,7 @@ static IrBasicBlock *ir_get_new_bb_runtime(IrAnalyze *ira, IrBasicBlock *old_bb,
 }
 
 static void ir_start_bb(IrAnalyze *ira, IrBasicBlock *old_bb, IrBasicBlock *const_predecessor_bb) {
-    assert(!old_bb->suspended);
+    ir_assert(!old_bb->suspended, old_bb->instruction_list.at(0));
     ira->instruction_index = 0;
     ira->old_irb.current_basic_block = old_bb;
     ira->const_predecessor_bb = const_predecessor_bb;
std/c.zig
@@ -21,6 +21,33 @@ pub fn getErrno(rc: var) u16 {
     }
 }
 
+/// The return type is `type` to force comptime function call execution.
+/// TODO: https://github.com/ziglang/zig/issues/425
+/// If not linking libc, returns struct{pub const ok = false;}
+/// If linking musl libc, returns struct{pub const ok = true;}
+/// If linking gnu libc (glibc), the `ok` value will be true if the target
+/// version is greater than or equal to `glibc_version`.
+/// If linking a libc other than these, returns `false`.
+pub fn versionCheck(glibc_version: builtin.Version) type {
+    return struct {
+        pub const ok = blk: {
+            if (!builtin.link_libc) break :blk false;
+            switch (builtin.abi) {
+                .musl, .musleabi, .musleabihf => break :blk true,
+                .gnu, .gnuabin32, .gnuabi64, .gnueabi, .gnueabihf, .gnux32 => {
+                    const ver = builtin.glibc_version orelse break :blk false;
+                    if (ver.major < glibc_version.major) break :blk false;
+                    if (ver.major > glibc_version.major) break :blk true;
+                    if (ver.minor < glibc_version.minor) break :blk false;
+                    if (ver.minor > glibc_version.minor) break :blk true;
+                    break :blk ver.patch >= glibc_version.patch;
+                },
+                else => break :blk false,
+            }
+        };
+    };
+}
+
 // TODO https://github.com/ziglang/zig/issues/265 on this whole file
 
 pub extern "c" fn fopen(filename: [*]const u8, modes: [*]const u8) ?*FILE;
std/os.zig
@@ -105,14 +105,18 @@ pub fn getrandom(buf: []u8) GetRandomError!void {
     }
     if (linux.is_the_target) {
         while (true) {
-            // Bypass libc because it's missing on even relatively new versions.
-            switch (linux.getErrno(linux.getrandom(buf.ptr, buf.len, 0))) {
+            const err = if (std.c.versionCheck(builtin.Version{ .major = 2, .minor = 25, .patch = 0 }).ok) blk: {
+                break :blk errno(std.c.getrandom(buf.ptr, buf.len, 0));
+            } else blk: {
+                break :blk linux.getErrno(linux.getrandom(buf.ptr, buf.len, 0));
+            };
+            switch (err) {
                 0 => return,
                 EINVAL => unreachable,
                 EFAULT => unreachable,
                 EINTR => continue,
                 ENOSYS => return getRandomBytesDevURandom(buf),
-                else => |err| return unexpectedErrno(err),
+                else => return unexpectedErrno(err),
             }
         }
     }