diff --git a/CMakeLists.txt b/CMakeLists.txt index f8c862e3de..d4bf6f2fac 100644 --- a/CMakeLists.txt +++ b/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") diff --git a/src/analyze.cpp b/src/analyze.cpp index 0b43f2d1e4..82ae972cbf 100644 --- a/src/analyze.cpp +++ b/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; diff --git a/src/os.cpp b/src/os.cpp index ddf01d3393..363d6fbf32 100644 --- a/src/os.cpp +++ b/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)) { diff --git a/src/os.hpp b/src/os.hpp index 0a529fcbbd..2aefad4fa8 100644 --- a/src/os.hpp +++ b/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 &args, Termination *term); int os_exec_process(const char *exe, ZigList &args, Termination *term, Buf *out_stderr, Buf *out_stdout); diff --git a/std/c/darwin.zig b/std/c/darwin.zig index 9d4961fe00..abc36b0d40 100644 --- a/std/c/darwin.zig +++ b/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, +}; diff --git a/std/c/index.zig b/std/c/index.zig index 091458d789..2139c11633 100644 --- a/std/c/index.zig +++ b/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; diff --git a/std/io.zig b/std/io.zig index 73f49c009f..0e582e44e5 100644 --- a/std/io.zig +++ b/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 { diff --git a/std/os/child_process.zig b/std/os/child_process.zig index 8f821d8099..67365e50e1 100644 --- a/std/os/child_process.zig +++ b/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); } - diff --git a/std/os/darwin.zig b/std/os/darwin.zig index eedef329ae..4704cbaeb2 100644 --- a/std/os/darwin.zig +++ b/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 { - arch.syscall1(arch.SYS_close, usize(fd)) + errnoWrap(c.close(fd)) } -pub fn open(path: &const u8, flags: usize, perm: usize) -> usize { - arch.syscall3(arch.SYS_open, usize(path), flags, perm) +pub fn abort() -> noreturn { + c.abort() } -pub fn read(fd: i32, buf: &u8, count: usize) -> usize { - arch.syscall3(arch.SYS_read, usize(fd), usize(buf), count) +pub fn exit(code: i32) -> noreturn { + c.exit(code) } -pub fn lseek(fd: i32, offset: usize, ref_pos: usize) -> usize { - arch.syscall3(arch.SYS_lseek, usize(fd), offset, ref_pos) +pub fn isatty(fd: i32) -> bool { + c.isatty(fd) == 0 } -pub const stat = arch.stat; -pub const timespec = arch.timespec; - -pub fn fstat(fd: i32, stat_buf: &stat) -> usize { - arch.syscall2(arch.SYS_fstat, usize(fd), usize(stat_buf)) +pub fn fstat(fd: i32, buf: &c.stat) -> usize { + errnoWrap(c.fstat(fd, buf)) } -error Unexpected; - -pub fn getrandom(buf: &u8, count: usize) -> usize { - const rr = open_c(c"/dev/urandom", O_LARGEFILE | O_RDONLY, 0); - - if(getErrno(rr) > 0) return rr; - - var fd: i32 = i32(rr); - const readRes = read(fd, buf, count); - readRes +pub fn lseek(fd: i32, offset: isize, whence: c_int) -> usize { + errnoWrap(c.lseek(fd, buf, whence)) } -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 - - //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; +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 munmap(address: &u8, length: usize) -> usize { + errnoWrap(c.munmap(@ptrCast(&c_void, address), length)) +} + +pub fn unlink(path: &const u8) -> usize { + errnoWrap(c.unlink(path)) +} + +pub fn getcwd(buf: &u8, size: usize) -> usize { + if (c.getcwd(buf, size) == null) @bitCast(usize, -isize(*c._errno())) else 0 +} + +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 fork() -> usize { + errnoWrap(c.fork()) +} + +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 mkdir(path: &const u8, mode: u32) -> usize { + errnoWrap(c.mkdir(path, mode)) +} + +pub fn symlink(existing: &const u8, new: &const u8) -> usize { + errnoWrap(c.symlink(existing, new)) +} + +pub fn rename(old: &const u8, new: &const u8) -> usize { + errnoWrap(c.rename(old, new)) +} + +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)) +} + +/// 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 + }) } diff --git a/std/os/darwin_x86_64.zig b/std/os/darwin_x86_64.zig deleted file mode 100644 index ea6cc5a37a..0000000000 --- a/std/os/darwin_x86_64.zig +++ /dev/null @@ -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, -}; diff --git a/std/os/errno.zig b/std/os/errno.zig index 6f50b50225..39f4e37a10 100644 --- a/std/os/errno.zig +++ b/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 diff --git a/std/os/index.zig b/std/os/index.zig index 54578f563c..dcc05ef67f 100644 --- a/std/os/index.zig +++ b/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)) + 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, } - }, - Os.windows => { - var hCryptProv: windows.HCRYPTPROV = undefined; - if (!windows.CryptAcquireContext(&hCryptProv, null, null, windows.PROV_RSA_FULL, 0)) { - return error.Unexpected; - } - defer _ = windows.CryptReleaseContext(hCryptProv, 0); - - 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; + return; + }, + Os.darwin, Os.macosx, Os.ios => { + const fd = %return posixOpen("/dev/urandom", posix.O_RDONLY|posix.O_CLOEXEC, + 0, null); + defer posixClose(fd); + + %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; + } + 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; diff --git a/std/os/linux.zig b/std/os/linux.zig index 16057be824..15d31fc86d 100644 --- a/std/os/linux.zig +++ b/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)) } diff --git a/std/os/linux_x86_64.zig b/std/os/linux_x86_64.zig index 0f8f163ce2..5fb050af24 100644 --- a/std/os/linux_x86_64.zig +++ b/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, diff --git a/test/cases/asm.zig b/test/cases/asm.zig index b5bf55991e..8a3020fe23 100644 --- a/test/cases/asm.zig +++ b/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); } }