diff options
| author | Andrew Kelley <superjoe30@gmail.com> | 2017-03-23 02:59:58 -0400 |
|---|---|---|
| committer | Andrew Kelley <superjoe30@gmail.com> | 2017-03-23 02:59:58 -0400 |
| commit | d6856859d3082d9b66aac7c25ceb2abcd13e2f7c (patch) | |
| tree | dacade36cf18d88b1c21414130b33da91d7f7784 /std/os.zig | |
| parent | 01b2bf4a44c586f2fa51e8824be608b92d82fed4 (diff) | |
| download | zig-d6856859d3082d9b66aac7c25ceb2abcd13e2f7c.tar.gz zig-d6856859d3082d9b66aac7c25ceb2abcd13e2f7c.zip | |
improvements for windows and libc integration
* standard library knows if it is linking against libc and will
sometimes call libc functions in that case instead of providing
redundant definitions
* fix infinite loop bug when resolving use declarations
* allow calling the same C function from different C imports.
closes #277
* push more logic from compiler to std/bootstrap.zig
* standard library provides way to access errno
closes #274
* fix compile error in standard library for windows
* add implementation of getRandomBytes for windows
Diffstat (limited to 'std/os.zig')
| -rw-r--r-- | std/os.zig | 57 |
1 files changed, 46 insertions, 11 deletions
diff --git a/std/os.zig b/std/os.zig index bfb8daecb3..b50aa021f9 100644 --- a/std/os.zig +++ b/std/os.zig @@ -1,20 +1,49 @@ -const system = switch(@compileVar("os")) { +const posix = switch(@compileVar("os")) { Os.linux => @import("linux.zig"), - Os.darwin => @import("darwin.zig"), + Os.darwin, Os.macosx, Os.ios => @import("darwin.zig"), else => @compileError("Unsupported OS"), }; +const windows = @import("windows.zig"); const errno = @import("errno.zig"); +const linking_libc = @import("build.zig").linking_libc; +const c = @import("c/index.zig"); error Unexpected; +/// Fills `buf` with random bytes. If linking against libc, this calls the +/// appropriate OS-specific library call. Otherwise it uses the zig standard +/// library implementation. pub fn getRandomBytes(buf: []u8) -> %void { while (true) { - const ret = switch (@compileVar("os")) { - Os.linux => system.getrandom(buf.ptr, buf.len, 0), - Os.darwin => system.getrandom(buf.ptr, buf.len), - else => @compileError("unsupported os"), + const err = switch (@compileVar("os")) { + Os.linux => { + if (linking_libc) { + if (c.getrandom(buf.ptr, buf.len, 0) == -1) *c._errno() else 0 + } else { + posix.getErrno(posix.getrandom(buf.ptr, buf.len, 0)) + } + }, + Os.darwin, Os.macosx, Os.ios => { + if (linking_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; + } + defer _ = windows.CryptReleaseContext(hCryptProv, 0); + + if (!windows.CryptGenRandom(hCryptProv, windows.DWORD(buf.len), buf.ptr)) { + return error.Unexpected; + } + return; + }, + else => @compileError("Unsupported OS"), }; - const err = system.getErrno(ret); if (err > 0) { return switch (err) { errno.EINVAL => @unreachable(), @@ -27,13 +56,19 @@ pub fn getRandomBytes(buf: []u8) -> %void { } } +/// Raises a signal in the current kernel thread, ending its execution. +/// If linking against libc, this calls the abort() libc function. Otherwise +/// it uses the zig standard library implementation. pub coldcc fn abort() -> unreachable { + if (linking_libc) { + c.abort(); + } switch (@compileVar("os")) { - Os.linux, Os.darwin => { - _ = system.raise(system.SIGABRT); - _ = system.raise(system.SIGKILL); + Os.linux => { + _ = posix.raise(posix.SIGABRT); + _ = posix.raise(posix.SIGKILL); while (true) {} }, - else => @compileError("unsupported os"), + else => @compileError("Unsupported OS"), } } |
