Commit 07f52119de

Andrew Kelley <andrew@ziglang.org>
2020-02-28 09:11:37
implement native OS version detection for linux
1 parent ef24f2d
Changed files (3)
lib/std/zig/system.zig
@@ -200,7 +200,22 @@ pub const NativeTargetInfo = struct {
         const cpu = Target.Cpu.baseline(arch);
 
         // TODO Detect native operating system version. Until that is implemented we use the default range.
-        const os = Target.Os.defaultVersionRange(os_tag);
+        var os = Target.Os.defaultVersionRange(os_tag);
+        switch (Target.current.os.tag) {
+            .linux => {
+                const uts = std.os.uname();
+                const release = mem.toSliceConst(u8, @ptrCast([*:0]const u8, &uts.release));
+                if (std.builtin.Version.parse(release)) |ver| {
+                    os.version_range.linux.range.min = ver;
+                    os.version_range.linux.range.max = ver;
+                } else |err| switch (err) {
+                    error.Overflow => {},
+                    error.InvalidCharacter => {},
+                    error.InvalidVersion => {},
+                }
+            },
+            else => {},
+        }
 
         return detectAbiAndDynamicLinker(allocator, cpu, os);
     }
lib/std/c.zig
@@ -125,6 +125,7 @@ pub extern "c" fn sysctlnametomib(name: [*:0]const u8, mibp: ?*c_int, sizep: ?*u
 pub extern "c" fn tcgetattr(fd: fd_t, termios_p: *termios) c_int;
 pub extern "c" fn tcsetattr(fd: fd_t, optional_action: TCSA, termios_p: *const termios) c_int;
 pub extern "c" fn fcntl(fd: fd_t, cmd: c_int, ...) c_int;
+pub extern "c" fn uname(buf: *utsname) c_int;
 
 pub extern "c" fn gethostname(name: [*]u8, len: usize) c_int;
 pub extern "c" fn bind(socket: fd_t, address: ?*const sockaddr, address_len: socklen_t) c_int;
lib/std/os.zig
@@ -3295,22 +3295,24 @@ pub fn gethostname(name_buffer: *[HOST_NAME_MAX]u8) GetHostNameError![]u8 {
         }
     }
     if (builtin.os.tag == .linux) {
-        var uts: utsname = undefined;
-        switch (errno(system.uname(&uts))) {
-            0 => {
-                const hostname = mem.toSlice(u8, @ptrCast([*:0]u8, &uts.nodename));
-                mem.copy(u8, name_buffer, hostname);
-                return name_buffer[0..hostname.len];
-            },
-            EFAULT => unreachable,
-            EPERM => return error.PermissionDenied,
-            else => |err| return unexpectedErrno(err),
-        }
+        const uts = uname();
+        const hostname = mem.toSliceConst(u8, @ptrCast([*:0]const u8, &uts.nodename));
+        mem.copy(u8, name_buffer, hostname);
+        return name_buffer[0..hostname.len];
     }
 
     @compileError("TODO implement gethostname for this OS");
 }
 
+pub fn uname() utsname {
+    var uts: utsname = undefined;
+    switch (errno(system.uname(&uts))) {
+        0 => return uts,
+        EFAULT => unreachable,
+        else => unreachable,
+    }
+}
+
 pub fn res_mkquery(
     op: u4,
     dname: []const u8,