Commit 29a418c9d5

Andrew Kelley <superjoe30@gmail.com>
2017-08-27 06:11:09
progress toward tests passing on MacOS
1 parent 105a09e
src/analyze.cpp
@@ -2891,6 +2891,10 @@ static void analyze_fn_body(CodeGen *g, FnTableEntry *fn_table_entry) {
 }
 
 static void add_symbols_from_import(CodeGen *g, AstNode *src_use_node, AstNode *dst_use_node) {
+    if (src_use_node->data.use.resolution == TldResolutionUnresolved) {
+        preview_use_decl(g, src_use_node);
+    }
+
     IrInstruction *use_target_value = src_use_node->data.use.value;
     if (use_target_value->value.type->id == TypeTableEntryIdInvalid) {
         dst_use_node->owner->any_imports_failed = true;
src/os.cpp
@@ -709,10 +709,6 @@ int os_delete_file(Buf *path) {
     }
 }
 
-void os_init(void) {
-    srand((unsigned)time(NULL));
-}
-
 int os_rename(Buf *src_path, Buf *dest_path) {
     if (rename(buf_ptr(src_path), buf_ptr(dest_path)) == -1) {
         return ErrorFileSystem;
@@ -805,7 +801,8 @@ int os_make_dir(Buf *path) {
 #endif
 }
 
-int zig_os_init(void) {
+int os_init(void) {
+    srand((unsigned)time(NULL));
 #if defined(ZIG_OS_WINDOWS)
     unsigned __int64 frequency;
     if (QueryPerformanceFrequency((LARGE_INTEGER*) &frequency)) {
src/os.hpp
@@ -27,8 +27,8 @@ struct Termination {
     int code;
 };
 
+int os_init(void);
 
-void os_init(void);
 void os_spawn_process(const char *exe, ZigList<const char *> &args, Termination *term);
 int os_exec_process(const char *exe, ZigList<const char *> &args,
         Termination *term, Buf *out_stderr, Buf *out_stdout);
std/c/darwin.zig
@@ -1,4 +1,32 @@
-pub extern "c" fn getrandom(buf_ptr: &u8, buf_len: usize) -> c_int;
-fn extern "c" __error() -> &c_int;
+extern "c" fn __error() -> &c_int;
 
 pub const _errno = __error;
+
+/// Renamed to Stat to not conflict with the stat function.
+pub const Stat = extern struct {
+    dev: u32,
+    mode: u16,
+    nlink: u16,
+    ino: u64,
+    uid: u32,
+    gid: u32,
+    rdev: u64,
+
+    atim: timespec,
+    mtim: timespec,
+    ctim: timespec,
+
+    size: u64,
+    blocks: u64,
+    blksize: u32,
+    flags: u32,
+    gen: u32,
+    lspare: i32,
+    qspare: [2]u64,
+
+};
+
+pub const timespec = extern struct {
+    tv_sec: isize,
+    tv_nsec: isize,
+};
std/c/index.zig
@@ -8,7 +8,32 @@ pub use switch(builtin.os) {
     Os.darwin, Os.macosx, Os.ios => @import("darwin.zig"),
     else => empty_import,
 };
+const empty_import = @import("../empty.zig");
 
 pub extern "c" fn abort() -> noreturn;
-
-const empty_import = @import("../empty.zig");
+pub extern "c" fn exit(code: c_int) -> noreturn;
+pub extern "c" fn isatty(fd: c_int) -> c_int;
+pub extern "c" fn close(fd: c_int) -> c_int;
+pub extern "c" fn fstat(fd: c_int, buf: &stat) -> c_int;
+pub extern "c" fn lseek(fd: c_int, offset: isize, whence: c_int) -> isize;
+pub extern "c" fn open(path: &const u8, oflag: c_int, ...) -> c_int;
+pub extern "c" fn raise(sig: c_int) -> c_int;
+pub extern "c" fn read(fd: c_int, buf: &c_void, nbyte: usize) -> isize;
+pub extern "c" fn stat(noalias path: &const u8, noalias buf: &Stat) -> c_int;
+pub extern "c" fn write(fd: c_int, buf: &const c_void, nbyte: usize) -> c_int;
+pub extern "c" fn mmap(addr: ?&c_void, len: usize, prot: c_int, flags: c_int,
+    fd: c_int, offset: isize) -> ?&c_void;
+pub extern "c" fn munmap(addr: &c_void, len: usize) -> c_int;
+pub extern "c" fn unlink(path: &const u8) -> c_int;
+pub extern "c" fn getcwd(buf: &u8, size: usize) -> ?&u8;
+pub extern "c" fn waitpid(pid: c_int, stat_loc: &c_int, options: c_int) -> c_int;
+pub extern "c" fn fork() -> c_int;
+pub extern "c" fn pipe(fds: &c_int) -> c_int;
+pub extern "c" fn mkdir(path: &const u8, mode: c_uint) -> c_int;
+pub extern "c" fn symlink(existing: &const u8, new: &const u8) -> c_int;
+pub extern "c" fn rename(old: &const u8, new: &const u8) -> c_int;
+pub extern "c" fn chdir(path: &const u8) -> c_int;
+pub extern "c" fn execve(path: &const u8, argv: &const ?&const u8,
+    envp: &const ?&const u8) -> c_int;
+pub extern "c" fn dup(fd: c_int) -> c_int;
+pub extern "c" fn dup2(old_fd: c_int, new_fd: c_int) -> c_int;
std/os/child_process.zig
@@ -229,42 +229,15 @@ fn forkChildErrReport(fd: i32, err: error) -> noreturn {
 }
 
 const ErrInt = @IntType(false, @sizeOf(error) * 8);
+
 fn writeIntFd(fd: i32, value: ErrInt) -> %void {
     var bytes: [@sizeOf(ErrInt)]u8 = undefined;
     mem.writeInt(bytes[0..], value, true);
-
-    var index: usize = 0;
-    while (index < bytes.len) {
-        const amt_written = posix.write(fd, &bytes[index], bytes.len - index);
-        const err = posix.getErrno(amt_written);
-        if (err > 0) {
-            switch (err) {
-                errno.EINTR => continue,
-                errno.EINVAL => unreachable,
-                else => return error.SystemResources,
-            }
-        }
-        index += amt_written;
-    }
+    os.posixWrite(fd, bytes[0..]) %% return error.SystemResources;
 }
 
 fn readIntFd(fd: i32) -> %ErrInt {
     var bytes: [@sizeOf(ErrInt)]u8 = undefined;
-
-    var index: usize = 0;
-    while (index < bytes.len) {
-        const amt_written = posix.read(fd, &bytes[index], bytes.len - index);
-        const err = posix.getErrno(amt_written);
-        if (err > 0) {
-            switch (err) {
-                errno.EINTR => continue,
-                errno.EINVAL => unreachable,
-                else => return error.SystemResources,
-            }
-        }
-        index += amt_written;
-    }
-
+    os.posixRead(fd, bytes[0..]) %% return error.SystemResources;
     return mem.readInt(bytes[0..], ErrInt, true);
 }
-
std/os/darwin.zig
@@ -1,18 +1,41 @@
-
-const builtin = @import("builtin");
-const arch = switch (builtin.arch) {
-    builtin.Arch.x86_64 => @import("darwin_x86_64.zig"),
-    else => @compileError("unsupported arch"),
-};
-
-const errno = @import("errno.zig");
+const c = @import("../c/index.zig");
+const assert = @import("../debug.zig").assert;
 
 pub const STDIN_FILENO = 0;
 pub const STDOUT_FILENO = 1;
 pub const STDERR_FILENO = 2;
 
+pub const PROT_NONE   = 0x00; /// [MC2] no permissions
+pub const PROT_READ   = 0x01; /// [MC2] pages can be read
+pub const PROT_WRITE  = 0x02; /// [MC2] pages can be written
+pub const PROT_EXEC   = 0x04; /// [MC2] pages can be executed
+
+pub const MAP_ANONYMOUS = 0x1000; /// allocated from memory, swap space
+pub const MAP_FILE = 0x0000; /// map from file (default)
+pub const MAP_FIXED = 0x0010; /// interpret addr exactly
+pub const MAP_HASSEMAPHORE = 0x0200; /// region may contain semaphores
+pub const MAP_PRIVATE = 0x0002; /// changes are private
+pub const MAP_SHARED = 0x0001; /// share changes
+pub const MAP_NOCACHE = 0x0400; /// don't cache pages for this mapping
+pub const MAP_NORESERVE = 0x0040; /// don't reserve needed swap area
+pub const MAP_FAILED = @maxValue(usize);
+
 pub const O_LARGEFILE = 0x0000;
-pub const O_RDONLY = 0x0000;
+
+pub const O_RDONLY   = 0x0000; /// open for reading only
+pub const O_WRONLY   = 0x0001; /// open for writing only
+pub const O_RDWR     = 0x0002; /// open for reading and writing
+pub const O_NONBLOCK = 0x0004; /// do not block on open or for data to become available
+pub const O_APPEND   = 0x0008; /// append on each write
+pub const O_CREAT    = 0x0200; /// create file if it does not exist
+pub const O_TRUNC    = 0x0400; /// truncate size to 0
+pub const O_EXCL     = 0x0800; /// error if O_CREAT and the file exists
+pub const O_SHLOCK   = 0x0010; /// atomically obtain a shared lock
+pub const O_EXLOCK   = 0x0020; /// atomically obtain an exclusive lock
+pub const O_NOFOLLOW = 0x0100; /// do not follow symlinks
+pub const O_SYMLINK  = 0x200000; /// allow open of symlinks
+pub const O_EVTONLY  = 0x8000; /// descriptor requested for event notifications only
+pub const O_CLOEXEC  = 0x1000000; /// mark as close-on-exec
 
 pub const SEEK_SET = 0x0;
 pub const SEEK_CUR = 0x1;
@@ -53,64 +76,133 @@ pub const SIGPWR    = 30;
 pub const SIGSYS    = 31;
 pub const SIGUNUSED = SIGSYS;
 
-pub fn exit(status: usize) -> noreturn {
-    _ = arch.syscall1(arch.SYS_exit, status);
-    unreachable
-}
+fn wstatus(x: i32) -> i32 { x & 0o177 }
+const wstopped = 0o177;
+pub fn WEXITSTATUS(x: i32) -> i32 { x >> 8 }
+pub fn WTERMSIG(x: i32) -> i32 { wstatus(x) }
+pub fn WSTOPSIG(x: i32) -> i32 { x >> 8 }
+pub fn WIFEXITED(x: i32) -> bool { wstatus(x) == 0 }
+pub fn WIFSTOPPED(x: i32) -> bool { wstatus(x) == wstopped and WSTOPSIG(x) != 0x13 }
+pub fn WIFSIGNALED(x: i32) -> bool { wstatus(x) != wstopped and wstatus(x) != 0 }
 
 /// Get the errno from a syscall return value, or 0 for no error.
 pub fn getErrno(r: usize) -> usize {
-    const signed_r = *@ptrCast(&const isize, &r);
+    const signed_r = @bitCast(isize, r);
     if (signed_r > -4096 and signed_r < 0) usize(-signed_r) else 0
 }
 
-pub fn write(fd: i32, buf: &const u8, count: usize) -> usize {
-    arch.syscall3(arch.SYS_write, usize(fd), usize(buf), count)
+pub fn close(fd: i32) -> usize {
+    errnoWrap(c.close(fd))
 }
 
-pub fn close(fd: i32) -> usize {
-    arch.syscall1(arch.SYS_close, usize(fd))
+pub fn abort() -> noreturn {
+    c.abort()
+}
+
+pub fn exit(code: i32) -> noreturn {
+    c.exit(code)
+}
+
+pub fn isatty(fd: i32) -> bool {
+    c.isatty(fd) == 0
+}
+
+pub fn fstat(fd: i32, buf: &c.stat) -> usize {
+    errnoWrap(c.fstat(fd, buf))
+}
+
+pub fn lseek(fd: i32, offset: isize, whence: c_int) -> usize {
+    errnoWrap(c.lseek(fd, buf, whence))
+}
+
+pub fn open(path: &const u8, flags: u32, mode: usize) -> usize {
+    errnoWrap(c.open(path, @bitCast(c_int, flags), mode))
+}
+
+pub fn raise(sig: i32) -> usize {
+    errnoWrap(c.raise(sig))
+}
+
+pub fn read(fd: i32, buf: &u8, nbyte: usize) -> usize {
+    errnoWrap(c.read(fd, @ptrCast(&c_void, buf), nbyte))
+}
+
+pub fn stat(noalias path: &const u8, noalias buf: &stat) -> usize {
+    errnoWrap(c.stat(path, buf))
+}
+
+pub fn write(fd: i32, buf: &const u8, nbyte: usize) -> usize {
+    errnoWrap(c.write(fd, @ptrCast(&const c_void, buf), nbyte))
+}
+
+pub fn mmap(address: ?&u8, length: usize, prot: usize, flags: usize, fd: i32,
+    offset: isize) -> usize
+{
+    const ptr_result = c.mmap(@ptrCast(&c_void, address), length,
+        @bitCast(c_int, c_uint(prot)), @bitCast(c_int, c_uint(flags)), fd, offset);
+    const isize_result = @bitCast(isize, @ptrToInt(ptr_result));
+    return errnoWrap(isize_result);
 }
 
-pub fn open(path: &const u8, flags: usize, perm: usize) -> usize {
-    arch.syscall3(arch.SYS_open, usize(path), flags, perm)
+pub fn munmap(address: &u8, length: usize) -> usize {
+    errnoWrap(c.munmap(@ptrCast(&c_void, address), length))
 }
 
-pub fn read(fd: i32, buf: &u8, count: usize) -> usize {
-    arch.syscall3(arch.SYS_read, usize(fd), usize(buf), count)
+pub fn unlink(path: &const u8) -> usize {
+    errnoWrap(c.unlink(path))
 }
 
-pub fn lseek(fd: i32, offset: usize, ref_pos: usize) -> usize {
-    arch.syscall3(arch.SYS_lseek, usize(fd), offset, ref_pos)
+pub fn getcwd(buf: &u8, size: usize) -> usize {
+    if (c.getcwd(buf, size) == null) @bitCast(usize, -isize(*c._errno())) else 0
 }
 
-pub const stat = arch.stat;
-pub const timespec = arch.timespec;
+pub fn waitpid(pid: i32, status: &i32, options: u32) -> usize {
+    comptime assert(i32.bit_count == c_int.bit_count);
+    errnoWrap(c.waitpid(pid, @ptrCast(&c_int, status), @bitCast(c_int, options)))
+}
 
-pub fn fstat(fd: i32, stat_buf: &stat) -> usize {
-    arch.syscall2(arch.SYS_fstat, usize(fd), usize(stat_buf))
+pub fn fork() -> usize {
+    errnoWrap(c.fork())
 }
 
-error Unexpected;
+pub fn pipe(fds: &[2]i32) -> usize {
+    comptime assert(i32.bit_count == c_int.bit_count);
+    errnoWrap(c.pipe(@ptrCast(&c_int, &(*fds)[0])))
+}
 
-pub fn getrandom(buf: &u8, count: usize) -> usize {
-    const rr = open_c(c"/dev/urandom", O_LARGEFILE | O_RDONLY, 0);
+pub fn mkdir(path: &const u8, mode: u32) -> usize {
+    errnoWrap(c.mkdir(path, mode))
+}
 
-    if(getErrno(rr) > 0) return rr;
+pub fn symlink(existing: &const u8, new: &const u8) -> usize {
+    errnoWrap(c.symlink(existing, new))
+}
 
-    var fd: i32 = i32(rr);
-    const readRes = read(fd, buf, count);
-    readRes
+pub fn rename(old: &const u8, new: &const u8) -> usize {
+    errnoWrap(c.rename(old, new))
 }
 
-pub fn raise(sig: i32) -> i32 {
-    // TODO investigate whether we need to block signals before calling kill
-    // like we do in the linux version of raise
+pub fn chdir(path: &const u8) -> usize {
+    errnoWrap(c.chdir(path))
+}
+
+pub fn execve(path: &const u8, argv: &const ?&const u8, envp: &const ?&const u8)
+    -> usize
+{
+    errnoWrap(c.execve(path, argv, envp))
+}
+
+pub fn dup2(old: i32, new: i32) -> usize {
+    errnoWrap(c.dup2(old, new))
+}
 
-    //var set: sigset_t = undefined;
-    //blockAppSignals(&set);
-    const pid = i32(arch.syscall0(arch.SYS_getpid));
-    const ret = i32(arch.syscall2(arch.SYS_kill, usize(pid), usize(sig)));
-    //restoreSignals(&set);
-    return ret;
+/// Takes the return value from a syscall and formats it back in the way
+/// that the kernel represents it to libc. Errno was a mistake, let's make
+/// it go away forever.
+fn errnoWrap(value: isize) -> usize {
+    @bitCast(usize, if (value == -1) {
+        -isize(*c._errno())
+    } else {
+        value
+    })
 }
std/os/darwin_x86_64.zig
@@ -1,87 +0,0 @@
-
-pub const SYSCALL_CLASS_SHIFT = 24;
-pub const SYSCALL_CLASS_MASK = 0xFF << SYSCALL_CLASS_SHIFT;
-// pub const SYSCALL_NUMBER_MASK = ~SYSCALL_CLASS_MASK; // ~ modifier not supported yet
-
-pub const SYSCALL_CLASS_NONE = 0; // Invalid
-pub const SYSCALL_CLASS_MACH = 1; // Mach
-pub const SYSCALL_CLASS_UNIX = 2; // Unix/BSD
-pub const SYSCALL_CLASS_MDEP = 3; // Machine-dependent
-pub const SYSCALL_CLASS_DIAG = 4; // Diagnostics
-
-// TODO: use the above constants to create the below values
-
-pub const SYS_exit = 0x2000001;
-pub const SYS_read = 0x2000003;
-pub const SYS_write = 0x2000004;
-pub const SYS_open = 0x2000005;
-pub const SYS_close = 0x2000006;
-pub const SYS_kill = 0x2000025;
-pub const SYS_getpid = 0x2000030;
-pub const SYS_fstat = 0x20000BD;
-pub const SYS_lseek = 0x20000C7;
-
-pub inline fn syscall0(number: usize) -> usize {
-    asm volatile ("syscall"
-        : [ret] "={rax}" (-> usize)
-        : [number] "{rax}" (number)
-        : "rcx", "r11")
-}
-
-pub inline fn syscall1(number: usize, arg1: usize) -> usize {
-    asm volatile ("syscall"
-        : [ret] "={rax}" (-> usize)
-        : [number] "{rax}" (number),
-            [arg1] "{rdi}" (arg1)
-        : "rcx", "r11")
-}
-
-pub inline fn syscall2(number: usize, arg1: usize, arg2: usize) -> usize {
-    asm volatile ("syscall"
-        : [ret] "={rax}" (-> usize)
-        : [number] "{rax}" (number),
-            [arg1] "{rdi}" (arg1),
-            [arg2] "{rsi}" (arg2)
-        : "rcx", "r11")
-}
-
-pub inline fn syscall3(number: usize, arg1: usize, arg2: usize, arg3: usize) -> usize {
-    asm volatile ("syscall"
-        : [ret] "={rax}" (-> usize)
-        : [number] "{rax}" (number),
-            [arg1] "{rdi}" (arg1),
-            [arg2] "{rsi}" (arg2),
-            [arg3] "{rdx}" (arg3)
-        : "rcx", "r11")
-}
-
-
-
-
-pub const stat = extern struct {
-    dev: u32,
-    mode: u16,
-    nlink: u16,
-    ino: u64,
-    uid: u32,
-    gid: u32,
-    rdev: u64,
-
-    atim: timespec,
-    mtim: timespec,
-    ctim: timespec,
-
-    size: u64,
-    blocks: u64,
-    blksize: u32,
-    flags: u32,
-    gen: u32,
-    lspare: i32,
-    qspare: [2]u64,
-
-};
-
-pub const timespec = extern struct {
-    tv_sec: isize,
-    tv_nsec: isize,
-};
std/os/errno.zig
@@ -1,146 +1,146 @@
-pub const EPERM = 1; // Operation not permitted
-pub const ENOENT = 2; // No such file or directory
-pub const ESRCH = 3; // No such process
-pub const EINTR = 4; // Interrupted system call
-pub const EIO = 5; // I/O error
-pub const ENXIO = 6; // No such device or address
-pub const E2BIG = 7; // Arg list too long
-pub const ENOEXEC = 8; // Exec format error
-pub const EBADF = 9; // Bad file number
-pub const ECHILD = 10; // No child processes
-pub const EAGAIN = 11; // Try again
-pub const ENOMEM = 12; // Out of memory
-pub const EACCES = 13; // Permission denied
-pub const EFAULT = 14; // Bad address
-pub const ENOTBLK = 15; // Block device required
-pub const EBUSY = 16; // Device or resource busy
-pub const EEXIST = 17; // File exists
-pub const EXDEV = 18; // Cross-device link
-pub const ENODEV = 19; // No such device
-pub const ENOTDIR = 20; // Not a directory
-pub const EISDIR = 21; // Is a directory
-pub const EINVAL = 22; // Invalid argument
-pub const ENFILE = 23; // File table overflow
-pub const EMFILE = 24; // Too many open files
-pub const ENOTTY = 25; // Not a typewriter
-pub const ETXTBSY = 26; // Text file busy
-pub const EFBIG = 27; // File too large
-pub const ENOSPC = 28; // No space left on device
-pub const ESPIPE = 29; // Illegal seek
-pub const EROFS = 30; // Read-only file system
-pub const EMLINK = 31; // Too many links
-pub const EPIPE = 32; // Broken pipe
-pub const EDOM = 33; // Math argument out of domain of func
-pub const ERANGE = 34; // Math result not representable
-pub const EDEADLK = 35; // Resource deadlock would occur
-pub const ENAMETOOLONG = 36; // File name too long
-pub const ENOLCK = 37; // No record locks available
-pub const ENOSYS = 38; // Function not implemented
-pub const ENOTEMPTY = 39; // Directory not empty
-pub const ELOOP = 40; // Too many symbolic links encountered
-pub const EWOULDBLOCK = EAGAIN; // Operation would block
-pub const ENOMSG = 42; // No message of desired type
-pub const EIDRM = 43; // Identifier removed
-pub const ECHRNG = 44; // Channel number out of range
-pub const EL2NSYNC = 45; // Level 2 not synchronized
-pub const EL3HLT = 46; // Level 3 halted
-pub const EL3RST = 47; // Level 3 reset
-pub const ELNRNG = 48; // Link number out of range
-pub const EUNATCH = 49; // Protocol driver not attached
-pub const ENOCSI = 50; // No CSI structure available
-pub const EL2HLT = 51; // Level 2 halted
-pub const EBADE = 52; // Invalid exchange
-pub const EBADR = 53; // Invalid request descriptor
-pub const EXFULL = 54; // Exchange full
-pub const ENOANO = 55; // No anode
-pub const EBADRQC = 56; // Invalid request code
-pub const EBADSLT = 57; // Invalid slot
+pub const EPERM = 1; /// Operation not permitted
+pub const ENOENT = 2; /// No such file or directory
+pub const ESRCH = 3; /// No such process
+pub const EINTR = 4; /// Interrupted system call
+pub const EIO = 5; /// I/O error
+pub const ENXIO = 6; /// No such device or address
+pub const E2BIG = 7; /// Arg list too long
+pub const ENOEXEC = 8; /// Exec format error
+pub const EBADF = 9; /// Bad file number
+pub const ECHILD = 10; /// No child processes
+pub const EAGAIN = 11; /// Try again
+pub const ENOMEM = 12; /// Out of memory
+pub const EACCES = 13; /// Permission denied
+pub const EFAULT = 14; /// Bad address
+pub const ENOTBLK = 15; /// Block device required
+pub const EBUSY = 16; /// Device or resource busy
+pub const EEXIST = 17; /// File exists
+pub const EXDEV = 18; /// Cross-device link
+pub const ENODEV = 19; /// No such device
+pub const ENOTDIR = 20; /// Not a directory
+pub const EISDIR = 21; /// Is a directory
+pub const EINVAL = 22; /// Invalid argument
+pub const ENFILE = 23; /// File table overflow
+pub const EMFILE = 24; /// Too many open files
+pub const ENOTTY = 25; /// Not a typewriter
+pub const ETXTBSY = 26; /// Text file busy
+pub const EFBIG = 27; /// File too large
+pub const ENOSPC = 28; /// No space left on device
+pub const ESPIPE = 29; /// Illegal seek
+pub const EROFS = 30; /// Read-only file system
+pub const EMLINK = 31; /// Too many links
+pub const EPIPE = 32; /// Broken pipe
+pub const EDOM = 33; /// Math argument out of domain of func
+pub const ERANGE = 34; /// Math result not representable
+pub const EDEADLK = 35; /// Resource deadlock would occur
+pub const ENAMETOOLONG = 36; /// File name too long
+pub const ENOLCK = 37; /// No record locks available
+pub const ENOSYS = 38; /// Function not implemented
+pub const ENOTEMPTY = 39; /// Directory not empty
+pub const ELOOP = 40; /// Too many symbolic links encountered
+pub const EWOULDBLOCK = EAGAIN; /// Operation would block
+pub const ENOMSG = 42; /// No message of desired type
+pub const EIDRM = 43; /// Identifier removed
+pub const ECHRNG = 44; /// Channel number out of range
+pub const EL2NSYNC = 45; /// Level 2 not synchronized
+pub const EL3HLT = 46; /// Level 3 halted
+pub const EL3RST = 47; /// Level 3 reset
+pub const ELNRNG = 48; /// Link number out of range
+pub const EUNATCH = 49; /// Protocol driver not attached
+pub const ENOCSI = 50; /// No CSI structure available
+pub const EL2HLT = 51; /// Level 2 halted
+pub const EBADE = 52; /// Invalid exchange
+pub const EBADR = 53; /// Invalid request descriptor
+pub const EXFULL = 54; /// Exchange full
+pub const ENOANO = 55; /// No anode
+pub const EBADRQC = 56; /// Invalid request code
+pub const EBADSLT = 57; /// Invalid slot
 
-pub const EBFONT = 59; // Bad font file format
-pub const ENOSTR = 60; // Device not a stream
-pub const ENODATA = 61; // No data available
-pub const ETIME = 62; // Timer expired
-pub const ENOSR = 63; // Out of streams resources
-pub const ENONET = 64; // Machine is not on the network
-pub const ENOPKG = 65; // Package not installed
-pub const EREMOTE = 66; // Object is remote
-pub const ENOLINK = 67; // Link has been severed
-pub const EADV = 68; // Advertise error
-pub const ESRMNT = 69; // Srmount error
-pub const ECOMM = 70; // Communication error on send
-pub const EPROTO = 71; // Protocol error
-pub const EMULTIHOP = 72; // Multihop attempted
-pub const EDOTDOT = 73; // RFS specific error
-pub const EBADMSG = 74; // Not a data message
-pub const EOVERFLOW = 75; // Value too large for defined data type
-pub const ENOTUNIQ = 76; // Name not unique on network
-pub const EBADFD = 77; // File descriptor in bad state
-pub const EREMCHG = 78; // Remote address changed
-pub const ELIBACC = 79; // Can not access a needed shared library
-pub const ELIBBAD = 80; // Accessing a corrupted shared library
-pub const ELIBSCN = 81; // .lib section in a.out corrupted
-pub const ELIBMAX = 82; // Attempting to link in too many shared libraries
-pub const ELIBEXEC = 83; // Cannot exec a shared library directly
-pub const EILSEQ = 84; // Illegal byte sequence
-pub const ERESTART = 85; // Interrupted system call should be restarted
-pub const ESTRPIPE = 86; // Streams pipe error
-pub const EUSERS = 87; // Too many users
-pub const ENOTSOCK = 88; // Socket operation on non-socket
-pub const EDESTADDRREQ = 89; // Destination address required
-pub const EMSGSIZE = 90; // Message too long
-pub const EPROTOTYPE = 91; // Protocol wrong type for socket
-pub const ENOPROTOOPT = 92; // Protocol not available
-pub const EPROTONOSUPPORT = 93; // Protocol not supported
-pub const ESOCKTNOSUPPORT = 94; // Socket type not supported
-pub const EOPNOTSUPP = 95; // Operation not supported on transport endpoint
-pub const EPFNOSUPPORT = 96; // Protocol family not supported
-pub const EAFNOSUPPORT = 97; // Address family not supported by protocol
-pub const EADDRINUSE = 98; // Address already in use
-pub const EADDRNOTAVAIL = 99; // Cannot assign requested address
-pub const ENETDOWN = 100; // Network is down
-pub const ENETUNREACH = 101; // Network is unreachable
-pub const ENETRESET = 102; // Network dropped connection because of reset
-pub const ECONNABORTED = 103; // Software caused connection abort
-pub const ECONNRESET = 104; // Connection reset by peer
-pub const ENOBUFS = 105; // No buffer space available
-pub const EISCONN = 106; // Transport endpoint is already connected
-pub const ENOTCONN = 107; // Transport endpoint is not connected
-pub const ESHUTDOWN = 108; // Cannot send after transport endpoint shutdown
-pub const ETOOMANYREFS = 109; // Too many references: cannot splice
-pub const ETIMEDOUT = 110; // Connection timed out
-pub const ECONNREFUSED = 111; // Connection refused
-pub const EHOSTDOWN = 112; // Host is down
-pub const EHOSTUNREACH = 113; // No route to host
-pub const EALREADY = 114; // Operation already in progress
-pub const EINPROGRESS = 115; // Operation now in progress
-pub const ESTALE = 116; // Stale NFS file handle
-pub const EUCLEAN = 117; // Structure needs cleaning
-pub const ENOTNAM = 118; // Not a XENIX named type file
-pub const ENAVAIL = 119; // No XENIX semaphores available
-pub const EISNAM = 120; // Is a named type file
-pub const EREMOTEIO = 121; // Remote I/O error
-pub const EDQUOT = 122; // Quota exceeded
+pub const EBFONT = 59; /// Bad font file format
+pub const ENOSTR = 60; /// Device not a stream
+pub const ENODATA = 61; /// No data available
+pub const ETIME = 62; /// Timer expired
+pub const ENOSR = 63; /// Out of streams resources
+pub const ENONET = 64; /// Machine is not on the network
+pub const ENOPKG = 65; /// Package not installed
+pub const EREMOTE = 66; /// Object is remote
+pub const ENOLINK = 67; /// Link has been severed
+pub const EADV = 68; /// Advertise error
+pub const ESRMNT = 69; /// Srmount error
+pub const ECOMM = 70; /// Communication error on send
+pub const EPROTO = 71; /// Protocol error
+pub const EMULTIHOP = 72; /// Multihop attempted
+pub const EDOTDOT = 73; /// RFS specific error
+pub const EBADMSG = 74; /// Not a data message
+pub const EOVERFLOW = 75; /// Value too large for defined data type
+pub const ENOTUNIQ = 76; /// Name not unique on network
+pub const EBADFD = 77; /// File descriptor in bad state
+pub const EREMCHG = 78; /// Remote address changed
+pub const ELIBACC = 79; /// Can not access a needed shared library
+pub const ELIBBAD = 80; /// Accessing a corrupted shared library
+pub const ELIBSCN = 81; /// .lib section in a.out corrupted
+pub const ELIBMAX = 82; /// Attempting to link in too many shared libraries
+pub const ELIBEXEC = 83; /// Cannot exec a shared library directly
+pub const EILSEQ = 84; /// Illegal byte sequence
+pub const ERESTART = 85; /// Interrupted system call should be restarted
+pub const ESTRPIPE = 86; /// Streams pipe error
+pub const EUSERS = 87; /// Too many users
+pub const ENOTSOCK = 88; /// Socket operation on non-socket
+pub const EDESTADDRREQ = 89; /// Destination address required
+pub const EMSGSIZE = 90; /// Message too long
+pub const EPROTOTYPE = 91; /// Protocol wrong type for socket
+pub const ENOPROTOOPT = 92; /// Protocol not available
+pub const EPROTONOSUPPORT = 93; /// Protocol not supported
+pub const ESOCKTNOSUPPORT = 94; /// Socket type not supported
+pub const EOPNOTSUPP = 95; /// Operation not supported on transport endpoint
+pub const EPFNOSUPPORT = 96; /// Protocol family not supported
+pub const EAFNOSUPPORT = 97; /// Address family not supported by protocol
+pub const EADDRINUSE = 98; /// Address already in use
+pub const EADDRNOTAVAIL = 99; /// Cannot assign requested address
+pub const ENETDOWN = 100; /// Network is down
+pub const ENETUNREACH = 101; /// Network is unreachable
+pub const ENETRESET = 102; /// Network dropped connection because of reset
+pub const ECONNABORTED = 103; /// Software caused connection abort
+pub const ECONNRESET = 104; /// Connection reset by peer
+pub const ENOBUFS = 105; /// No buffer space available
+pub const EISCONN = 106; /// Transport endpoint is already connected
+pub const ENOTCONN = 107; /// Transport endpoint is not connected
+pub const ESHUTDOWN = 108; /// Cannot send after transport endpoint shutdown
+pub const ETOOMANYREFS = 109; /// Too many references: cannot splice
+pub const ETIMEDOUT = 110; /// Connection timed out
+pub const ECONNREFUSED = 111; /// Connection refused
+pub const EHOSTDOWN = 112; /// Host is down
+pub const EHOSTUNREACH = 113; /// No route to host
+pub const EALREADY = 114; /// Operation already in progress
+pub const EINPROGRESS = 115; /// Operation now in progress
+pub const ESTALE = 116; /// Stale NFS file handle
+pub const EUCLEAN = 117; /// Structure needs cleaning
+pub const ENOTNAM = 118; /// Not a XENIX named type file
+pub const ENAVAIL = 119; /// No XENIX semaphores available
+pub const EISNAM = 120; /// Is a named type file
+pub const EREMOTEIO = 121; /// Remote I/O error
+pub const EDQUOT = 122; /// Quota exceeded
 
-pub const ENOMEDIUM = 123; // No medium found
-pub const EMEDIUMTYPE = 124; // Wrong medium type
+pub const ENOMEDIUM = 123; /// No medium found
+pub const EMEDIUMTYPE = 124; /// Wrong medium type
 
 // nameserver query return codes
-pub const ENSROK = 0; // DNS server returned answer with no data
-pub const ENSRNODATA = 160; // DNS server returned answer with no data
-pub const ENSRFORMERR = 161; // DNS server claims query was misformatted
-pub const ENSRSERVFAIL = 162; // DNS server returned general failure
-pub const ENSRNOTFOUND = 163; // Domain name not found
-pub const ENSRNOTIMP = 164; // DNS server does not implement requested operation
-pub const ENSRREFUSED = 165; // DNS server refused query
-pub const ENSRBADQUERY = 166; // Misformatted DNS query
-pub const ENSRBADNAME = 167; // Misformatted domain name
-pub const ENSRBADFAMILY = 168; // Unsupported address family
-pub const ENSRBADRESP = 169; // Misformatted DNS reply
-pub const ENSRCONNREFUSED = 170; // Could not contact DNS servers
-pub const ENSRTIMEOUT = 171; // Timeout while contacting DNS servers
-pub const ENSROF = 172; // End of file
-pub const ENSRFILE = 173; // Error reading file
-pub const ENSRNOMEM = 174; // Out of memory
-pub const ENSRDESTRUCTION = 175; // Application terminated lookup
-pub const ENSRQUERYDOMAINTOOLONG = 176; // Domain name is too long
-pub const ENSRCNAMELOOP = 177; // Domain name is too long
+pub const ENSROK = 0; /// DNS server returned answer with no data
+pub const ENSRNODATA = 160; /// DNS server returned answer with no data
+pub const ENSRFORMERR = 161; /// DNS server claims query was misformatted
+pub const ENSRSERVFAIL = 162; /// DNS server returned general failure
+pub const ENSRNOTFOUND = 163; /// Domain name not found
+pub const ENSRNOTIMP = 164; /// DNS server does not implement requested operation
+pub const ENSRREFUSED = 165; /// DNS server refused query
+pub const ENSRBADQUERY = 166; /// Misformatted DNS query
+pub const ENSRBADNAME = 167; /// Misformatted domain name
+pub const ENSRBADFAMILY = 168; /// Unsupported address family
+pub const ENSRBADRESP = 169; /// Misformatted DNS reply
+pub const ENSRCONNREFUSED = 170; /// Could not contact DNS servers
+pub const ENSRTIMEOUT = 171; /// Timeout while contacting DNS servers
+pub const ENSROF = 172; /// End of file
+pub const ENSRFILE = 173; /// Error reading file
+pub const ENSRNOMEM = 174; /// Out of memory
+pub const ENSRDESTRUCTION = 175; /// Application terminated lookup
+pub const ENSRQUERYDOMAINTOOLONG = 176; /// Domain name is too long
+pub const ENSRCNAMELOOP = 177; /// Domain name is too long
std/os/index.zig
@@ -56,43 +56,40 @@ error WouldBlock;
 /// appropriate OS-specific library call. Otherwise it uses the zig standard
 /// library implementation.
 pub fn getRandomBytes(buf: []u8) -> %void {
-    while (true) {
-        const err = switch (builtin.os) {
-            Os.linux => {
-                // TODO check libc version and potentially call c.getrandom.
-                // See #397
-                posix.getErrno(posix.getrandom(buf.ptr, buf.len, 0))
-            },
-            Os.darwin, Os.macosx, Os.ios => {
-                if (builtin.link_libc) {
-                    if (posix.getrandom(buf.ptr, buf.len) == -1) *c._errno() else 0
-                } else {
-                    posix.getErrno(posix.getrandom(buf.ptr, buf.len))
-                }
-            },
-            Os.windows => {
-                var hCryptProv: windows.HCRYPTPROV = undefined;
-                if (!windows.CryptAcquireContext(&hCryptProv, null, null, windows.PROV_RSA_FULL, 0)) {
-                    return error.Unexpected;
+    switch (builtin.os) {
+        Os.linux => while (true) {
+            // TODO check libc version and potentially call c.getrandom.
+            // See #397
+            const err = posix.getErrno(posix.getrandom(buf.ptr, buf.len, 0));
+            if (err > 0) {
+                return switch (err) {
+                    errno.EINVAL => unreachable,
+                    errno.EFAULT => unreachable,
+                    errno.EINTR  => continue,
+                    else         => error.Unexpected,
                 }
-                defer _ = windows.CryptReleaseContext(hCryptProv, 0);
+            }
+            return;
+        },
+        Os.darwin, Os.macosx, Os.ios => {
+            const fd = %return posixOpen("/dev/urandom", posix.O_RDONLY|posix.O_CLOEXEC,
+                0, null);
+            defer posixClose(fd);
 
-                if (!windows.CryptGenRandom(hCryptProv, windows.DWORD(buf.len), buf.ptr)) {
-                    return error.Unexpected;
-                }
-                return;
-            },
-            else => @compileError("Unsupported OS"),
-        };
-        if (err > 0) {
-            return switch (err) {
-                errno.EINVAL => unreachable,
-                errno.EFAULT => unreachable,
-                errno.EINTR  => continue,
-                else         => error.Unexpected,
+            %return posixRead(fd, buf);
+        },
+        Os.windows => {
+            var hCryptProv: windows.HCRYPTPROV = undefined;
+            if (!windows.CryptAcquireContext(&hCryptProv, null, null, windows.PROV_RSA_FULL, 0)) {
+                return error.Unexpected;
             }
-        }
-        return;
+            defer _ = windows.CryptReleaseContext(hCryptProv, 0);
+
+            if (!windows.CryptGenRandom(hCryptProv, windows.DWORD(buf.len), buf.ptr)) {
+                return error.Unexpected;
+            }
+        },
+        else => @compileError("Unsupported OS"),
     }
 }
 
@@ -128,12 +125,34 @@ pub fn posixClose(fd: i32) {
     }
 }
 
+/// Calls POSIX read, and keeps trying if it gets interrupted.
+pub fn posixRead(fd: i32, buf: []u8) -> %void {
+    var index: usize = 0;
+    while (index < buf.len) {
+        const amt_written = posix.read(fd, &buf[index], buf.len - index);
+        const err = posix.getErrno(amt_written);
+        if (err > 0) {
+            return switch (err) {
+                errno.EINTR => continue,
+                errno.EINVAL, errno.EFAULT => unreachable,
+                errno.EAGAIN => error.WouldBlock,
+                errno.EBADF => error.FileClosed,
+                errno.EIO => error.InputOutput,
+                errno.EISDIR => error.IsDir,
+                errno.ENOBUFS, errno.ENOMEM => error.SystemResources,
+                else => return error.Unexpected,
+            }
+        }
+        index += amt_written;
+    }
+}
+
 error WouldBlock;
 error FileClosed;
 error DestinationAddressRequired;
 error DiskQuota;
 error FileTooBig;
-error FileSystem;
+error InputOutput;
 error NoSpaceLeft;
 error BrokenPipe;
 error Unexpected;
@@ -152,7 +171,7 @@ pub fn posixWrite(fd: i32, bytes: []const u8) -> %void {
                 errno.EDESTADDRREQ => error.DestinationAddressRequired,
                 errno.EDQUOT => error.DiskQuota,
                 errno.EFBIG  => error.FileTooBig,
-                errno.EIO    => error.FileSystem,
+                errno.EIO    => error.InputOutput,
                 errno.ENOSPC => error.NoSpaceLeft,
                 errno.EPERM  => error.AccessDenied,
                 errno.EPIPE  => error.BrokenPipe,
@@ -213,7 +232,7 @@ pub fn windowsIsCygwinPty(handle: windows.HANDLE) -> bool {
 /// otherwise if the fixed size buffer is too small, allocator is used to obtain the needed memory.
 /// Calls POSIX open, keeps trying if it gets interrupted, and translates
 /// the return value into zig errors.
-pub fn posixOpen(file_path: []const u8, flags: usize, perm: usize, allocator: ?&Allocator) -> %i32 {
+pub fn posixOpen(file_path: []const u8, flags: u32, perm: usize, allocator: ?&Allocator) -> %i32 {
     var stack_buf: [max_noalloc_path_len]u8 = undefined;
     var path0: []u8 = undefined;
     var need_free = false;
std/os/linux.zig
@@ -309,8 +309,8 @@ pub const TIOCGPKT = 0x80045438;
 pub const TIOCGPTLCK = 0x80045439;
 pub const TIOCGEXCL = 0x80045440;
 
-fn unsigned(s: i32) -> u32 { *@ptrCast(&u32, &s) }
-fn signed(s: u32) -> i32 { *@ptrCast(&i32, &s) }
+fn unsigned(s: i32) -> u32 { @bitCast(u32, s) }
+fn signed(s: u32) -> i32 { @bitCast(i32, s) }
 pub fn WEXITSTATUS(s: i32) -> i32 { signed((unsigned(s) & 0xff00) >> 8) }
 pub fn WTERMSIG(s: i32) -> i32 { signed(unsigned(s) & 0x7f) }
 pub fn WSTOPSIG(s: i32) -> i32 { WEXITSTATUS(s) }
@@ -328,7 +328,7 @@ pub const winsize = extern struct {
 
 /// Get the errno from a syscall return value, or 0 for no error.
 pub fn getErrno(r: usize) -> usize {
-    const signed_r = *@ptrCast(&const isize, &r);
+    const signed_r = @bitCast(isize, r);
     if (signed_r > -4096 and signed_r < 0) usize(-signed_r) else 0
 }
 
@@ -353,7 +353,7 @@ pub fn getcwd(buf: &u8, size: usize) -> usize {
 }
 
 pub fn getdents(fd: i32, dirp: &u8, count: usize) -> usize {
-    arch.syscall3(arch.SYS_getdents, usize(fd), @ptrToInt(dirp), usize(count))
+    arch.syscall3(arch.SYS_getdents, usize(fd), @ptrToInt(dirp), count)
 }
 
 pub fn isatty(fd: i32) -> bool {
@@ -365,14 +365,15 @@ pub fn readlink(noalias path: &const u8, noalias buf_ptr: &u8, buf_len: usize) -
     arch.syscall3(arch.SYS_readlink, @ptrToInt(path), @ptrToInt(buf_ptr), buf_len)
 }
 
-pub fn mkdir(path: &const u8, mode: usize) -> usize {
+pub fn mkdir(path: &const u8, mode: u32) -> usize {
     arch.syscall2(arch.SYS_mkdir, @ptrToInt(path), mode)
 }
 
-pub fn mmap(address: ?&u8, length: usize, prot: usize, flags: usize, fd: i32, offset: usize)
+pub fn mmap(address: ?&u8, length: usize, prot: usize, flags: usize, fd: i32, offset: isize)
     -> usize
 {
-    arch.syscall6(arch.SYS_mmap, @ptrToInt(address), length, prot, flags, usize(fd), offset)
+    arch.syscall6(arch.SYS_mmap, @ptrToInt(address), length, prot, flags, usize(fd),
+        @bitCast(usize, offset))
 }
 
 pub fn munmap(address: &u8, length: usize) -> usize {
@@ -415,7 +416,7 @@ pub fn rename(old: &const u8, new: &const u8) -> usize {
     arch.syscall2(arch.SYS_rename, @ptrToInt(old), @ptrToInt(new))
 }
 
-pub fn open(path: &const u8, flags: usize, perm: usize) -> usize {
+pub fn open(path: &const u8, flags: u32, perm: usize) -> usize {
     arch.syscall3(arch.SYS_open, @ptrToInt(path), flags, perm)
 }
 
@@ -431,12 +432,12 @@ pub fn close(fd: i32) -> usize {
     arch.syscall1(arch.SYS_close, usize(fd))
 }
 
-pub fn lseek(fd: i32, offset: usize, ref_pos: usize) -> usize {
-    arch.syscall3(arch.SYS_lseek, usize(fd), offset, ref_pos)
+pub fn lseek(fd: i32, offset: isize, ref_pos: usize) -> usize {
+    arch.syscall3(arch.SYS_lseek, usize(fd), @bitCast(usize, offset), ref_pos)
 }
 
 pub fn exit(status: i32) -> noreturn {
-    _ = arch.syscall1(arch.SYS_exit, usize(status));
+    _ = arch.syscall1(arch.SYS_exit, @bitCast(usize, isize(status)));
     unreachable
 }
 
@@ -453,7 +454,7 @@ pub fn unlink(path: &const u8) -> usize {
 }
 
 pub fn waitpid(pid: i32, status: &i32, options: i32) -> usize {
-    arch.syscall4(arch.SYS_wait4, usize(pid), @ptrToInt(status), usize(options), 0)
+    arch.syscall4(arch.SYS_wait4, usize(pid), @ptrToInt(status), @bitCast(usize, isize(options)), 0)
 }
 
 const NSIG = 65;
@@ -461,11 +462,11 @@ const sigset_t = [128]u8;
 const all_mask = []u8 { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, };
 const app_mask = []u8 { 0xff, 0xff, 0xff, 0xfc, 0x7f, 0xff, 0xff, 0xff, };
 
-pub fn raise(sig: i32) -> i32 {
+pub fn raise(sig: i32) -> usize {
     var set: sigset_t = undefined;
     blockAppSignals(&set);
     const tid = i32(arch.syscall0(arch.SYS_gettid));
-    const ret = i32(arch.syscall2(arch.SYS_tkill, usize(tid), usize(sig)));
+    const ret = arch.syscall2(arch.SYS_tkill, usize(tid), usize(sig));
     restoreSignals(&set);
     return ret;
 }
@@ -630,9 +631,9 @@ pub fn accept4(fd: i32, noalias addr: &sockaddr, noalias len: &socklen_t, flags:
 //     return ifr.ifr_ifindex;
 // }
 
-pub const stat = arch.stat;
+pub const Stat = arch.Stat;
 pub const timespec = arch.timespec;
 
-pub fn fstat(fd: i32, stat_buf: &stat) -> usize {
+pub fn fstat(fd: i32, stat_buf: &Stat) -> usize {
     arch.syscall2(arch.SYS_fstat, usize(fd), @ptrToInt(stat_buf))
 }
std/os/linux_x86_64.zig
@@ -454,7 +454,8 @@ pub const msghdr = extern struct {
     msg_flags: i32,
 };
 
-pub const stat = extern struct {
+/// Renamed to Stat to not conflict with the stat function.
+pub const Stat = extern struct {
     dev: u64,
     ino: u64,
     nlink: usize,
std/io.zig
@@ -2,10 +2,11 @@ const builtin = @import("builtin");
 const Os = builtin.Os;
 const system = switch(builtin.os) {
     Os.linux => @import("os/linux.zig"),
-    Os.darwin => @import("os/darwin.zig"),
+    Os.darwin, Os.macosx, Os.ios => @import("os/darwin.zig"),
     Os.windows => @import("os/windows/index.zig"),
     else => @compileError("Unsupported OS"),
 };
+const c = @import("c/index.zig");
 
 const errno = @import("os/errno.zig");
 const math = @import("math/index.zig");
@@ -180,7 +181,11 @@ pub const OutStream = struct {
 
     pub fn isTty(self: &OutStream) -> %bool {
         if (is_posix) {
-            return system.isatty(self.fd);
+            if (builtin.link_libc) {
+                return c.isatty(self.fd) == 0;
+            } else {
+                return system.isatty(self.fd);
+            }
         } else if (is_windows) {
             return os.windowsIsTty(%return self.getHandle());
         } else {
@@ -417,7 +422,11 @@ pub const InStream = struct {
 
     pub fn isTty(self: &InStream) -> %bool {
         if (is_posix) {
-            return system.isatty(self.fd);
+            if (builtin.link_libc) {
+                return c.isatty(self.fd) == 0;
+            } else {
+                return system.isatty(self.fd);
+            }
         } else if (is_windows) {
             return os.windowsIsTty(%return self.getHandle());
         } else {
test/cases/asm.zig
@@ -2,7 +2,7 @@ const config = @import("builtin");
 const assert = @import("std").debug.assert;
 
 comptime {
-    if (config.arch == config.Arch.x86_64) {
+    if (config.arch == config.Arch.x86_64 and config.os == config.Os.linux) {
         asm volatile (
             \\.globl aoeu;
             \\.type aoeu, @function;
@@ -12,7 +12,7 @@ comptime {
 }
 
 test "module level assembly" {
-    if (config.arch == config.Arch.x86_64) {
+    if (config.arch == config.Arch.x86_64 and config.os == config.Os.linux) {
         assert(aoeu() == 1234);
     }
 }
CMakeLists.txt
@@ -297,7 +297,6 @@ install(FILES "${CMAKE_SOURCE_DIR}/std/mem.zig" DESTINATION "${ZIG_STD_DEST}")
 install(FILES "${CMAKE_SOURCE_DIR}/std/net.zig" DESTINATION "${ZIG_STD_DEST}")
 install(FILES "${CMAKE_SOURCE_DIR}/std/os/child_process.zig" DESTINATION "${ZIG_STD_DEST}/os")
 install(FILES "${CMAKE_SOURCE_DIR}/std/os/darwin.zig" DESTINATION "${ZIG_STD_DEST}/os")
-install(FILES "${CMAKE_SOURCE_DIR}/std/os/darwin_x86_64.zig" DESTINATION "${ZIG_STD_DEST}/os")
 install(FILES "${CMAKE_SOURCE_DIR}/std/os/errno.zig" DESTINATION "${ZIG_STD_DEST}/os")
 install(FILES "${CMAKE_SOURCE_DIR}/std/os/index.zig" DESTINATION "${ZIG_STD_DEST}/os")
 install(FILES "${CMAKE_SOURCE_DIR}/std/os/linux.zig" DESTINATION "${ZIG_STD_DEST}/os")