authorgravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2019-05-26 23:35:26-04:00
committergravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2019-05-26 23:35:26-04:00
log0c6ab61b228211398841cf11912c7252362009b7
treed2a67490f5e580ba8a447d70edf427e6e0cc6ce0
parent2b42e910bf4696032158cc7ae268d3c69d699f70
signature Commit is signed but in an unrecognized format.

tests passing on linux


38 files changed, 348 insertions(+), 298 deletions(-)

build.zig+2-4
...@@ -166,10 +166,8 @@ fn dependOnLib(b: *Builder, lib_exe_obj: var, dep: LibraryDep) void {...@@ -166,10 +166,8 @@ fn dependOnLib(b: *Builder, lib_exe_obj: var, dep: LibraryDep) void {
166}166}
167167
168fn fileExists(filename: []const u8) !bool {168fn fileExists(filename: []const u8) !bool {
169 fs.File.exists(filename) catch |err| switch (err) {169 fs.File.access(filename) catch |err| switch (err) {
170 error.PermissionDenied,170 error.FileNotFound => return false,
171 error.FileNotFound,
172 => return false,
173 else => return err,171 else => return err,
174 };172 };
175 return true;173 return true;
doc/langref.html.in+2-2
...@@ -796,8 +796,8 @@ const assert = std.debug.assert;...@@ -796,8 +796,8 @@ const assert = std.debug.assert;
796threadlocal var x: i32 = 1234;796threadlocal var x: i32 = 1234;
797797
798test "thread local storage" {798test "thread local storage" {
799 const thread1 = try std.os.spawnThread({}, testTls);799 const thread1 = try std.Thread.spawn({}, testTls);
800 const thread2 = try std.os.spawnThread({}, testTls);800 const thread2 = try std.Thread.spawn({}, testTls);
801 testTls({});801 testTls({});
802 thread1.wait();802 thread1.wait();
803 thread2.wait();803 thread2.wait();
example/cat/main.zig+5-4
...@@ -1,12 +1,13 @@...@@ -1,12 +1,13 @@
1const std = @import("std");1const std = @import("std");
2const io = std.io;2const io = std.io;
3const process = std.process;
4const File = std.fs.File;
3const mem = std.mem;5const mem = std.mem;
4const os = std.os;
5const warn = std.debug.warn;6const warn = std.debug.warn;
6const allocator = std.debug.global_allocator;7const allocator = std.debug.global_allocator;
78
8pub fn main() !void {9pub fn main() !void {
9 var args_it = os.args();10 var args_it = process.args();
10 const exe = try unwrapArg(args_it.next(allocator).?);11 const exe = try unwrapArg(args_it.next(allocator).?);
11 var catted_anything = false;12 var catted_anything = false;
12 var stdout_file = try io.getStdOut();13 var stdout_file = try io.getStdOut();
...@@ -20,7 +21,7 @@ pub fn main() !void {...@@ -20,7 +21,7 @@ pub fn main() !void {
20 } else if (arg[0] == '-') {21 } else if (arg[0] == '-') {
21 return usage(exe);22 return usage(exe);
22 } else {23 } else {
23 var file = os.File.openRead(arg) catch |err| {24 var file = File.openRead(arg) catch |err| {
24 warn("Unable to open file: {}\n", @errorName(err));25 warn("Unable to open file: {}\n", @errorName(err));
25 return err;26 return err;
26 };27 };
...@@ -41,7 +42,7 @@ fn usage(exe: []const u8) !void {...@@ -41,7 +42,7 @@ fn usage(exe: []const u8) !void {
41 return error.Invalid;42 return error.Invalid;
42}43}
4344
44fn cat_file(stdout: *os.File, file: *os.File) !void {45fn cat_file(stdout: *File, file: *File) !void {
45 var buf: [1024 * 4]u8 = undefined;46 var buf: [1024 * 4]u8 = undefined;
4647
47 while (true) {48 while (true) {
example/guess_number/main.zig+1-2
...@@ -2,7 +2,6 @@ const builtin = @import("builtin");...@@ -2,7 +2,6 @@ const builtin = @import("builtin");
2const std = @import("std");2const std = @import("std");
3const io = std.io;3const io = std.io;
4const fmt = std.fmt;4const fmt = std.fmt;
5const os = std.os;
65
7pub fn main() !void {6pub fn main() !void {
8 var stdout_file = try io.getStdOut();7 var stdout_file = try io.getStdOut();
...@@ -11,7 +10,7 @@ pub fn main() !void {...@@ -11,7 +10,7 @@ pub fn main() !void {
11 try stdout.print("Welcome to the Guess Number Game in Zig.\n");10 try stdout.print("Welcome to the Guess Number Game in Zig.\n");
1211
13 var seed_bytes: [@sizeOf(u64)]u8 = undefined;12 var seed_bytes: [@sizeOf(u64)]u8 = undefined;
14 os.getRandomBytes(seed_bytes[0..]) catch |err| {13 std.crypto.randomBytes(seed_bytes[0..]) catch |err| {
15 std.debug.warn("unable to seed random number generator: {}", err);14 std.debug.warn("unable to seed random number generator: {}", err);
16 return err;15 return err;
17 };16 };
example/hello_world/hello_libc.zig+1-1
...@@ -5,6 +5,6 @@ const c = @cImport({...@@ -5,6 +5,6 @@ const c = @cImport({
5});5});
66
7export fn main(argc: c_int, argv: [*]?[*]u8) c_int {7export fn main(argc: c_int, argv: [*]?[*]u8) c_int {
8 c.fprintf(c.stderr, c"Hello, world!\n");8 _ = c.fprintf(c.stderr, c"Hello, world!\n");
9 return 0;9 return 0;
10}10}
src-self-hosted/compilation.zig+1
...@@ -301,6 +301,7 @@ pub const Compilation = struct {...@@ -301,6 +301,7 @@ pub const Compilation = struct {
301 InvalidUtf8,301 InvalidUtf8,
302 BadPathName,302 BadPathName,
303 DeviceBusy,303 DeviceBusy,
304 CurrentWorkingDirectoryUnlinked,
304 };305 };
305306
306 pub const Event = union(enum) {307 pub const Event = union(enum) {
src-self-hosted/libc_installation.zig+3-3
...@@ -182,7 +182,7 @@ pub const LibCInstallation = struct {...@@ -182,7 +182,7 @@ pub const LibCInstallation = struct {
182 }182 }
183183
184 async fn findNativeIncludeDirLinux(self: *LibCInstallation, loop: *event.Loop) !void {184 async fn findNativeIncludeDirLinux(self: *LibCInstallation, loop: *event.Loop) !void {
185 const cc_exe = std.process.getEnvPosix("CC") orelse "cc";185 const cc_exe = std.os.getenv("CC") orelse "cc";
186 const argv = []const []const u8{186 const argv = []const []const u8{
187 cc_exe,187 cc_exe,
188 "-E",188 "-E",
...@@ -392,7 +392,7 @@ pub const LibCInstallation = struct {...@@ -392,7 +392,7 @@ pub const LibCInstallation = struct {
392392
393/// caller owns returned memory393/// caller owns returned memory
394async fn ccPrintFileName(loop: *event.Loop, o_file: []const u8, want_dirname: bool) ![]u8 {394async fn ccPrintFileName(loop: *event.Loop, o_file: []const u8, want_dirname: bool) ![]u8 {
395 const cc_exe = std.process.getEnvPosix("CC") orelse "cc";395 const cc_exe = std.os.getenv("CC") orelse "cc";
396 const arg1 = try std.fmt.allocPrint(loop.allocator, "-print-file-name={}", o_file);396 const arg1 = try std.fmt.allocPrint(loop.allocator, "-print-file-name={}", o_file);
397 defer loop.allocator.free(arg1);397 defer loop.allocator.free(arg1);
398 const argv = []const []const u8{ cc_exe, arg1 };398 const argv = []const []const u8{ cc_exe, arg1 };
...@@ -463,7 +463,7 @@ fn fileExists(path: []const u8) !bool {...@@ -463,7 +463,7 @@ fn fileExists(path: []const u8) !bool {
463 if (fs.File.access(path)) |_| {463 if (fs.File.access(path)) |_| {
464 return true;464 return true;
465 } else |err| switch (err) {465 } else |err| switch (err) {
466 error.FileNotFound, error.PermissionDenied => return false,466 error.FileNotFound => return false,
467 else => return error.FileSystem,467 else => return error.FileSystem,
468 }468 }
469}469}
src-self-hosted/main.zig+10-9
...@@ -702,6 +702,7 @@ const FmtError = error{...@@ -702,6 +702,7 @@ const FmtError = error{
702 ReadOnlyFileSystem,702 ReadOnlyFileSystem,
703 LinkQuotaExceeded,703 LinkQuotaExceeded,
704 FileBusy,704 FileBusy,
705 CurrentWorkingDirectoryUnlinked,
705} || fs.File.OpenError;706} || fs.File.OpenError;
706707
707async fn asyncFmtMain(708async fn asyncFmtMain(
...@@ -851,7 +852,7 @@ fn cmdTargets(allocator: *Allocator, args: []const []const u8) !void {...@@ -851,7 +852,7 @@ fn cmdTargets(allocator: *Allocator, args: []const []const u8) !void {
851}852}
852853
853fn cmdVersion(allocator: *Allocator, args: []const []const u8) !void {854fn cmdVersion(allocator: *Allocator, args: []const []const u8) !void {
854 try stdout.print("{}\n", std.cstr.toSliceConst(c.ZIG_VERSION_STRING));855 try stdout.print("{}\n", std.mem.toSliceConst(u8, c.ZIG_VERSION_STRING));
855}856}
856857
857const args_test_spec = []Flag{Flag.Bool("--help")};858const args_test_spec = []Flag{Flag.Bool("--help")};
...@@ -924,14 +925,14 @@ fn cmdInternalBuildInfo(allocator: *Allocator, args: []const []const u8) !void {...@@ -924,14 +925,14 @@ fn cmdInternalBuildInfo(allocator: *Allocator, args: []const []const u8) !void {
924 \\ZIG_DIA_GUIDS_LIB {}925 \\ZIG_DIA_GUIDS_LIB {}
925 \\926 \\
926 ,927 ,
927 std.cstr.toSliceConst(c.ZIG_CMAKE_BINARY_DIR),928 std.mem.toSliceConst(u8, c.ZIG_CMAKE_BINARY_DIR),
928 std.cstr.toSliceConst(c.ZIG_CXX_COMPILER),929 std.mem.toSliceConst(u8, c.ZIG_CXX_COMPILER),
929 std.cstr.toSliceConst(c.ZIG_LLVM_CONFIG_EXE),930 std.mem.toSliceConst(u8, c.ZIG_LLVM_CONFIG_EXE),
930 std.cstr.toSliceConst(c.ZIG_LLD_INCLUDE_PATH),931 std.mem.toSliceConst(u8, c.ZIG_LLD_INCLUDE_PATH),
931 std.cstr.toSliceConst(c.ZIG_LLD_LIBRARIES),932 std.mem.toSliceConst(u8, c.ZIG_LLD_LIBRARIES),
932 std.cstr.toSliceConst(c.ZIG_STD_FILES),933 std.mem.toSliceConst(u8, c.ZIG_STD_FILES),
933 std.cstr.toSliceConst(c.ZIG_C_HEADER_FILES),934 std.mem.toSliceConst(u8, c.ZIG_C_HEADER_FILES),
934 std.cstr.toSliceConst(c.ZIG_DIA_GUIDS_LIB),935 std.mem.toSliceConst(u8, c.ZIG_DIA_GUIDS_LIB),
935 );936 );
936}937}
937938
std/c.zig+9-4
...@@ -39,8 +39,8 @@ pub extern "c" fn open(path: [*]const u8, oflag: c_uint, ...) c_int;...@@ -39,8 +39,8 @@ pub extern "c" fn open(path: [*]const u8, oflag: c_uint, ...) c_int;
39pub extern "c" fn raise(sig: c_int) c_int;39pub extern "c" fn raise(sig: c_int) c_int;
40pub extern "c" fn read(fd: fd_t, buf: [*]u8, nbyte: usize) isize;40pub extern "c" fn read(fd: fd_t, buf: [*]u8, nbyte: usize) isize;
41pub extern "c" fn pread(fd: fd_t, buf: [*]u8, nbyte: usize, offset: u64) isize;41pub extern "c" fn pread(fd: fd_t, buf: [*]u8, nbyte: usize, offset: u64) isize;
42pub extern "c" fn preadv(fd: c_int, iov: [*]const iovec, iovcnt: c_int, offset: usize) isize;42pub extern "c" fn preadv(fd: c_int, iov: [*]const iovec, iovcnt: c_uint, offset: usize) isize;
43pub extern "c" fn pwritev(fd: c_int, iov: [*]const iovec, iovcnt: c_int, offset: usize) isize;43pub extern "c" fn pwritev(fd: c_int, iov: [*]const iovec_const, iovcnt: c_uint, offset: usize) isize;
44pub extern "c" fn stat(noalias path: [*]const u8, noalias buf: *Stat) c_int;44pub extern "c" fn stat(noalias path: [*]const u8, noalias buf: *Stat) c_int;
45pub extern "c" fn write(fd: fd_t, buf: [*]const u8, nbyte: usize) isize;45pub extern "c" fn write(fd: fd_t, buf: [*]const u8, nbyte: usize) isize;
46pub extern "c" fn pwrite(fd: fd_t, buf: [*]const u8, nbyte: usize, offset: u64) isize;46pub extern "c" fn pwrite(fd: fd_t, buf: [*]const u8, nbyte: usize, offset: u64) isize;
...@@ -49,7 +49,7 @@ pub extern "c" fn munmap(addr: *align(page_size) c_void, len: usize) c_int;...@@ -49,7 +49,7 @@ pub extern "c" fn munmap(addr: *align(page_size) c_void, len: usize) c_int;
49pub extern "c" fn mprotect(addr: *align(page_size) c_void, len: usize, prot: c_uint) c_int;49pub extern "c" fn mprotect(addr: *align(page_size) c_void, len: usize, prot: c_uint) c_int;
50pub extern "c" fn unlink(path: [*]const u8) c_int;50pub extern "c" fn unlink(path: [*]const u8) c_int;
51pub extern "c" fn getcwd(buf: [*]u8, size: usize) ?[*]u8;51pub extern "c" fn getcwd(buf: [*]u8, size: usize) ?[*]u8;
52pub extern "c" fn waitpid(pid: c_int, stat_loc: *c_int, options: c_int) c_int;52pub extern "c" fn waitpid(pid: c_int, stat_loc: *c_uint, options: c_uint) c_int;
53pub extern "c" fn fork() c_int;53pub extern "c" fn fork() c_int;
54pub extern "c" fn access(path: [*]const u8, mode: c_uint) c_int;54pub extern "c" fn access(path: [*]const u8, mode: c_uint) c_int;
55pub extern "c" fn pipe(fds: *[2]fd_t) c_int;55pub extern "c" fn pipe(fds: *[2]fd_t) c_int;
...@@ -76,7 +76,12 @@ pub extern "c" fn sysctlbyname(name: [*]const u8, oldp: ?*c_void, oldlenp: ?*usi...@@ -76,7 +76,12 @@ pub extern "c" fn sysctlbyname(name: [*]const u8, oldp: ?*c_void, oldlenp: ?*usi
76pub extern "c" fn sysctlnametomib(name: [*]const u8, mibp: ?*c_int, sizep: ?*usize) c_int;76pub extern "c" fn sysctlnametomib(name: [*]const u8, mibp: ?*c_int, sizep: ?*usize) c_int;
7777
78pub extern "c" fn bind(socket: fd_t, address: ?*const sockaddr, address_len: socklen_t) c_int;78pub extern "c" fn bind(socket: fd_t, address: ?*const sockaddr, address_len: socklen_t) c_int;
79pub extern "c" fn socket(domain: c_int, sock_type: c_int, protocol: c_int) c_int;79pub extern "c" fn socket(domain: c_uint, sock_type: c_uint, protocol: c_uint) c_int;
80pub extern "c" fn listen(sockfd: fd_t, backlog: c_uint) c_int;
81pub extern "c" fn getsockname(sockfd: fd_t, noalias addr: *sockaddr, noalias addrlen: *socklen_t) c_int;
82pub extern "c" fn connect(sockfd: fd_t, sock_addr: *const sockaddr, addrlen: socklen_t) c_int;
83pub extern "c" fn accept4(sockfd: fd_t, addr: *sockaddr, addrlen: *socklen_t, flags: c_uint) c_int;
84pub extern "c" fn getsockopt(sockfd: fd_t, level: c_int, optname: c_int, optval: *c_void, optlen: *socklen_t) c_int;
80pub extern "c" fn kill(pid: pid_t, sig: c_int) c_int;85pub extern "c" fn kill(pid: pid_t, sig: c_int) c_int;
81pub extern "c" fn getdirentries(fd: fd_t, buf_ptr: [*]u8, nbytes: usize, basep: *i64) isize;86pub extern "c" fn getdirentries(fd: fd_t, buf_ptr: [*]u8, nbytes: usize, basep: *i64) isize;
82pub extern "c" fn openat(fd: c_int, path: [*]const u8, flags: c_int) c_int;87pub extern "c" fn openat(fd: c_int, path: [*]const u8, flags: c_int) c_int;
std/c/linux.zig+18-4
...@@ -1,13 +1,27 @@...@@ -1,13 +1,27 @@
1const std = @import("../std.zig");1const std = @import("../std.zig");
2use std.c;2use std.c;
33
4pub extern "c" fn getrandom(buf_ptr: [*]u8, buf_len: usize, flags: c_uint) c_int;
5pub extern "c" fn sched_getaffinity(pid: c_int, size: usize, set: *cpu_set_t) c_int;
6extern "c" fn __errno_location() *c_int;4extern "c" fn __errno_location() *c_int;
7pub const _errno = __errno_location;5pub const _errno = __errno_location;
86
7pub extern "c" fn getrandom(buf_ptr: [*]u8, buf_len: usize, flags: c_uint) c_int;
8pub extern "c" fn sched_getaffinity(pid: c_int, size: usize, set: *cpu_set_t) c_int;
9pub extern "c" fn eventfd(initval: c_uint, flags: c_uint) c_int;
10pub extern "c" fn epoll_ctl(epfd: fd_t, op: c_uint, fd: fd_t, event: *epoll_event) c_int;
11pub extern "c" fn epoll_create1(flags: c_uint) c_int;
12pub extern "c" fn epoll_wait(epfd: fd_t, events: [*]epoll_event, maxevents: c_uint, timeout: c_int) c_int;
13pub extern "c" fn epoll_pwait(
14 epfd: fd_t,
15 events: [*]epoll_event,
16 maxevents: c_int,
17 timeout: c_int,
18 sigmask: *const sigset_t,
19) c_int;
20pub extern "c" fn inotify_init1(flags: c_uint) c_int;
21pub extern "c" fn inotify_add_watch(fd: fd_t, pathname: [*]const u8, mask: u32) c_int;
22
9/// See std.elf for constants for this23/// See std.elf for constants for this
10pub extern fn getauxval(__type: c_ulong) c_ulong;24pub extern "c" fn getauxval(__type: c_ulong) c_ulong;
1125
12pub const dl_iterate_phdr_callback = extern fn (info: *dl_phdr_info, size: usize, data: ?*c_void) c_int;26pub const dl_iterate_phdr_callback = extern fn (info: *dl_phdr_info, size: usize, data: ?*c_void) c_int;
13pub extern fn dl_iterate_phdr(callback: dl_iterate_phdr_callback, data: ?*c_void) c_int;27pub extern "c" fn dl_iterate_phdr(callback: dl_iterate_phdr_callback, data: ?*c_void) c_int;
std/child_process.zig+9-9
...@@ -54,10 +54,10 @@ pub const ChildProcess = struct {...@@ -54,10 +54,10 @@ pub const ChildProcess = struct {
54 os.ChangeCurDirError || windows.CreateProcessError;54 os.ChangeCurDirError || windows.CreateProcessError;
5555
56 pub const Term = union(enum) {56 pub const Term = union(enum) {
57 Exited: i32,57 Exited: u32,
58 Signal: i32,58 Signal: u32,
59 Stopped: i32,59 Stopped: u32,
60 Unknown: i32,60 Unknown: u32,
61 };61 };
6262
63 pub const StdIo = enum {63 pub const StdIo = enum {
...@@ -155,7 +155,7 @@ pub const ChildProcess = struct {...@@ -155,7 +155,7 @@ pub const ChildProcess = struct {
155 }155 }
156156
157 pub const ExecResult = struct {157 pub const ExecResult = struct {
158 term: os.ChildProcess.Term,158 term: Term,
159 stdout: []u8,159 stdout: []u8,
160 stderr: []u8,160 stderr: []u8,
161 };161 };
...@@ -224,7 +224,7 @@ pub const ChildProcess = struct {...@@ -224,7 +224,7 @@ pub const ChildProcess = struct {
224 if (windows.GetExitCodeProcess(self.handle, &exit_code) == 0) {224 if (windows.GetExitCodeProcess(self.handle, &exit_code) == 0) {
225 break :x Term{ .Unknown = 0 };225 break :x Term{ .Unknown = 0 };
226 } else {226 } else {
227 break :x Term{ .Exited = @bitCast(i32, exit_code) };227 break :x Term{ .Exited = exit_code };
228 }228 }
229 });229 });
230230
...@@ -240,7 +240,7 @@ pub const ChildProcess = struct {...@@ -240,7 +240,7 @@ pub const ChildProcess = struct {
240 self.handleWaitResult(status);240 self.handleWaitResult(status);
241 }241 }
242242
243 fn handleWaitResult(self: *ChildProcess, status: i32) void {243 fn handleWaitResult(self: *ChildProcess, status: u32) void {
244 self.term = self.cleanupAfterWait(status);244 self.term = self.cleanupAfterWait(status);
245 }245 }
246246
...@@ -259,7 +259,7 @@ pub const ChildProcess = struct {...@@ -259,7 +259,7 @@ pub const ChildProcess = struct {
259 }259 }
260 }260 }
261261
262 fn cleanupAfterWait(self: *ChildProcess, status: i32) !Term {262 fn cleanupAfterWait(self: *ChildProcess, status: u32) !Term {
263 defer {263 defer {
264 os.close(self.err_pipe[0]);264 os.close(self.err_pipe[0]);
265 os.close(self.err_pipe[1]);265 os.close(self.err_pipe[1]);
...@@ -281,7 +281,7 @@ pub const ChildProcess = struct {...@@ -281,7 +281,7 @@ pub const ChildProcess = struct {
281 return statusToTerm(status);281 return statusToTerm(status);
282 }282 }
283283
284 fn statusToTerm(status: i32) Term {284 fn statusToTerm(status: u32) Term {
285 return if (os.WIFEXITED(status))285 return if (os.WIFEXITED(status))
286 Term{ .Exited = os.WEXITSTATUS(status) }286 Term{ .Exited = os.WEXITSTATUS(status) }
287 else if (os.WIFSIGNALED(status))287 else if (os.WIFSIGNALED(status))
std/cstr.zig+1-1
...@@ -28,7 +28,7 @@ test "cstr fns" {...@@ -28,7 +28,7 @@ test "cstr fns" {
2828
29fn testCStrFnsImpl() void {29fn testCStrFnsImpl() void {
30 testing.expect(cmp(c"aoeu", c"aoez") == -1);30 testing.expect(cmp(c"aoeu", c"aoez") == -1);
31 testing.expect(len(c"123456789") == 9);31 testing.expect(mem.len(u8, c"123456789") == 9);
32}32}
3333
34/// Returns a mutable slice with 1 more byte of length which is a null byte.34/// Returns a mutable slice with 1 more byte of length which is a null byte.
std/dynamic_library.zig+13-25
...@@ -6,8 +6,7 @@ const os = std.os;...@@ -6,8 +6,7 @@ const os = std.os;
6const assert = std.debug.assert;6const assert = std.debug.assert;
7const testing = std.testing;7const testing = std.testing;
8const elf = std.elf;8const elf = std.elf;
9const windows = os.windows;9const windows = std.os.windows;
10const win_util = @import("os/windows/util.zig");
11const maxInt = std.math.maxInt;10const maxInt = std.math.maxInt;
1211
13pub const DynLib = switch (builtin.os) {12pub const DynLib = switch (builtin.os) {
...@@ -102,17 +101,16 @@ pub fn linkmap_iterator(phdrs: []elf.Phdr) !LinkMap.Iterator {...@@ -102,17 +101,16 @@ pub fn linkmap_iterator(phdrs: []elf.Phdr) !LinkMap.Iterator {
102pub const LinuxDynLib = struct {101pub const LinuxDynLib = struct {
103 elf_lib: ElfLib,102 elf_lib: ElfLib,
104 fd: i32,103 fd: i32,
105 map_addr: usize,104 memory: []align(mem.page_size) u8,
106 map_size: usize,
107105
108 /// Trusts the file106 /// Trusts the file
109 pub fn open(allocator: *mem.Allocator, path: []const u8) !DynLib {107 pub fn open(allocator: *mem.Allocator, path: []const u8) !DynLib {
110 const fd = try os.open(path, 0, os.O_RDONLY | os.O_CLOEXEC);108 const fd = try os.open(path, 0, os.O_RDONLY | os.O_CLOEXEC);
111 errdefer std.os.close(fd);109 errdefer os.close(fd);
112110
113 const size = @intCast(usize, (try std.os.posixFStat(fd)).size);111 const size = @intCast(usize, (try os.fstat(fd)).size);
114112
115 const addr = os.mmap(113 const bytes = try os.mmap(
116 null,114 null,
117 size,115 size,
118 os.PROT_READ | os.PROT_EXEC,116 os.PROT_READ | os.PROT_EXEC,
...@@ -120,21 +118,18 @@ pub const LinuxDynLib = struct {...@@ -120,21 +118,18 @@ pub const LinuxDynLib = struct {
120 fd,118 fd,
121 0,119 0,
122 );120 );
123 errdefer os.munmap(addr, size);121 errdefer os.munmap(bytes);
124
125 const bytes = @intToPtr([*]align(mem.page_size) u8, addr)[0..size];
126122
127 return DynLib{123 return DynLib{
128 .elf_lib = try ElfLib.init(bytes),124 .elf_lib = try ElfLib.init(bytes),
129 .fd = fd,125 .fd = fd,
130 .map_addr = addr,126 .memory = bytes,
131 .map_size = size,
132 };127 };
133 }128 }
134129
135 pub fn close(self: *DynLib) void {130 pub fn close(self: *DynLib) void {
136 os.munmap(self.map_addr, self.map_size);131 os.munmap(self.memory);
137 std.os.close(self.fd);132 os.close(self.fd);
138 self.* = undefined;133 self.* = undefined;
139 }134 }
140135
...@@ -253,28 +248,21 @@ pub const WindowsDynLib = struct {...@@ -253,28 +248,21 @@ pub const WindowsDynLib = struct {
253 dll: windows.HMODULE,248 dll: windows.HMODULE,
254249
255 pub fn open(allocator: *mem.Allocator, path: []const u8) !WindowsDynLib {250 pub fn open(allocator: *mem.Allocator, path: []const u8) !WindowsDynLib {
256 const wpath = try win_util.sliceToPrefixedFileW(path);251 const wpath = try windows.sliceToPrefixedFileW(path);
257252
258 return WindowsDynLib{253 return WindowsDynLib{
259 .allocator = allocator,254 .allocator = allocator,
260 .dll = windows.LoadLibraryW(&wpath) orelse {255 .dll = try windows.LoadLibraryW(&wpath),
261 switch (windows.GetLastError()) {
262 windows.ERROR.FILE_NOT_FOUND => return error.FileNotFound,
263 windows.ERROR.PATH_NOT_FOUND => return error.FileNotFound,
264 windows.ERROR.MOD_NOT_FOUND => return error.FileNotFound,
265 else => |err| return windows.unexpectedError(err),
266 }
267 },
268 };256 };
269 }257 }
270258
271 pub fn close(self: *WindowsDynLib) void {259 pub fn close(self: *WindowsDynLib) void {
272 assert(windows.FreeLibrary(self.dll) != 0);260 windows.FreeLibrary(self.dll);
273 self.* = undefined;261 self.* = undefined;
274 }262 }
275263
276 pub fn lookup(self: *WindowsDynLib, name: []const u8) ?usize {264 pub fn lookup(self: *WindowsDynLib, name: []const u8) ?usize {
277 return @ptrToInt(windows.GetProcAddress(self.dll, name.ptr));265 return @ptrToInt(windows.kernel32.GetProcAddress(self.dll, name.ptr));
278 }266 }
279};267};
280268
std/event/fs.zig+7-7
...@@ -36,7 +36,7 @@ pub const Request = struct {...@@ -36,7 +36,7 @@ pub const Request = struct {
36 offset: usize,36 offset: usize,
37 result: Error!void,37 result: Error!void,
3838
39 pub const Error = os.PosixWriteError;39 pub const Error = os.WriteError;
40 };40 };
4141
42 pub const PReadV = struct {42 pub const PReadV = struct {
...@@ -45,7 +45,7 @@ pub const Request = struct {...@@ -45,7 +45,7 @@ pub const Request = struct {
45 offset: usize,45 offset: usize,
46 result: Error!usize,46 result: Error!usize,
4747
48 pub const Error = os.PosixReadError;48 pub const Error = os.ReadError;
49 };49 };
5050
51 pub const Open = struct {51 pub const Open = struct {
...@@ -172,7 +172,7 @@ pub async fn pwritevPosix(...@@ -172,7 +172,7 @@ pub async fn pwritevPosix(
172 fd: fd_t,172 fd: fd_t,
173 iovecs: []const os.iovec_const,173 iovecs: []const os.iovec_const,
174 offset: usize,174 offset: usize,
175) os.PosixWriteError!void {175) os.WriteError!void {
176 // workaround for https://github.com/ziglang/zig/issues/1194176 // workaround for https://github.com/ziglang/zig/issues/1194
177 suspend {177 suspend {
178 resume @handle();178 resume @handle();
...@@ -320,7 +320,7 @@ pub async fn preadvPosix(...@@ -320,7 +320,7 @@ pub async fn preadvPosix(
320 fd: fd_t,320 fd: fd_t,
321 iovecs: []const os.iovec,321 iovecs: []const os.iovec,
322 offset: usize,322 offset: usize,
323) os.PosixReadError!usize {323) os.ReadError!usize {
324 // workaround for https://github.com/ziglang/zig/issues/1194324 // workaround for https://github.com/ziglang/zig/issues/1194
325 suspend {325 suspend {
326 resume @handle();326 resume @handle();
...@@ -786,7 +786,7 @@ pub fn Watch(comptime V: type) type {...@@ -786,7 +786,7 @@ pub fn Watch(comptime V: type) type {
786786
787 switch (builtin.os) {787 switch (builtin.os) {
788 builtin.Os.linux => {788 builtin.Os.linux => {
789 const inotify_fd = try os.linuxINotifyInit1(os.linux.IN_NONBLOCK | os.linux.IN_CLOEXEC);789 const inotify_fd = try os.inotify_init1(os.linux.IN_NONBLOCK | os.linux.IN_CLOEXEC);
790 errdefer os.close(inotify_fd);790 errdefer os.close(inotify_fd);
791791
792 var result: *Self = undefined;792 var result: *Self = undefined;
...@@ -977,7 +977,7 @@ pub fn Watch(comptime V: type) type {...@@ -977,7 +977,7 @@ pub fn Watch(comptime V: type) type {
977 var basename_with_null_consumed = false;977 var basename_with_null_consumed = false;
978 defer if (!basename_with_null_consumed) self.channel.loop.allocator.free(basename_with_null);978 defer if (!basename_with_null_consumed) self.channel.loop.allocator.free(basename_with_null);
979979
980 const wd = try os.linuxINotifyAddWatchC(980 const wd = try os.inotify_add_watchC(
981 self.os_data.inotify_fd,981 self.os_data.inotify_fd,
982 dirname_with_null.ptr,982 dirname_with_null.ptr,
983 os.linux.IN_CLOSE_WRITE | os.linux.IN_ONLYDIR | os.linux.IN_EXCL_UNLINK,983 os.linux.IN_CLOSE_WRITE | os.linux.IN_ONLYDIR | os.linux.IN_EXCL_UNLINK,
...@@ -1255,7 +1255,7 @@ pub fn Watch(comptime V: type) type {...@@ -1255,7 +1255,7 @@ pub fn Watch(comptime V: type) type {
1255 ev = @ptrCast(*os.linux.inotify_event, ptr);1255 ev = @ptrCast(*os.linux.inotify_event, ptr);
1256 if (ev.mask & os.linux.IN_CLOSE_WRITE == os.linux.IN_CLOSE_WRITE) {1256 if (ev.mask & os.linux.IN_CLOSE_WRITE == os.linux.IN_CLOSE_WRITE) {
1257 const basename_ptr = ptr + @sizeOf(os.linux.inotify_event);1257 const basename_ptr = ptr + @sizeOf(os.linux.inotify_event);
1258 const basename_with_null = basename_ptr[0 .. std.cstr.len(basename_ptr) + 1];1258 const basename_with_null = basename_ptr[0 .. std.mem.len(u8, basename_ptr) + 1];
1259 const user_value = blk: {1259 const user_value = blk: {
1260 const held = await (async watch.os_data.table_lock.acquire() catch unreachable);1260 const held = await (async watch.os_data.table_lock.acquire() catch unreachable);
1261 defer held.release();1261 defer held.release();
std/event/loop.zig+16-16
...@@ -99,7 +99,7 @@ pub const Loop = struct {...@@ -99,7 +99,7 @@ pub const Loop = struct {
99 /// have the correct pointer value.99 /// have the correct pointer value.
100 pub fn initMultiThreaded(self: *Loop, allocator: *mem.Allocator) !void {100 pub fn initMultiThreaded(self: *Loop, allocator: *mem.Allocator) !void {
101 if (builtin.single_threaded) @compileError("initMultiThreaded unavailable when building in single-threaded mode");101 if (builtin.single_threaded) @compileError("initMultiThreaded unavailable when building in single-threaded mode");
102 const core_count = try os.cpuCount(allocator);102 const core_count = try Thread.cpuCount();
103 return self.initInternal(allocator, core_count);103 return self.initInternal(allocator, core_count);
104 }104 }
105105
...@@ -139,9 +139,9 @@ pub const Loop = struct {...@@ -139,9 +139,9 @@ pub const Loop = struct {
139 self.allocator.free(self.extra_threads);139 self.allocator.free(self.extra_threads);
140 }140 }
141141
142 const InitOsDataError = os.LinuxEpollCreateError || mem.Allocator.Error || os.LinuxEventFdError ||142 const InitOsDataError = os.EpollCreateError || mem.Allocator.Error || os.EventFdError ||
143 os.SpawnThreadError || os.LinuxEpollCtlError || os.BsdKEventError ||143 Thread.SpawnError || os.EpollCtlError || os.KEventError ||
144 os.WindowsCreateIoCompletionPortError;144 windows.CreateIoCompletionPortError;
145145
146 const wakeup_bytes = []u8{0x1} ** 8;146 const wakeup_bytes = []u8{0x1} ** 8;
147147
...@@ -172,7 +172,7 @@ pub const Loop = struct {...@@ -172,7 +172,7 @@ pub const Loop = struct {
172 .handle = undefined,172 .handle = undefined,
173 .overlapped = ResumeNode.overlapped_init,173 .overlapped = ResumeNode.overlapped_init,
174 },174 },
175 .eventfd = try os.linuxEventFd(1, os.EFD_CLOEXEC | os.EFD_NONBLOCK),175 .eventfd = try os.eventfd(1, os.EFD_CLOEXEC | os.EFD_NONBLOCK),
176 .epoll_op = os.EPOLL_CTL_ADD,176 .epoll_op = os.EPOLL_CTL_ADD,
177 },177 },
178 .next = undefined,178 .next = undefined,
...@@ -180,17 +180,17 @@ pub const Loop = struct {...@@ -180,17 +180,17 @@ pub const Loop = struct {
180 self.available_eventfd_resume_nodes.push(eventfd_node);180 self.available_eventfd_resume_nodes.push(eventfd_node);
181 }181 }
182182
183 self.os_data.epollfd = try os.linuxEpollCreate(os.EPOLL_CLOEXEC);183 self.os_data.epollfd = try os.epoll_create1(os.EPOLL_CLOEXEC);
184 errdefer os.close(self.os_data.epollfd);184 errdefer os.close(self.os_data.epollfd);
185185
186 self.os_data.final_eventfd = try os.linuxEventFd(0, os.EFD_CLOEXEC | os.EFD_NONBLOCK);186 self.os_data.final_eventfd = try os.eventfd(0, os.EFD_CLOEXEC | os.EFD_NONBLOCK);
187 errdefer os.close(self.os_data.final_eventfd);187 errdefer os.close(self.os_data.final_eventfd);
188188
189 self.os_data.final_eventfd_event = os.epoll_event{189 self.os_data.final_eventfd_event = os.epoll_event{
190 .events = os.EPOLLIN,190 .events = os.EPOLLIN,
191 .data = os.epoll_data{ .ptr = @ptrToInt(&self.final_resume_node) },191 .data = os.epoll_data{ .ptr = @ptrToInt(&self.final_resume_node) },
192 };192 };
193 try os.linuxEpollCtl(193 try os.epoll_ctl(
194 self.os_data.epollfd,194 self.os_data.epollfd,
195 os.EPOLL_CTL_ADD,195 os.EPOLL_CTL_ADD,
196 self.os_data.final_eventfd,196 self.os_data.final_eventfd,
...@@ -211,7 +211,7 @@ pub const Loop = struct {...@@ -211,7 +211,7 @@ pub const Loop = struct {
211 var extra_thread_index: usize = 0;211 var extra_thread_index: usize = 0;
212 errdefer {212 errdefer {
213 // writing 8 bytes to an eventfd cannot fail213 // writing 8 bytes to an eventfd cannot fail
214 os.posixWrite(self.os_data.final_eventfd, wakeup_bytes) catch unreachable;214 os.write(self.os_data.final_eventfd, wakeup_bytes) catch unreachable;
215 while (extra_thread_index != 0) {215 while (extra_thread_index != 0) {
216 extra_thread_index -= 1;216 extra_thread_index -= 1;
217 self.extra_threads[extra_thread_index].wait();217 self.extra_threads[extra_thread_index].wait();
...@@ -417,11 +417,11 @@ pub const Loop = struct {...@@ -417,11 +417,11 @@ pub const Loop = struct {
417 .events = flags,417 .events = flags,
418 .data = os.linux.epoll_data{ .ptr = @ptrToInt(resume_node) },418 .data = os.linux.epoll_data{ .ptr = @ptrToInt(resume_node) },
419 };419 };
420 try os.linuxEpollCtl(self.os_data.epollfd, op, fd, &ev);420 try os.epoll_ctl(self.os_data.epollfd, op, fd, &ev);
421 }421 }
422422
423 pub fn linuxRemoveFd(self: *Loop, fd: i32) void {423 pub fn linuxRemoveFd(self: *Loop, fd: i32) void {
424 os.linuxEpollCtl(self.os_data.epollfd, os.linux.EPOLL_CTL_DEL, fd, undefined) catch {};424 os.epoll_ctl(self.os_data.epollfd, os.linux.EPOLL_CTL_DEL, fd, undefined) catch {};
425 self.finishOneEvent();425 self.finishOneEvent();
426 }426 }
427427
...@@ -626,7 +626,7 @@ pub const Loop = struct {...@@ -626,7 +626,7 @@ pub const Loop = struct {
626 builtin.Os.linux => {626 builtin.Os.linux => {
627 self.posixFsRequest(&self.os_data.fs_end_request);627 self.posixFsRequest(&self.os_data.fs_end_request);
628 // writing 8 bytes to an eventfd cannot fail628 // writing 8 bytes to an eventfd cannot fail
629 os.posixWrite(self.os_data.final_eventfd, wakeup_bytes) catch unreachable;629 os.write(self.os_data.final_eventfd, wakeup_bytes) catch unreachable;
630 return;630 return;
631 },631 },
632 builtin.Os.macosx, builtin.Os.freebsd, builtin.Os.netbsd => {632 builtin.Os.macosx, builtin.Os.freebsd, builtin.Os.netbsd => {
...@@ -666,7 +666,7 @@ pub const Loop = struct {...@@ -666,7 +666,7 @@ pub const Loop = struct {
666 builtin.Os.linux => {666 builtin.Os.linux => {
667 // only process 1 event so we don't steal from other threads667 // only process 1 event so we don't steal from other threads
668 var events: [1]os.linux.epoll_event = undefined;668 var events: [1]os.linux.epoll_event = undefined;
669 const count = os.linuxEpollWait(self.os_data.epollfd, events[0..], -1);669 const count = os.epoll_wait(self.os_data.epollfd, events[0..], -1);
670 for (events[0..count]) |ev| {670 for (events[0..count]) |ev| {
671 const resume_node = @intToPtr(*ResumeNode, ev.data.ptr);671 const resume_node = @intToPtr(*ResumeNode, ev.data.ptr);
672 const handle = resume_node.handle;672 const handle = resume_node.handle;
...@@ -783,10 +783,10 @@ pub const Loop = struct {...@@ -783,10 +783,10 @@ pub const Loop = struct {
783 switch (node.data.msg) {783 switch (node.data.msg) {
784 @TagType(fs.Request.Msg).End => return,784 @TagType(fs.Request.Msg).End => return,
785 @TagType(fs.Request.Msg).PWriteV => |*msg| {785 @TagType(fs.Request.Msg).PWriteV => |*msg| {
786 msg.result = os.posix_pwritev(msg.fd, msg.iov.ptr, msg.iov.len, msg.offset);786 msg.result = os.pwritev(msg.fd, msg.iov, msg.offset);
787 },787 },
788 @TagType(fs.Request.Msg).PReadV => |*msg| {788 @TagType(fs.Request.Msg).PReadV => |*msg| {
789 msg.result = os.posix_preadv(msg.fd, msg.iov.ptr, msg.iov.len, msg.offset);789 msg.result = os.preadv(msg.fd, msg.iov, msg.offset);
790 },790 },
791 @TagType(fs.Request.Msg).Open => |*msg| {791 @TagType(fs.Request.Msg).Open => |*msg| {
792 msg.result = os.openC(msg.path.ptr, msg.flags, msg.mode);792 msg.result = os.openC(msg.path.ptr, msg.flags, msg.mode);
...@@ -800,7 +800,7 @@ pub const Loop = struct {...@@ -800,7 +800,7 @@ pub const Loop = struct {
800 break :blk;800 break :blk;
801 };801 };
802 defer os.close(fd);802 defer os.close(fd);
803 msg.result = os.posixWrite(fd, msg.contents);803 msg.result = os.write(fd, msg.contents);
804 },804 },
805 }805 }
806 switch (node.data.finish) {806 switch (node.data.finish) {
std/event/net.zig+15-12
...@@ -45,13 +45,13 @@ pub const Server = struct {...@@ -45,13 +45,13 @@ pub const Server = struct {
45 ) !void {45 ) !void {
46 self.handleRequestFn = handleRequestFn;46 self.handleRequestFn = handleRequestFn;
4747
48 const sockfd = try os.posixSocket(os.AF_INET, os.SOCK_STREAM | os.SOCK_CLOEXEC | os.SOCK_NONBLOCK, os.PROTO_tcp);48 const sockfd = try os.socket(os.AF_INET, os.SOCK_STREAM | os.SOCK_CLOEXEC | os.SOCK_NONBLOCK, os.PROTO_tcp);
49 errdefer os.close(sockfd);49 errdefer os.close(sockfd);
50 self.sockfd = sockfd;50 self.sockfd = sockfd;
5151
52 try os.posixBind(sockfd, &address.os_addr);52 try os.bind(sockfd, &address.os_addr);
53 try os.posixListen(sockfd, os.SOMAXCONN);53 try os.listen(sockfd, os.SOMAXCONN);
54 self.listen_address = std.net.Address.initPosix(try os.posixGetSockName(sockfd));54 self.listen_address = std.net.Address.initPosix(try os.getsockname(sockfd));
5555
56 self.accept_coro = try async<self.loop.allocator> Server.handler(self);56 self.accept_coro = try async<self.loop.allocator> Server.handler(self);
57 errdefer cancel self.accept_coro.?;57 errdefer cancel self.accept_coro.?;
...@@ -64,7 +64,10 @@ pub const Server = struct {...@@ -64,7 +64,10 @@ pub const Server = struct {
64 /// Stop listening64 /// Stop listening
65 pub fn close(self: *Server) void {65 pub fn close(self: *Server) void {
66 self.loop.linuxRemoveFd(self.sockfd.?);66 self.loop.linuxRemoveFd(self.sockfd.?);
67 os.close(self.sockfd.?);67 if (self.sockfd) |fd| {
68 os.close(fd);
69 self.sockfd = null;
70 }
68 }71 }
6972
70 pub fn deinit(self: *Server) void {73 pub fn deinit(self: *Server) void {
...@@ -76,7 +79,7 @@ pub const Server = struct {...@@ -76,7 +79,7 @@ pub const Server = struct {
76 while (true) {79 while (true) {
77 var accepted_addr: std.net.Address = undefined;80 var accepted_addr: std.net.Address = undefined;
78 // TODO just inline the following function here and don't expose it as posixAsyncAccept81 // TODO just inline the following function here and don't expose it as posixAsyncAccept
79 if (os.posixAsyncAccept(self.sockfd.?, &accepted_addr.os_addr, os.SOCK_NONBLOCK | os.SOCK_CLOEXEC)) |accepted_fd| {82 if (os.accept4_async(self.sockfd.?, &accepted_addr.os_addr, os.SOCK_NONBLOCK | os.SOCK_CLOEXEC)) |accepted_fd| {
80 if (accepted_fd == -1) {83 if (accepted_fd == -1) {
81 // would block84 // would block
82 suspend; // we will get resumed by epoll_wait in the event loop85 suspend; // we will get resumed by epoll_wait in the event loop
...@@ -105,7 +108,7 @@ pub const Server = struct {...@@ -105,7 +108,7 @@ pub const Server = struct {
105};108};
106109
107pub async fn connectUnixSocket(loop: *Loop, path: []const u8) !i32 {110pub async fn connectUnixSocket(loop: *Loop, path: []const u8) !i32 {
108 const sockfd = try os.posixSocket(111 const sockfd = try os.socket(
109 os.AF_UNIX,112 os.AF_UNIX,
110 os.SOCK_STREAM | os.SOCK_CLOEXEC | os.SOCK_NONBLOCK,113 os.SOCK_STREAM | os.SOCK_CLOEXEC | os.SOCK_NONBLOCK,
111 0,114 0,
...@@ -120,9 +123,9 @@ pub async fn connectUnixSocket(loop: *Loop, path: []const u8) !i32 {...@@ -120,9 +123,9 @@ pub async fn connectUnixSocket(loop: *Loop, path: []const u8) !i32 {
120 if (path.len > @typeOf(sock_addr.path).len) return error.NameTooLong;123 if (path.len > @typeOf(sock_addr.path).len) return error.NameTooLong;
121 mem.copy(u8, sock_addr.path[0..], path);124 mem.copy(u8, sock_addr.path[0..], path);
122 const size = @intCast(u32, @sizeOf(os.sa_family_t) + path.len);125 const size = @intCast(u32, @sizeOf(os.sa_family_t) + path.len);
123 try os.posixConnectAsync(sockfd, &sock_addr, size);126 try os.connect_async(sockfd, &sock_addr, size);
124 try await try async loop.linuxWaitFd(sockfd, os.EPOLLIN | os.EPOLLOUT | os.EPOLLET);127 try await try async loop.linuxWaitFd(sockfd, os.EPOLLIN | os.EPOLLOUT | os.EPOLLET);
125 try os.posixGetSockOptConnectError(sockfd);128 try os.getsockoptError(sockfd);
126129
127 return sockfd;130 return sockfd;
128}131}
...@@ -249,12 +252,12 @@ pub async fn readv(loop: *Loop, fd: fd_t, data: []const []u8) !usize {...@@ -249,12 +252,12 @@ pub async fn readv(loop: *Loop, fd: fd_t, data: []const []u8) !usize {
249pub async fn connect(loop: *Loop, _address: *const std.net.Address) !File {252pub async fn connect(loop: *Loop, _address: *const std.net.Address) !File {
250 var address = _address.*; // TODO https://github.com/ziglang/zig/issues/1592253 var address = _address.*; // TODO https://github.com/ziglang/zig/issues/1592
251254
252 const sockfd = try os.posixSocket(os.AF_INET, os.SOCK_STREAM | os.SOCK_CLOEXEC | os.SOCK_NONBLOCK, os.PROTO_tcp);255 const sockfd = try os.socket(os.AF_INET, os.SOCK_STREAM | os.SOCK_CLOEXEC | os.SOCK_NONBLOCK, os.PROTO_tcp);
253 errdefer os.close(sockfd);256 errdefer os.close(sockfd);
254257
255 try os.posixConnectAsync(sockfd, &address.os_addr, @sizeOf(os.sockaddr_in));258 try os.connect_async(sockfd, &address.os_addr, @sizeOf(os.sockaddr_in));
256 try await try async loop.linuxWaitFd(sockfd, os.EPOLLIN | os.EPOLLOUT | os.EPOLLET);259 try await try async loop.linuxWaitFd(sockfd, os.EPOLLIN | os.EPOLLOUT | os.EPOLLET);
257 try os.posixGetSockOptConnectError(sockfd);260 try os.getsockoptError(sockfd);
258261
259 return File.openHandle(sockfd);262 return File.openHandle(sockfd);
260}263}
std/fs.zig+4-22
...@@ -38,24 +38,6 @@ pub const MAX_PATH_BYTES = switch (builtin.os) {...@@ -38,24 +38,6 @@ pub const MAX_PATH_BYTES = switch (builtin.os) {
38 else => @compileError("Unsupported OS"),38 else => @compileError("Unsupported OS"),
39};39};
4040
41/// The result is a slice of `out_buffer`, from index `0`.
42pub fn getCwd(out_buffer: *[MAX_PATH_BYTES]u8) ![]u8 {
43 return os.getcwd(out_buffer);
44}
45
46/// Caller must free the returned memory.
47pub fn getCwdAlloc(allocator: *Allocator) ![]u8 {
48 var buf: [MAX_PATH_BYTES]u8 = undefined;
49 return mem.dupe(allocator, u8, try os.getcwd(&buf));
50}
51
52test "getCwdAlloc" {
53 // at least call it so it gets compiled
54 var buf: [1000]u8 = undefined;
55 const allocator = &std.heap.FixedBufferAllocator.init(&buf).allocator;
56 _ = getCwdAlloc(allocator) catch {};
57}
58
59// here we replace the standard +/ with -_ so that it can be used in a file name41// here we replace the standard +/ with -_ so that it can be used in a file name
60const b64_fs_encoder = base64.Base64Encoder.init("ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789-_", base64.standard_pad_char);42const b64_fs_encoder = base64.Base64Encoder.init("ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789-_", base64.standard_pad_char);
6143
...@@ -260,17 +242,17 @@ pub fn makePath(allocator: *Allocator, full_path: []const u8) !void {...@@ -260,17 +242,17 @@ pub fn makePath(allocator: *Allocator, full_path: []const u8) !void {
260242
261/// Returns `error.DirNotEmpty` if the directory is not empty.243/// Returns `error.DirNotEmpty` if the directory is not empty.
262/// To delete a directory recursively, see `deleteTree`.244/// To delete a directory recursively, see `deleteTree`.
263pub fn deleteDir(dir_path: []const u8) DeleteDirError!void {245pub fn deleteDir(dir_path: []const u8) !void {
264 return os.rmdir(dir_path);246 return os.rmdir(dir_path);
265}247}
266248
267/// Same as `deleteDir` except the parameter is a null-terminated UTF8-encoded string.249/// Same as `deleteDir` except the parameter is a null-terminated UTF8-encoded string.
268pub fn deleteDirC(dir_path: [*]const u8) DeleteDirError!void {250pub fn deleteDirC(dir_path: [*]const u8) !void {
269 return os.rmdirC(dir_path);251 return os.rmdirC(dir_path);
270}252}
271253
272/// Same as `deleteDir` except the parameter is a null-terminated UTF16LE-encoded string.254/// Same as `deleteDir` except the parameter is a null-terminated UTF16LE-encoded string.
273pub fn deleteDirW(dir_path: [*]const u16) DeleteDirError!void {255pub fn deleteDirW(dir_path: [*]const u16) !void {
274 return os.rmdirW(dir_path);256 return os.rmdirW(dir_path);
275}257}
276258
...@@ -362,7 +344,7 @@ pub fn deleteTree(allocator: *Allocator, full_path: []const u8) DeleteTreeError!...@@ -362,7 +344,7 @@ pub fn deleteTree(allocator: *Allocator, full_path: []const u8) DeleteTreeError!
362 };344 };
363 defer dir.close();345 defer dir.close();
364346
365 var full_entry_buf = ArrayList(u8).init(allocator);347 var full_entry_buf = std.ArrayList(u8).init(allocator);
366 defer full_entry_buf.deinit();348 defer full_entry_buf.deinit();
367349
368 while (try dir.next()) |entry| {350 while (try dir.next()) |entry| {
std/fs/file.zig+9-6
...@@ -137,24 +137,27 @@ pub const File = struct {...@@ -137,24 +137,27 @@ pub const File = struct {
137137
138 /// Test for the existence of `path`.138 /// Test for the existence of `path`.
139 /// `path` is UTF8-encoded.139 /// `path` is UTF8-encoded.
140 pub fn exists(path: []const u8) !void {140 /// In general it is recommended to avoid this function. For example,
141 /// instead of testing if a file exists and then opening it, just
142 /// open it and handle the error for file not found.
143 pub fn access(path: []const u8) !void {
141 return os.access(path, os.F_OK);144 return os.access(path, os.F_OK);
142 }145 }
143146
144 /// Same as `exists` except the parameter is null-terminated.147 /// Same as `access` except the parameter is null-terminated.
145 pub fn existsC(path: [*]const u8) !void {148 pub fn accessC(path: [*]const u8) !void {
146 return os.accessC(path, os.F_OK);149 return os.accessC(path, os.F_OK);
147 }150 }
148151
149 /// Same as `exists` except the parameter is null-terminated UTF16LE-encoded.152 /// Same as `access` except the parameter is null-terminated UTF16LE-encoded.
150 pub fn existsW(path: [*]const u16) !void {153 pub fn accessW(path: [*]const u16) !void {
151 return os.accessW(path, os.F_OK);154 return os.accessW(path, os.F_OK);
152 }155 }
153156
154 /// Upon success, the stream is in an uninitialized state. To continue using it,157 /// Upon success, the stream is in an uninitialized state. To continue using it,
155 /// you must use the open() function.158 /// you must use the open() function.
156 pub fn close(self: File) void {159 pub fn close(self: File) void {
157 os.close(self.handle);160 return os.close(self.handle);
158 }161 }
159162
160 /// Test whether the file refers to a terminal.163 /// Test whether the file refers to a terminal.
std/fs/path.zig+8-7
...@@ -9,6 +9,7 @@ const Allocator = mem.Allocator;...@@ -9,6 +9,7 @@ const Allocator = mem.Allocator;
9const math = std.math;9const math = std.math;
10const windows = std.os.windows;10const windows = std.os.windows;
11const fs = std.fs;11const fs = std.fs;
12const process = std.process;
1213
13pub const sep_windows = '\\';14pub const sep_windows = '\\';
14pub const sep_posix = '/';15pub const sep_posix = '/';
...@@ -390,7 +391,7 @@ pub fn resolve(allocator: *Allocator, paths: []const []const u8) ![]u8 {...@@ -390,7 +391,7 @@ pub fn resolve(allocator: *Allocator, paths: []const []const u8) ![]u8 {
390pub fn resolveWindows(allocator: *Allocator, paths: []const []const u8) ![]u8 {391pub fn resolveWindows(allocator: *Allocator, paths: []const []const u8) ![]u8 {
391 if (paths.len == 0) {392 if (paths.len == 0) {
392 assert(windows.is_the_target); // resolveWindows called on non windows can't use getCwd393 assert(windows.is_the_target); // resolveWindows called on non windows can't use getCwd
393 return fs.getCwdAlloc(allocator);394 return process.getCwdAlloc(allocator);
394 }395 }
395396
396 // determine which disk designator we will result with, if any397 // determine which disk designator we will result with, if any
...@@ -485,7 +486,7 @@ pub fn resolveWindows(allocator: *Allocator, paths: []const []const u8) ![]u8 {...@@ -485,7 +486,7 @@ pub fn resolveWindows(allocator: *Allocator, paths: []const []const u8) ![]u8 {
485 },486 },
486 WindowsPath.Kind.None => {487 WindowsPath.Kind.None => {
487 assert(windows.is_the_target); // resolveWindows called on non windows can't use getCwd488 assert(windows.is_the_target); // resolveWindows called on non windows can't use getCwd
488 const cwd = try fs.getCwdAlloc(allocator);489 const cwd = try process.getCwdAlloc(allocator);
489 defer allocator.free(cwd);490 defer allocator.free(cwd);
490 const parsed_cwd = windowsParsePath(cwd);491 const parsed_cwd = windowsParsePath(cwd);
491 result = try allocator.alloc(u8, max_size + parsed_cwd.disk_designator.len + 1);492 result = try allocator.alloc(u8, max_size + parsed_cwd.disk_designator.len + 1);
...@@ -501,7 +502,7 @@ pub fn resolveWindows(allocator: *Allocator, paths: []const []const u8) ![]u8 {...@@ -501,7 +502,7 @@ pub fn resolveWindows(allocator: *Allocator, paths: []const []const u8) ![]u8 {
501 } else {502 } else {
502 assert(windows.is_the_target); // resolveWindows called on non windows can't use getCwd503 assert(windows.is_the_target); // resolveWindows called on non windows can't use getCwd
503 // TODO call get cwd for the result_disk_designator instead of the global one504 // TODO call get cwd for the result_disk_designator instead of the global one
504 const cwd = try fs.getCwdAlloc(allocator);505 const cwd = try process.getCwdAlloc(allocator);
505 defer allocator.free(cwd);506 defer allocator.free(cwd);
506507
507 result = try allocator.alloc(u8, max_size + cwd.len + 1);508 result = try allocator.alloc(u8, max_size + cwd.len + 1);
...@@ -571,7 +572,7 @@ pub fn resolveWindows(allocator: *Allocator, paths: []const []const u8) ![]u8 {...@@ -571,7 +572,7 @@ pub fn resolveWindows(allocator: *Allocator, paths: []const []const u8) ![]u8 {
571pub fn resolvePosix(allocator: *Allocator, paths: []const []const u8) ![]u8 {572pub fn resolvePosix(allocator: *Allocator, paths: []const []const u8) ![]u8 {
572 if (paths.len == 0) {573 if (paths.len == 0) {
573 assert(!windows.is_the_target); // resolvePosix called on windows can't use getCwd574 assert(!windows.is_the_target); // resolvePosix called on windows can't use getCwd
574 return fs.getCwdAlloc(allocator);575 return process.getCwdAlloc(allocator);
575 }576 }
576577
577 var first_index: usize = 0;578 var first_index: usize = 0;
...@@ -593,7 +594,7 @@ pub fn resolvePosix(allocator: *Allocator, paths: []const []const u8) ![]u8 {...@@ -593,7 +594,7 @@ pub fn resolvePosix(allocator: *Allocator, paths: []const []const u8) ![]u8 {
593 result = try allocator.alloc(u8, max_size);594 result = try allocator.alloc(u8, max_size);
594 } else {595 } else {
595 assert(!windows.is_the_target); // resolvePosix called on windows can't use getCwd596 assert(!windows.is_the_target); // resolvePosix called on windows can't use getCwd
596 const cwd = try fs.getCwdAlloc(allocator);597 const cwd = try process.getCwdAlloc(allocator);
597 defer allocator.free(cwd);598 defer allocator.free(cwd);
598 result = try allocator.alloc(u8, max_size + cwd.len + 1);599 result = try allocator.alloc(u8, max_size + cwd.len + 1);
599 mem.copy(u8, result, cwd);600 mem.copy(u8, result, cwd);
...@@ -632,7 +633,7 @@ pub fn resolvePosix(allocator: *Allocator, paths: []const []const u8) ![]u8 {...@@ -632,7 +633,7 @@ pub fn resolvePosix(allocator: *Allocator, paths: []const []const u8) ![]u8 {
632}633}
633634
634test "resolve" {635test "resolve" {
635 const cwd = try fs.getCwdAlloc(debug.global_allocator);636 const cwd = try process.getCwdAlloc(debug.global_allocator);
636 if (windows.is_the_target) {637 if (windows.is_the_target) {
637 if (windowsParsePath(cwd).kind == WindowsPath.Kind.Drive) {638 if (windowsParsePath(cwd).kind == WindowsPath.Kind.Drive) {
638 cwd[0] = asciiUpper(cwd[0]);639 cwd[0] = asciiUpper(cwd[0]);
...@@ -646,7 +647,7 @@ test "resolve" {...@@ -646,7 +647,7 @@ test "resolve" {
646647
647test "resolveWindows" {648test "resolveWindows" {
648 if (windows.is_the_target) {649 if (windows.is_the_target) {
649 const cwd = try fs.getCwdAlloc(debug.global_allocator);650 const cwd = try process.getCwdAlloc(debug.global_allocator);
650 const parsed_cwd = windowsParsePath(cwd);651 const parsed_cwd = windowsParsePath(cwd);
651 {652 {
652 const result = testResolveWindows([][]const u8{ "/usr/local", "lib\\zig\\std\\array_list.zig" });653 const result = testResolveWindows([][]const u8{ "/usr/local", "lib\\zig\\std\\array_list.zig" });
std/heap.zig+1-1
...@@ -112,7 +112,7 @@ pub const DirectAllocator = struct {...@@ -112,7 +112,7 @@ pub const DirectAllocator = struct {
112 -1,112 -1,
113 0,113 0,
114 ) catch return error.OutOfMemory;114 ) catch return error.OutOfMemory;
115 if (alloc_size == n) return slice;115 if (alloc_size == n) return slice[0..n];
116116
117 const aligned_addr = mem.alignForward(@ptrToInt(slice.ptr), alignment);117 const aligned_addr = mem.alignForward(@ptrToInt(slice.ptr), alignment);
118118
std/io/test.zig+4-4
...@@ -7,7 +7,7 @@ const DefaultPrng = std.rand.DefaultPrng;...@@ -7,7 +7,7 @@ const DefaultPrng = std.rand.DefaultPrng;
7const expect = std.testing.expect;7const expect = std.testing.expect;
8const expectError = std.testing.expectError;8const expectError = std.testing.expectError;
9const mem = std.mem;9const mem = std.mem;
10const os = std.os;10const fs = std.fs;
11const File = std.fs.File;11const File = std.fs.File;
1212
13test "write a file, read it, then delete it" {13test "write a file, read it, then delete it" {
...@@ -58,7 +58,7 @@ test "write a file, read it, then delete it" {...@@ -58,7 +58,7 @@ test "write a file, read it, then delete it" {
58 expect(mem.eql(u8, contents["begin".len .. contents.len - "end".len], data));58 expect(mem.eql(u8, contents["begin".len .. contents.len - "end".len], data));
59 expect(mem.eql(u8, contents[contents.len - "end".len ..], "end"));59 expect(mem.eql(u8, contents[contents.len - "end".len ..], "end"));
60 }60 }
61 try os.deleteFile(tmp_file_name);61 try fs.deleteFile(tmp_file_name);
62}62}
6363
64test "BufferOutStream" {64test "BufferOutStream" {
...@@ -316,7 +316,7 @@ test "BitStreams with File Stream" {...@@ -316,7 +316,7 @@ test "BitStreams with File Stream" {
316316
317 expectError(error.EndOfStream, bit_stream.readBitsNoEof(u1, 1));317 expectError(error.EndOfStream, bit_stream.readBitsNoEof(u1, 1));
318 }318 }
319 try os.deleteFile(tmp_file_name);319 try fs.deleteFile(tmp_file_name);
320}320}
321321
322fn testIntSerializerDeserializer(comptime endian: builtin.Endian, comptime packing: io.Packing) !void {322fn testIntSerializerDeserializer(comptime endian: builtin.Endian, comptime packing: io.Packing) !void {
...@@ -596,7 +596,7 @@ test "c out stream" {...@@ -596,7 +596,7 @@ test "c out stream" {
596596
597 const filename = c"tmp_io_test_file.txt";597 const filename = c"tmp_io_test_file.txt";
598 const out_file = std.c.fopen(filename, c"w") orelse return error.UnableToOpenTestFile;598 const out_file = std.c.fopen(filename, c"w") orelse return error.UnableToOpenTestFile;
599 defer std.os.deleteFileC(filename) catch {};599 defer fs.deleteFileC(filename) catch {};
600600
601 const out_stream = &io.COutStream.init(out_file).stream;601 const out_stream = &io.COutStream.init(out_file).stream;
602 try out_stream.print("hi: {}\n", i32(123));602 try out_stream.print("hi: {}\n", i32(123));
std/os.zig+40-31
...@@ -284,7 +284,7 @@ pub fn read(fd: fd_t, buf: []u8) ReadError!usize {...@@ -284,7 +284,7 @@ pub fn read(fd: fd_t, buf: []u8) ReadError!usize {
284/// Number of bytes read is returned. Upon reading end-of-file, zero is returned.284/// Number of bytes read is returned. Upon reading end-of-file, zero is returned.
285/// This function is for blocking file descriptors only. For non-blocking, see285/// This function is for blocking file descriptors only. For non-blocking, see
286/// `preadvAsync`.286/// `preadvAsync`.
287pub fn preadv(fd: fd_t, iov: [*]const iovec, count: usize, offset: u64) ReadError!usize {287pub fn preadv(fd: fd_t, iov: []const iovec, offset: u64) ReadError!usize {
288 if (darwin.is_the_target) {288 if (darwin.is_the_target) {
289 // Darwin does not have preadv but it does have pread.289 // Darwin does not have preadv but it does have pread.
290 var off: usize = 0;290 var off: usize = 0;
...@@ -301,7 +301,7 @@ pub fn preadv(fd: fd_t, iov: [*]const iovec, count: usize, offset: u64) ReadErro...@@ -301,7 +301,7 @@ pub fn preadv(fd: fd_t, iov: [*]const iovec, count: usize, offset: u64) ReadErro
301 if (inner_off == v.iov_len) {301 if (inner_off == v.iov_len) {
302 iov_i += 1;302 iov_i += 1;
303 inner_off = 0;303 inner_off = 0;
304 if (iov_i == count) {304 if (iov_i == iov.len) {
305 return off;305 return off;
306 }306 }
307 }307 }
...@@ -323,9 +323,10 @@ pub fn preadv(fd: fd_t, iov: [*]const iovec, count: usize, offset: u64) ReadErro...@@ -323,9 +323,10 @@ pub fn preadv(fd: fd_t, iov: [*]const iovec, count: usize, offset: u64) ReadErro
323 }323 }
324 }324 }
325 while (true) {325 while (true) {
326 const rc = system.preadv(fd, iov, count, offset);326 // TODO handle the case when iov_len is too large and get rid of this @intCast
327 const rc = system.preadv(fd, iov.ptr, @intCast(u32, iov.len), offset);
327 switch (errno(rc)) {328 switch (errno(rc)) {
328 0 => return rc,329 0 => return @bitCast(usize, rc),
329 EINTR => continue,330 EINTR => continue,
330 EINVAL => unreachable,331 EINVAL => unreachable,
331 EFAULT => unreachable,332 EFAULT => unreachable,
...@@ -407,7 +408,7 @@ pub fn write(fd: fd_t, bytes: []const u8) WriteError!void {...@@ -407,7 +408,7 @@ pub fn write(fd: fd_t, bytes: []const u8) WriteError!void {
407/// Write multiple buffers to a file descriptor. Keeps trying if it gets interrupted.408/// Write multiple buffers to a file descriptor. Keeps trying if it gets interrupted.
408/// This function is for blocking file descriptors only. For non-blocking, see409/// This function is for blocking file descriptors only. For non-blocking, see
409/// `pwritevAsync`.410/// `pwritevAsync`.
410pub fn pwritev(fd: fd_t, iov: [*]const iovec_const, count: usize, offset: u64) WriteError!void {411pub fn pwritev(fd: fd_t, iov: []const iovec_const, offset: u64) WriteError!void {
411 if (darwin.is_the_target) {412 if (darwin.is_the_target) {
412 // Darwin does not have pwritev but it does have pwrite.413 // Darwin does not have pwritev but it does have pwrite.
413 var off: usize = 0;414 var off: usize = 0;
...@@ -424,7 +425,7 @@ pub fn pwritev(fd: fd_t, iov: [*]const iovec_const, count: usize, offset: u64) W...@@ -424,7 +425,7 @@ pub fn pwritev(fd: fd_t, iov: [*]const iovec_const, count: usize, offset: u64) W
424 if (inner_off == v.iov_len) {425 if (inner_off == v.iov_len) {
425 iov_i += 1;426 iov_i += 1;
426 inner_off = 0;427 inner_off = 0;
427 if (iov_i == count) {428 if (iov_i == iov.len) {
428 return;429 return;
429 }430 }
430 }431 }
...@@ -449,7 +450,8 @@ pub fn pwritev(fd: fd_t, iov: [*]const iovec_const, count: usize, offset: u64) W...@@ -449,7 +450,8 @@ pub fn pwritev(fd: fd_t, iov: [*]const iovec_const, count: usize, offset: u64) W
449 }450 }
450451
451 while (true) {452 while (true) {
452 const rc = system.pwritev(fd, iov, count, offset);453 // TODO handle the case when iov_len is too large and get rid of this @intCast
454 const rc = system.pwritev(fd, iov.ptr, @intCast(u32, iov.len), offset);
453 switch (errno(rc)) {455 switch (errno(rc)) {
454 0 => return,456 0 => return,
455 EINTR => continue,457 EINTR => continue,
...@@ -724,7 +726,7 @@ pub fn getcwd(out_buffer: []u8) GetCwdError![]u8 {...@@ -724,7 +726,7 @@ pub fn getcwd(out_buffer: []u8) GetCwdError![]u8 {
724 EINVAL => unreachable,726 EINVAL => unreachable,
725 ENOENT => return error.CurrentWorkingDirectoryUnlinked,727 ENOENT => return error.CurrentWorkingDirectoryUnlinked,
726 ERANGE => return error.NameTooLong,728 ERANGE => return error.NameTooLong,
727 else => return unexpectedErrno(err),729 else => return unexpectedErrno(@intCast(usize, err)),
728 }730 }
729}731}
730732
...@@ -1121,7 +1123,7 @@ pub fn readlinkC(file_path: [*]const u8, out_buffer: []u8) ReadLinkError![]u8 {...@@ -1121,7 +1123,7 @@ pub fn readlinkC(file_path: [*]const u8, out_buffer: []u8) ReadLinkError![]u8 {
1121 }1123 }
1122 const rc = system.readlink(file_path, out_buffer.ptr, out_buffer.len);1124 const rc = system.readlink(file_path, out_buffer.ptr, out_buffer.len);
1123 switch (errno(rc)) {1125 switch (errno(rc)) {
1124 0 => return out_buffer[0..rc],1126 0 => return out_buffer[0..@bitCast(usize, rc)],
1125 EACCES => return error.AccessDenied,1127 EACCES => return error.AccessDenied,
1126 EFAULT => unreachable,1128 EFAULT => unreachable,
1127 EINVAL => unreachable,1129 EINVAL => unreachable,
...@@ -1307,7 +1309,7 @@ pub const BindError = error{...@@ -1307,7 +1309,7 @@ pub const BindError = error{
13071309
1308/// addr is `*const T` where T is one of the sockaddr1310/// addr is `*const T` where T is one of the sockaddr
1309pub fn bind(fd: i32, addr: *const sockaddr) BindError!void {1311pub fn bind(fd: i32, addr: *const sockaddr) BindError!void {
1310 const rc = system.bind(fd, system, @sizeOf(sockaddr));1312 const rc = system.bind(fd, addr, @sizeOf(sockaddr));
1311 switch (errno(rc)) {1313 switch (errno(rc)) {
1312 0 => return,1314 0 => return,
1313 EACCES => return error.AccessDenied,1315 EACCES => return error.AccessDenied,
...@@ -1521,7 +1523,7 @@ pub fn epoll_wait(epfd: i32, events: []epoll_event, timeout: i32) usize {...@@ -1521,7 +1523,7 @@ pub fn epoll_wait(epfd: i32, events: []epoll_event, timeout: i32) usize {
1521 // TODO get rid of the @intCast1523 // TODO get rid of the @intCast
1522 const rc = system.epoll_wait(epfd, events.ptr, @intCast(u32, events.len), timeout);1524 const rc = system.epoll_wait(epfd, events.ptr, @intCast(u32, events.len), timeout);
1523 switch (errno(rc)) {1525 switch (errno(rc)) {
1524 0 => return rc,1526 0 => return @intCast(usize, rc),
1525 EINTR => continue,1527 EINTR => continue,
1526 EBADF => unreachable,1528 EBADF => unreachable,
1527 EFAULT => unreachable,1529 EFAULT => unreachable,
...@@ -1613,12 +1615,10 @@ pub const ConnectError = error{...@@ -1613,12 +1615,10 @@ pub const ConnectError = error{
1613/// Initiate a connection on a socket.1615/// Initiate a connection on a socket.
1614/// This is for blocking file descriptors only.1616/// This is for blocking file descriptors only.
1615/// For non-blocking, see `connect_async`.1617/// For non-blocking, see `connect_async`.
1616pub fn connect(sockfd: i32, sockaddr: *const sockaddr) ConnectError!void {1618pub fn connect(sockfd: i32, sock_addr: *sockaddr, len: socklen_t) ConnectError!void {
1617 while (true) {1619 while (true) {
1618 switch (errno(system.connect(sockfd, sockaddr, @sizeOf(sockaddr)))) {1620 switch (errno(system.connect(sockfd, sock_addr, @sizeOf(sockaddr)))) {
1619 0 => return,1621 0 => return,
1620 else => |err| return unexpectedErrno(err),
1621
1622 EACCES => return error.PermissionDenied,1622 EACCES => return error.PermissionDenied,
1623 EPERM => return error.PermissionDenied,1623 EPERM => return error.PermissionDenied,
1624 EADDRINUSE => return error.AddressInUse,1624 EADDRINUSE => return error.AddressInUse,
...@@ -1636,19 +1636,18 @@ pub fn connect(sockfd: i32, sockaddr: *const sockaddr) ConnectError!void {...@@ -1636,19 +1636,18 @@ pub fn connect(sockfd: i32, sockaddr: *const sockaddr) ConnectError!void {
1636 ENOTSOCK => unreachable, // The file descriptor sockfd does not refer to a socket.1636 ENOTSOCK => unreachable, // The file descriptor sockfd does not refer to a socket.
1637 EPROTOTYPE => unreachable, // The socket type does not support the requested communications protocol.1637 EPROTOTYPE => unreachable, // The socket type does not support the requested communications protocol.
1638 ETIMEDOUT => return error.ConnectionTimedOut,1638 ETIMEDOUT => return error.ConnectionTimedOut,
1639 else => |err| return unexpectedErrno(err),
1639 }1640 }
1640 }1641 }
1641}1642}
16421643
1643/// Same as `connect` except it is for blocking socket file descriptors.1644/// Same as `connect` except it is for blocking socket file descriptors.
1644/// It expects to receive EINPROGRESS`.1645/// It expects to receive EINPROGRESS`.
1645pub fn connect_async(sockfd: i32, sockaddr: *const c_void, len: u32) ConnectError!void {1646pub fn connect_async(sockfd: i32, sock_addr: *sockaddr, len: socklen_t) ConnectError!void {
1646 while (true) {1647 while (true) {
1647 switch (errno(system.connect(sockfd, sockaddr, len))) {1648 switch (errno(system.connect(sockfd, sock_addr, @sizeOf(sockaddr)))) {
1648 0, EINPROGRESS => return,
1649 EINTR => continue,1649 EINTR => continue,
1650 else => |err| return unexpectedErrno(err),1650 0, EINPROGRESS => return,
1651
1652 EACCES => return error.PermissionDenied,1651 EACCES => return error.PermissionDenied,
1653 EPERM => return error.PermissionDenied,1652 EPERM => return error.PermissionDenied,
1654 EADDRINUSE => return error.AddressInUse,1653 EADDRINUSE => return error.AddressInUse,
...@@ -1664,13 +1663,14 @@ pub fn connect_async(sockfd: i32, sockaddr: *const c_void, len: u32) ConnectErro...@@ -1664,13 +1663,14 @@ pub fn connect_async(sockfd: i32, sockaddr: *const c_void, len: u32) ConnectErro
1664 ENOTSOCK => unreachable, // The file descriptor sockfd does not refer to a socket.1663 ENOTSOCK => unreachable, // The file descriptor sockfd does not refer to a socket.
1665 EPROTOTYPE => unreachable, // The socket type does not support the requested communications protocol.1664 EPROTOTYPE => unreachable, // The socket type does not support the requested communications protocol.
1666 ETIMEDOUT => return error.ConnectionTimedOut,1665 ETIMEDOUT => return error.ConnectionTimedOut,
1666 else => |err| return unexpectedErrno(err),
1667 }1667 }
1668 }1668 }
1669}1669}
16701670
1671pub fn getsockoptError(sockfd: i32) ConnectError!void {1671pub fn getsockoptError(sockfd: i32) ConnectError!void {
1672 var err_code: i32 = undefined;1672 var err_code: u32 = undefined;
1673 var size: u32 = @sizeOf(i32);1673 var size: u32 = @sizeOf(u32);
1674 const rc = system.getsockopt(sockfd, SOL_SOCKET, SO_ERROR, @ptrCast([*]u8, &err_code), &size);1674 const rc = system.getsockopt(sockfd, SOL_SOCKET, SO_ERROR, @ptrCast([*]u8, &err_code), &size);
1675 assert(size == 4);1675 assert(size == 4);
1676 switch (errno(rc)) {1676 switch (errno(rc)) {
...@@ -1702,11 +1702,13 @@ pub fn getsockoptError(sockfd: i32) ConnectError!void {...@@ -1702,11 +1702,13 @@ pub fn getsockoptError(sockfd: i32) ConnectError!void {
1702 }1702 }
1703}1703}
17041704
1705pub fn waitpid(pid: i32, flags: u32) i32 {1705pub fn waitpid(pid: i32, flags: u32) u32 {
1706 var status: i32 = undefined;1706 // TODO allow implicit pointer cast from *u32 to *c_uint ?
1707 const Status = if (builtin.link_libc) c_uint else u32;
1708 var status: Status = undefined;
1707 while (true) {1709 while (true) {
1708 switch (errno(system.waitpid(pid, &status, flags))) {1710 switch (errno(system.waitpid(pid, &status, flags))) {
1709 0 => return status,1711 0 => return @bitCast(u32, status),
1710 EINTR => continue,1712 EINTR => continue,
1711 ECHILD => unreachable, // The process specified does not exist. It would be a race condition to handle this error.1713 ECHILD => unreachable, // The process specified does not exist. It would be a race condition to handle this error.
1712 EINVAL => unreachable, // The options argument was invalid1714 EINVAL => unreachable, // The options argument was invalid
...@@ -1892,11 +1894,19 @@ pub fn fork() ForkError!pid_t {...@@ -1892,11 +1894,19 @@ pub fn fork() ForkError!pid_t {
1892}1894}
18931895
1894pub const MMapError = error{1896pub const MMapError = error{
1897 /// The underlying filesystem of the specified file does not support memory mapping.
1898 MemoryMappingNotSupported,
1899
1900 /// A file descriptor refers to a non-regular file. Or a file mapping was requested,
1901 /// but the file descriptor is not open for reading. Or `MAP_SHARED` was requested
1902 /// and `PROT_WRITE` is set, but the file descriptor is not open in `O_RDWR` mode.
1903 /// Or `PROT_WRITE` is set, but the file is append-only.
1895 AccessDenied,1904 AccessDenied,
1905
1906 /// The `prot` argument asks for `PROT_EXEC` but the mapped area belongs to a file on
1907 /// a filesystem that was mounted no-exec.
1896 PermissionDenied,1908 PermissionDenied,
1897 LockedMemoryLimitExceeded,1909 LockedMemoryLimitExceeded,
1898 SystemFdQuotaExceeded,
1899 MemoryMappingNotSupported,
1900 OutOfMemory,1910 OutOfMemory,
1901 Unexpected,1911 Unexpected,
1902};1912};
...@@ -1932,7 +1942,6 @@ pub fn mmap(...@@ -1932,7 +1942,6 @@ pub fn mmap(
1932 EAGAIN => return error.LockedMemoryLimitExceeded,1942 EAGAIN => return error.LockedMemoryLimitExceeded,
1933 EBADF => unreachable, // Always a race condition.1943 EBADF => unreachable, // Always a race condition.
1934 EOVERFLOW => unreachable, // The number of pages used for length + offset would overflow.1944 EOVERFLOW => unreachable, // The number of pages used for length + offset would overflow.
1935 ENFILE => return error.SystemFdQuotaExceeded,
1936 ENODEV => return error.MemoryMappingNotSupported,1945 ENODEV => return error.MemoryMappingNotSupported,
1937 EINVAL => unreachable, // Invalid parameters to mmap()1946 EINVAL => unreachable, // Invalid parameters to mmap()
1938 ENOMEM => return error.OutOfMemory,1947 ENOMEM => return error.OutOfMemory,
...@@ -2265,7 +2274,7 @@ pub fn realpathC(pathname: [*]const u8, out_buffer: *[MAX_PATH_BYTES]u8) RealPat...@@ -2265,7 +2274,7 @@ pub fn realpathC(pathname: [*]const u8, out_buffer: *[MAX_PATH_BYTES]u8) RealPat
2265 ENAMETOOLONG => return error.NameTooLong,2274 ENAMETOOLONG => return error.NameTooLong,
2266 ELOOP => return error.SymLinkLoop,2275 ELOOP => return error.SymLinkLoop,
2267 EIO => return error.InputOutput,2276 EIO => return error.InputOutput,
2268 else => |err| return unexpectedErrno(err),2277 else => |err| return unexpectedErrno(@intCast(usize, err)),
2269 };2278 };
2270 return mem.toSlice(u8, result_path);2279 return mem.toSlice(u8, result_path);
2271}2280}
...@@ -2349,7 +2358,7 @@ pub fn clock_gettime(clk_id: i32, tp: *timespec) ClockGetTimeError!void {...@@ -2349,7 +2358,7 @@ pub fn clock_gettime(clk_id: i32, tp: *timespec) ClockGetTimeError!void {
2349}2358}
23502359
2351pub fn clock_getres(clk_id: i32, res: *timespec) ClockGetTimeError!void {2360pub fn clock_getres(clk_id: i32, res: *timespec) ClockGetTimeError!void {
2352 switch (errno(system.clock_getres(clk_id, tp))) {2361 switch (errno(system.clock_getres(clk_id, res))) {
2353 0 => return,2362 0 => return,
2354 EFAULT => unreachable,2363 EFAULT => unreachable,
2355 EINVAL => return error.UnsupportedClock,2364 EINVAL => return error.UnsupportedClock,
...@@ -2364,7 +2373,7 @@ pub const SchedGetAffinityError = error{...@@ -2364,7 +2373,7 @@ pub const SchedGetAffinityError = error{
23642373
2365pub fn sched_getaffinity(pid: pid_t) SchedGetAffinityError!cpu_set_t {2374pub fn sched_getaffinity(pid: pid_t) SchedGetAffinityError!cpu_set_t {
2366 var set: cpu_set_t = undefined;2375 var set: cpu_set_t = undefined;
2367 switch (errno(system.sched_getaffinity(pid, &set))) {2376 switch (errno(system.sched_getaffinity(pid, @sizeOf(cpu_set_t), &set))) {
2368 0 => return set,2377 0 => return set,
2369 EFAULT => unreachable,2378 EFAULT => unreachable,
2370 EINVAL => unreachable,2379 EINVAL => unreachable,
std/os/bits/darwin.zig+8-8
...@@ -219,7 +219,7 @@ pub const MAP_NOCACHE = 0x0400;...@@ -219,7 +219,7 @@ pub const MAP_NOCACHE = 0x0400;
219219
220/// don't reserve needed swap area220/// don't reserve needed swap area
221pub const MAP_NORESERVE = 0x0040;221pub const MAP_NORESERVE = 0x0040;
222pub const MAP_FAILED = maxInt(usize);222pub const MAP_FAILED = @intToPtr(*c_void, maxInt(usize));
223223
224/// [XSI] no hang in wait/no child to reap224/// [XSI] no hang in wait/no child to reap
225pub const WNOHANG = 0x00000001;225pub const WNOHANG = 0x00000001;
...@@ -749,26 +749,26 @@ pub const IPPROTO_UDP = 17;...@@ -749,26 +749,26 @@ pub const IPPROTO_UDP = 17;
749pub const IPPROTO_IP = 0;749pub const IPPROTO_IP = 0;
750pub const IPPROTO_IPV6 = 41;750pub const IPPROTO_IPV6 = 41;
751751
752fn wstatus(x: i32) i32 {752fn wstatus(x: u32) u32 {
753 return x & 0o177;753 return x & 0o177;
754}754}
755const wstopped = 0o177;755const wstopped = 0o177;
756pub fn WEXITSTATUS(x: i32) i32 {756pub fn WEXITSTATUS(x: u32) u32 {
757 return x >> 8;757 return x >> 8;
758}758}
759pub fn WTERMSIG(x: i32) i32 {759pub fn WTERMSIG(x: u32) u32 {
760 return wstatus(x);760 return wstatus(x);
761}761}
762pub fn WSTOPSIG(x: i32) i32 {762pub fn WSTOPSIG(x: u32) u32 {
763 return x >> 8;763 return x >> 8;
764}764}
765pub fn WIFEXITED(x: i32) bool {765pub fn WIFEXITED(x: u32) bool {
766 return wstatus(x) == 0;766 return wstatus(x) == 0;
767}767}
768pub fn WIFSTOPPED(x: i32) bool {768pub fn WIFSTOPPED(x: u32) bool {
769 return wstatus(x) == wstopped and WSTOPSIG(x) != 0x13;769 return wstatus(x) == wstopped and WSTOPSIG(x) != 0x13;
770}770}
771pub fn WIFSIGNALED(x: i32) bool {771pub fn WIFSIGNALED(x: u32) bool {
772 return wstatus(x) != wstopped and wstatus(x) != 0;772 return wstatus(x) != wstopped and wstatus(x) != 0;
773}773}
774774
std/os/bits/freebsd.zig+11-17
...@@ -161,7 +161,7 @@ pub const CLOCK_SECOND = 13;...@@ -161,7 +161,7 @@ pub const CLOCK_SECOND = 13;
161pub const CLOCK_THREAD_CPUTIME_ID = 14;161pub const CLOCK_THREAD_CPUTIME_ID = 14;
162pub const CLOCK_PROCESS_CPUTIME_ID = 15;162pub const CLOCK_PROCESS_CPUTIME_ID = 15;
163163
164pub const MAP_FAILED = maxInt(usize);164pub const MAP_FAILED = @intToPtr(*c_void, maxInt(usize));
165pub const MAP_SHARED = 0x0001;165pub const MAP_SHARED = 0x0001;
166pub const MAP_PRIVATE = 0x0002;166pub const MAP_PRIVATE = 0x0002;
167pub const MAP_FIXED = 0x0010;167pub const MAP_FIXED = 0x0010;
...@@ -644,29 +644,23 @@ pub const TIOCGPKT = 0x80045438;...@@ -644,29 +644,23 @@ pub const TIOCGPKT = 0x80045438;
644pub const TIOCGPTLCK = 0x80045439;644pub const TIOCGPTLCK = 0x80045439;
645pub const TIOCGEXCL = 0x80045440;645pub const TIOCGEXCL = 0x80045440;
646646
647fn unsigned(s: i32) u32 {647pub fn WEXITSTATUS(s: u32) u32 {
648 return @bitCast(u32, s);648 return (s & 0xff00) >> 8;
649}649}
650fn signed(s: u32) i32 {650pub fn WTERMSIG(s: u32) u32 {
651 return @bitCast(i32, s);651 return s & 0x7f;
652}652}
653pub fn WEXITSTATUS(s: i32) i32 {653pub fn WSTOPSIG(s: u32) u32 {
654 return signed((unsigned(s) & 0xff00) >> 8);
655}
656pub fn WTERMSIG(s: i32) i32 {
657 return signed(unsigned(s) & 0x7f);
658}
659pub fn WSTOPSIG(s: i32) i32 {
660 return WEXITSTATUS(s);654 return WEXITSTATUS(s);
661}655}
662pub fn WIFEXITED(s: i32) bool {656pub fn WIFEXITED(s: u32) bool {
663 return WTERMSIG(s) == 0;657 return WTERMSIG(s) == 0;
664}658}
665pub fn WIFSTOPPED(s: i32) bool {659pub fn WIFSTOPPED(s: u32) bool {
666 return @intCast(u16, (((unsigned(s) & 0xffff) *% 0x10001) >> 8)) > 0x7f00;660 return @intCast(u16, (((s & 0xffff) *% 0x10001) >> 8)) > 0x7f00;
667}661}
668pub fn WIFSIGNALED(s: i32) bool {662pub fn WIFSIGNALED(s: u32) bool {
669 return (unsigned(s) & 0xffff) -% 1 < 0xff;663 return (s & 0xffff) -% 1 < 0xff;
670}664}
671665
672pub const winsize = extern struct {666pub const winsize = extern struct {
std/os/bits/linux.zig+13-17
...@@ -1,5 +1,7 @@...@@ -1,5 +1,7 @@
1const builtin = @import("builtin");
1const std = @import("../../std.zig");2const std = @import("../../std.zig");
2const maxInt = std.math.maxInt;3const maxInt = std.math.maxInt;
4use @import("../bits.zig");
35
4pub use @import("linux/errno.zig");6pub use @import("linux/errno.zig");
5pub use switch (builtin.arch) {7pub use switch (builtin.arch) {
...@@ -661,29 +663,23 @@ pub const TFD_CLOEXEC = O_CLOEXEC;...@@ -661,29 +663,23 @@ pub const TFD_CLOEXEC = O_CLOEXEC;
661pub const TFD_TIMER_ABSTIME = 1;663pub const TFD_TIMER_ABSTIME = 1;
662pub const TFD_TIMER_CANCEL_ON_SET = (1 << 1);664pub const TFD_TIMER_CANCEL_ON_SET = (1 << 1);
663665
664fn unsigned(s: i32) u32 {666pub fn WEXITSTATUS(s: u32) u32 {
665 return @bitCast(u32, s);667 return (s & 0xff00) >> 8;
666}668}
667fn signed(s: u32) i32 {669pub fn WTERMSIG(s: u32) u32 {
668 return @bitCast(i32, s);670 return s & 0x7f;
669}671}
670pub fn WEXITSTATUS(s: i32) i32 {672pub fn WSTOPSIG(s: u32) u32 {
671 return signed((unsigned(s) & 0xff00) >> 8);
672}
673pub fn WTERMSIG(s: i32) i32 {
674 return signed(unsigned(s) & 0x7f);
675}
676pub fn WSTOPSIG(s: i32) i32 {
677 return WEXITSTATUS(s);673 return WEXITSTATUS(s);
678}674}
679pub fn WIFEXITED(s: i32) bool {675pub fn WIFEXITED(s: u32) bool {
680 return WTERMSIG(s) == 0;676 return WTERMSIG(s) == 0;
681}677}
682pub fn WIFSTOPPED(s: i32) bool {678pub fn WIFSTOPPED(s: u32) bool {
683 return @intCast(u16, ((unsigned(s) & 0xffff) *% 0x10001) >> 8) > 0x7f00;679 return @intCast(u16, ((s & 0xffff) *% 0x10001) >> 8) > 0x7f00;
684}680}
685pub fn WIFSIGNALED(s: i32) bool {681pub fn WIFSIGNALED(s: u32) bool {
686 return (unsigned(s) & 0xffff) -% 1 < 0xff;682 return (s & 0xffff) -% 1 < 0xff;
687}683}
688684
689pub const winsize = extern struct {685pub const winsize = extern struct {
...@@ -902,7 +898,7 @@ pub const dirent64 = extern struct {...@@ -902,7 +898,7 @@ pub const dirent64 = extern struct {
902pub const dl_phdr_info = extern struct {898pub const dl_phdr_info = extern struct {
903 dlpi_addr: usize,899 dlpi_addr: usize,
904 dlpi_name: ?[*]const u8,900 dlpi_name: ?[*]const u8,
905 dlpi_phdr: [*]elf.Phdr,901 dlpi_phdr: [*]std.elf.Phdr,
906 dlpi_phnum: u16,902 dlpi_phnum: u16,
907};903};
908904
std/os/bits/netbsd.zig+10-16
...@@ -152,7 +152,7 @@ pub const CLOCK_MONOTONIC = 3;...@@ -152,7 +152,7 @@ pub const CLOCK_MONOTONIC = 3;
152pub const CLOCK_THREAD_CPUTIME_ID = 0x20000000;152pub const CLOCK_THREAD_CPUTIME_ID = 0x20000000;
153pub const CLOCK_PROCESS_CPUTIME_ID = 0x40000000;153pub const CLOCK_PROCESS_CPUTIME_ID = 0x40000000;
154154
155pub const MAP_FAILED = maxInt(usize);155pub const MAP_FAILED = @intToPtr(*c_void, maxInt(usize));
156pub const MAP_SHARED = 0x0001;156pub const MAP_SHARED = 0x0001;
157pub const MAP_PRIVATE = 0x0002;157pub const MAP_PRIVATE = 0x0002;
158pub const MAP_REMAPDUP = 0x0004;158pub const MAP_REMAPDUP = 0x0004;
...@@ -516,34 +516,28 @@ pub const TIOCSWINSZ = 0x80087467;...@@ -516,34 +516,28 @@ pub const TIOCSWINSZ = 0x80087467;
516pub const TIOCUCNTL = 0x80047466;516pub const TIOCUCNTL = 0x80047466;
517pub const TIOCXMTFRAME = 0x80087444;517pub const TIOCXMTFRAME = 0x80087444;
518518
519fn unsigned(s: i32) u32 {519pub fn WEXITSTATUS(s: u32) u32 {
520 return @bitCast(u32, s);520 return (s >> 8) & 0xff;
521}521}
522fn signed(s: u32) i32 {522pub fn WTERMSIG(s: u32) u32 {
523 return @bitCast(i32, s);523 return s & 0x7f;
524}524}
525pub fn WEXITSTATUS(s: i32) i32 {525pub fn WSTOPSIG(s: u32) u32 {
526 return signed((unsigned(s) >> 8) & 0xff);
527}
528pub fn WTERMSIG(s: i32) i32 {
529 return signed(unsigned(s) & 0x7f);
530}
531pub fn WSTOPSIG(s: i32) i32 {
532 return WEXITSTATUS(s);526 return WEXITSTATUS(s);
533}527}
534pub fn WIFEXITED(s: i32) bool {528pub fn WIFEXITED(s: u32) bool {
535 return WTERMSIG(s) == 0;529 return WTERMSIG(s) == 0;
536}530}
537531
538pub fn WIFCONTINUED(s: i32) bool {532pub fn WIFCONTINUED(s: u32) bool {
539 return ((s & 0x7f) == 0xffff);533 return ((s & 0x7f) == 0xffff);
540}534}
541535
542pub fn WIFSTOPPED(s: i32) bool {536pub fn WIFSTOPPED(s: u32) bool {
543 return ((s & 0x7f != 0x7f) and !WIFCONTINUED(s));537 return ((s & 0x7f != 0x7f) and !WIFCONTINUED(s));
544}538}
545539
546pub fn WIFSIGNALED(s: i32) bool {540pub fn WIFSIGNALED(s: u32) bool {
547 return !WIFSTOPPED(s) and !WIFCONTINUED(s) and !WIFEXITED(s);541 return !WIFSTOPPED(s) and !WIFCONTINUED(s) and !WIFEXITED(s);
548}542}
549543
std/os/linux.zig+1-1
...@@ -382,7 +382,7 @@ pub fn unlinkat(dirfd: i32, path: [*]const u8, flags: u32) usize {...@@ -382,7 +382,7 @@ pub fn unlinkat(dirfd: i32, path: [*]const u8, flags: u32) usize {
382 return syscall3(SYS_unlinkat, @bitCast(usize, isize(dirfd)), @ptrToInt(path), flags);382 return syscall3(SYS_unlinkat, @bitCast(usize, isize(dirfd)), @ptrToInt(path), flags);
383}383}
384384
385pub fn waitpid(pid: i32, status: *i32, flags: u32) usize {385pub fn waitpid(pid: i32, status: *u32, flags: u32) usize {
386 return syscall4(SYS_wait4, @bitCast(usize, isize(pid)), @ptrToInt(status), flags, 0);386 return syscall4(SYS_wait4, @bitCast(usize, isize(pid)), @ptrToInt(status), flags, 0);
387}387}
388388
std/os/linux/test.zig+1-1
...@@ -11,7 +11,7 @@ test "getpid" {...@@ -11,7 +11,7 @@ test "getpid" {
1111
12test "timer" {12test "timer" {
13 const epoll_fd = linux.epoll_create();13 const epoll_fd = linux.epoll_create();
14 var err = linux.getErrno(epoll_fd);14 var err: usize = linux.getErrno(epoll_fd);
15 expect(err == 0);15 expect(err == 0);
1616
17 const timer_fd = linux.timerfd_create(linux.CLOCK_MONOTONIC, 0);17 const timer_fd = linux.timerfd_create(linux.CLOCK_MONOTONIC, 0);
std/os/linux/vdso.zig+1-1
...@@ -5,7 +5,7 @@ const mem = std.mem;...@@ -5,7 +5,7 @@ const mem = std.mem;
5const maxInt = std.math.maxInt;5const maxInt = std.math.maxInt;
66
7pub fn lookup(vername: []const u8, name: []const u8) usize {7pub fn lookup(vername: []const u8, name: []const u8) usize {
8 const vdso_addr = std.os.linuxGetAuxVal(std.elf.AT_SYSINFO_EHDR);8 const vdso_addr = std.os.system.getauxval(std.elf.AT_SYSINFO_EHDR);
9 if (vdso_addr == 0) return 0;9 if (vdso_addr == 0) return 0;
1010
11 const eh = @intToPtr(*elf.Ehdr, vdso_addr);11 const eh = @intToPtr(*elf.Ehdr, vdso_addr);
std/os/test.zig+16-19
...@@ -15,11 +15,11 @@ const AtomicRmwOp = builtin.AtomicRmwOp;...@@ -15,11 +15,11 @@ const AtomicRmwOp = builtin.AtomicRmwOp;
15const AtomicOrder = builtin.AtomicOrder;15const AtomicOrder = builtin.AtomicOrder;
1616
17test "makePath, put some files in it, deleteTree" {17test "makePath, put some files in it, deleteTree" {
18 try os.makePath(a, "os_test_tmp" ++ fs.path.sep_str ++ "b" ++ fs.path.sep_str ++ "c");18 try fs.makePath(a, "os_test_tmp" ++ fs.path.sep_str ++ "b" ++ fs.path.sep_str ++ "c");
19 try io.writeFile("os_test_tmp" ++ fs.path.sep_str ++ "b" ++ fs.path.sep_str ++ "c" ++ fs.path.sep_str ++ "file.txt", "nonsense");19 try io.writeFile("os_test_tmp" ++ fs.path.sep_str ++ "b" ++ fs.path.sep_str ++ "c" ++ fs.path.sep_str ++ "file.txt", "nonsense");
20 try io.writeFile("os_test_tmp" ++ fs.path.sep_str ++ "b" ++ fs.path.sep_str ++ "file2.txt", "blah");20 try io.writeFile("os_test_tmp" ++ fs.path.sep_str ++ "b" ++ fs.path.sep_str ++ "file2.txt", "blah");
21 try os.deleteTree(a, "os_test_tmp");21 try fs.deleteTree(a, "os_test_tmp");
22 if (os.Dir.open(a, "os_test_tmp")) |dir| {22 if (fs.Dir.open(a, "os_test_tmp")) |dir| {
23 @panic("expected error");23 @panic("expected error");
24 } else |err| {24 } else |err| {
25 expect(err == error.FileNotFound);25 expect(err == error.FileNotFound);
...@@ -27,7 +27,7 @@ test "makePath, put some files in it, deleteTree" {...@@ -27,7 +27,7 @@ test "makePath, put some files in it, deleteTree" {
27}27}
2828
29test "access file" {29test "access file" {
30 try os.makePath(a, "os_test_tmp");30 try fs.makePath(a, "os_test_tmp");
31 if (File.access("os_test_tmp" ++ fs.path.sep_str ++ "file.txt")) |ok| {31 if (File.access("os_test_tmp" ++ fs.path.sep_str ++ "file.txt")) |ok| {
32 @panic("expected error");32 @panic("expected error");
33 } else |err| {33 } else |err| {
...@@ -35,8 +35,8 @@ test "access file" {...@@ -35,8 +35,8 @@ test "access file" {
35 }35 }
3636
37 try io.writeFile("os_test_tmp" ++ fs.path.sep_str ++ "file.txt", "");37 try io.writeFile("os_test_tmp" ++ fs.path.sep_str ++ "file.txt", "");
38 try File.access("os_test_tmp" ++ fs.path.sep_str ++ "file.txt");38 try os.access("os_test_tmp" ++ fs.path.sep_str ++ "file.txt", os.F_OK);
39 try os.deleteTree(a, "os_test_tmp");39 try fs.deleteTree(a, "os_test_tmp");
40}40}
4141
42fn testThreadIdFn(thread_id: *Thread.Id) void {42fn testThreadIdFn(thread_id: *Thread.Id) void {
...@@ -52,15 +52,12 @@ test "std.Thread.getCurrentId" {...@@ -52,15 +52,12 @@ test "std.Thread.getCurrentId" {
52 thread.wait();52 thread.wait();
53 if (Thread.use_pthreads) {53 if (Thread.use_pthreads) {
54 expect(thread_current_id == thread_id);54 expect(thread_current_id == thread_id);
55 } else if (os.windows.is_the_target) {
56 expect(Thread.getCurrentId() != thread_current_id);
55 } else {57 } else {
56 switch (builtin.os) {58 // If the thread completes very quickly, then thread_id can be 0. See the
57 builtin.Os.windows => expect(Thread.getCurrentId() != thread_current_id),59 // documentation comments for `std.Thread.handle`.
58 else => {60 expect(thread_id == 0 or thread_current_id == thread_id);
59 // If the thread completes very quickly, then thread_id can be 0. See the
60 // documentation comments for `std.Thread.handle`.
61 expect(thread_id == 0 or thread_current_id == thread_id);
62 },
63 }
64 }61 }
65}62}
6663
...@@ -92,7 +89,7 @@ fn start2(ctx: *i32) u8 {...@@ -92,7 +89,7 @@ fn start2(ctx: *i32) u8 {
92}89}
9390
94test "cpu count" {91test "cpu count" {
95 const cpu_count = try std.os.cpuCount(a);92 const cpu_count = try Thread.cpuCount();
96 expect(cpu_count >= 1);93 expect(cpu_count >= 1);
97}94}
9895
...@@ -105,7 +102,7 @@ test "AtomicFile" {...@@ -105,7 +102,7 @@ test "AtomicFile" {
105 \\ this is a test file102 \\ this is a test file
106 ;103 ;
107 {104 {
108 var af = try os.AtomicFile.init(test_out_file, File.default_mode);105 var af = try fs.AtomicFile.init(test_out_file, File.default_mode);
109 defer af.deinit();106 defer af.deinit();
110 try af.file.write(test_content);107 try af.file.write(test_content);
111 try af.finish();108 try af.finish();
...@@ -113,7 +110,7 @@ test "AtomicFile" {...@@ -113,7 +110,7 @@ test "AtomicFile" {
113 const content = try io.readFileAlloc(allocator, test_out_file);110 const content = try io.readFileAlloc(allocator, test_out_file);
114 expect(mem.eql(u8, content, test_content));111 expect(mem.eql(u8, content, test_content));
115112
116 try os.deleteFile(test_out_file);113 try fs.deleteFile(test_out_file);
117}114}
118115
119test "thread local storage" {116test "thread local storage" {
...@@ -145,10 +142,10 @@ test "getrandom" {...@@ -145,10 +142,10 @@ test "getrandom" {
145test "getcwd" {142test "getcwd" {
146 // at least call it so it gets compiled143 // at least call it so it gets compiled
147 var buf: [std.fs.MAX_PATH_BYTES]u8 = undefined;144 var buf: [std.fs.MAX_PATH_BYTES]u8 = undefined;
148 _ = os.getcwd(&buf) catch {};145 _ = os.getcwd(&buf) catch undefined;
149}146}
150147
151test "realpath" {148test "realpath" {
152 var buf: [std.fs.MAX_PATH_BYTES]u8 = undefined;149 var buf: [std.fs.MAX_PATH_BYTES]u8 = undefined;
153 testing.expectError(error.FileNotFound, os.realpath("definitely_bogus_does_not_exist1234", &buf));150 testing.expectError(error.FileNotFound, fs.realpath("definitely_bogus_does_not_exist1234", &buf));
154}151}
std/os/windows.zig+38
...@@ -1180,6 +1180,44 @@ pub fn CreateProcessW(...@@ -1180,6 +1180,44 @@ pub fn CreateProcessW(
1180 }1180 }
1181}1181}
11821182
1183pub const LoadLibraryError = error{
1184 FileNotFound,
1185 Unexpected,
1186};
1187
1188pub fn LoadLibraryW(lpLibFileName: [*]const u16) LoadLibraryError!HMODULE {
1189 return kernel32.LoadLibraryW(lpLibFileName) orelse {
1190 switch (kernel32.GetLastError()) {
1191 ERROR.FILE_NOT_FOUND => return error.FileNotFound,
1192 ERROR.PATH_NOT_FOUND => return error.FileNotFound,
1193 ERROR.MOD_NOT_FOUND => return error.FileNotFound,
1194 else => |err| return unexpectedError(err),
1195 }
1196 };
1197}
1198
1199pub fn FreeLibrary(hModule: HMODULE) void {
1200 assert(kernel32.FreeLibrary(hModule) != 0);
1201}
1202
1203pub fn QueryPerformanceFrequency() u64 {
1204 // "On systems that run Windows XP or later, the function will always succeed"
1205 // https://docs.microsoft.com/en-us/windows/desktop/api/profileapi/nf-profileapi-queryperformancefrequency
1206 var result: LARGE_INTEGER = undefined;
1207 assert(kernel32.QueryPerformanceFrequency(&result) != 0);
1208 // The kernel treats this integer as unsigned.
1209 return @bitCast(u64, result);
1210}
1211
1212pub fn QueryPerformanceCounter() u64 {
1213 // "On systems that run Windows XP or later, the function will always succeed"
1214 // https://docs.microsoft.com/en-us/windows/desktop/api/profileapi/nf-profileapi-queryperformancecounter
1215 var result: LARGE_INTEGER = undefined;
1216 assert(kernel32.QueryPerformanceCounter(&result) != 0);
1217 // The kernel treats this integer as unsigned.
1218 return @bitCast(u64, result);
1219}
1220
1183pub fn cStrToPrefixedFileW(s: [*]const u8) ![PATH_MAX_WIDE + 1]u16 {1221pub fn cStrToPrefixedFileW(s: [*]const u8) ![PATH_MAX_WIDE + 1]u16 {
1184 return sliceToPrefixedFileW(mem.toSliceConst(u8, s));1222 return sliceToPrefixedFileW(mem.toSliceConst(u8, s));
1185}1223}
std/os/zen.zig+1-1
...@@ -80,7 +80,7 @@ pub const STDOUT_FILENO = 1;...@@ -80,7 +80,7 @@ pub const STDOUT_FILENO = 1;
80pub const STDERR_FILENO = 2;80pub const STDERR_FILENO = 2;
8181
82// FIXME: let's borrow Linux's error numbers for now.82// FIXME: let's borrow Linux's error numbers for now.
83use @import("../bits/linux/errno.zig");83use @import("bits/linux/errno.zig");
84// Get the errno from a syscall return value, or 0 for no error.84// Get the errno from a syscall return value, or 0 for no error.
85pub fn getErrno(r: usize) usize {85pub fn getErrno(r: usize) usize {
86 const signed_r = @bitCast(isize, r);86 const signed_r = @bitCast(isize, r);
std/process.zig+21-1
...@@ -1,7 +1,9 @@...@@ -1,7 +1,9 @@
1const builtin = @import("builtin");1const builtin = @import("builtin");
2const std = @import("std.zig");2const std = @import("std.zig");
3const os = std.os;3const os = std.os;
4const fs = std.fs;
4const BufMap = std.BufMap;5const BufMap = std.BufMap;
6const Buffer = std.Buffer;
5const mem = std.mem;7const mem = std.mem;
6const math = std.math;8const math = std.math;
7const Allocator = mem.Allocator;9const Allocator = mem.Allocator;
...@@ -13,6 +15,24 @@ pub const exit = os.exit;...@@ -13,6 +15,24 @@ pub const exit = os.exit;
13pub const changeCurDir = os.chdir;15pub const changeCurDir = os.chdir;
14pub const changeCurDirC = os.chdirC;16pub const changeCurDirC = os.chdirC;
1517
18/// The result is a slice of `out_buffer`, from index `0`.
19pub fn getCwd(out_buffer: *[fs.MAX_PATH_BYTES]u8) ![]u8 {
20 return os.getcwd(out_buffer);
21}
22
23/// Caller must free the returned memory.
24pub fn getCwdAlloc(allocator: *Allocator) ![]u8 {
25 var buf: [fs.MAX_PATH_BYTES]u8 = undefined;
26 return mem.dupe(allocator, u8, try os.getcwd(&buf));
27}
28
29test "getCwdAlloc" {
30 // at least call it so it gets compiled
31 var buf: [1000]u8 = undefined;
32 const allocator = &std.heap.FixedBufferAllocator.init(&buf).allocator;
33 _ = getCwdAlloc(allocator) catch undefined;
34}
35
16/// Caller must free result when done.36/// Caller must free result when done.
17/// TODO make this go through libc when we have it37/// TODO make this go through libc when we have it
18pub fn getEnvMap(allocator: *Allocator) !BufMap {38pub fn getEnvMap(allocator: *Allocator) !BufMap {
...@@ -402,7 +422,7 @@ pub fn argsAlloc(allocator: *mem.Allocator) ![]const []u8 {...@@ -402,7 +422,7 @@ pub fn argsAlloc(allocator: *mem.Allocator) ![]const []u8 {
402 var contents = try Buffer.initSize(allocator, 0);422 var contents = try Buffer.initSize(allocator, 0);
403 defer contents.deinit();423 defer contents.deinit();
404424
405 var slice_list = ArrayList(usize).init(allocator);425 var slice_list = std.ArrayList(usize).init(allocator);
406 defer slice_list.deinit();426 defer slice_list.deinit();
407427
408 while (it.next(allocator)) |arg_or_err| {428 while (it.next(allocator)) |arg_or_err| {
std/thread.zig+36-20
...@@ -1,8 +1,10 @@...@@ -1,8 +1,10 @@
1const builtin = @import("builtin");1const builtin = @import("builtin");
2const std = @import("std.zig");2const std = @import("std.zig");
3const os = std.os;3const os = std.os;
4const mem = std.mem;
4const windows = std.os.windows;5const windows = std.os.windows;
5const c = std.c;6const c = std.c;
7const assert = std.debug.assert;
68
7pub const Thread = struct {9pub const Thread = struct {
8 data: Data,10 data: Data,
...@@ -31,14 +33,12 @@ pub const Thread = struct {...@@ -31,14 +33,12 @@ pub const Thread = struct {
31 pub const Data = if (use_pthreads)33 pub const Data = if (use_pthreads)
32 struct {34 struct {
33 handle: Thread.Handle,35 handle: Thread.Handle,
34 mmap_addr: usize,36 memory: []align(mem.page_size) u8,
35 mmap_len: usize,
36 }37 }
37 else switch (builtin.os) {38 else switch (builtin.os) {
38 .linux => struct {39 .linux => struct {
39 handle: Thread.Handle,40 handle: Thread.Handle,
40 mmap_addr: usize,41 memory: []align(mem.page_size) u8,
41 mmap_len: usize,
42 },42 },
43 .windows => struct {43 .windows => struct {
44 handle: Thread.Handle,44 handle: Thread.Handle,
...@@ -56,7 +56,7 @@ pub const Thread = struct {...@@ -56,7 +56,7 @@ pub const Thread = struct {
56 return c.pthread_self();56 return c.pthread_self();
57 } else57 } else
58 return switch (builtin.os) {58 return switch (builtin.os) {
59 .linux => linux.gettid(),59 .linux => os.linux.gettid(),
60 .windows => windows.GetCurrentThreadId(),60 .windows => windows.GetCurrentThreadId(),
61 else => @compileError("Unsupported OS"),61 else => @compileError("Unsupported OS"),
62 };62 };
...@@ -82,21 +82,21 @@ pub const Thread = struct {...@@ -82,21 +82,21 @@ pub const Thread = struct {
82 os.EDEADLK => unreachable,82 os.EDEADLK => unreachable,
83 else => unreachable,83 else => unreachable,
84 }84 }
85 os.munmap(self.data.mmap_addr, self.data.mmap_len);85 os.munmap(self.data.memory);
86 } else switch (builtin.os) {86 } else switch (builtin.os) {
87 .linux => {87 .linux => {
88 while (true) {88 while (true) {
89 const pid_value = @atomicLoad(i32, &self.data.handle, .SeqCst);89 const pid_value = @atomicLoad(i32, &self.data.handle, .SeqCst);
90 if (pid_value == 0) break;90 if (pid_value == 0) break;
91 const rc = linux.futex_wait(&self.data.handle, linux.FUTEX_WAIT, pid_value, null);91 const rc = os.linux.futex_wait(&self.data.handle, os.linux.FUTEX_WAIT, pid_value, null);
92 switch (linux.getErrno(rc)) {92 switch (os.linux.getErrno(rc)) {
93 0 => continue,93 0 => continue,
94 os.EINTR => continue,94 os.EINTR => continue,
95 os.EAGAIN => continue,95 os.EAGAIN => continue,
96 else => unreachable,96 else => unreachable,
97 }97 }
98 }98 }
99 os.munmap(self.data.mmap_addr, self.data.mmap_len);99 os.munmap(self.data.memory);
100 },100 },
101 .windows => {101 .windows => {
102 assert(windows.WaitForSingleObject(self.data.handle, windows.INFINITE) == windows.WAIT_OBJECT_0);102 assert(windows.WaitForSingleObject(self.data.handle, windows.INFINITE) == windows.WAIT_OBJECT_0);
...@@ -130,6 +130,10 @@ pub const Thread = struct {...@@ -130,6 +130,10 @@ pub const Thread = struct {
130 /// Not enough userland memory to spawn the thread.130 /// Not enough userland memory to spawn the thread.
131 OutOfMemory,131 OutOfMemory,
132132
133 /// `mlockall` is enabled, and the memory needed to spawn the thread
134 /// would exceed the limit.
135 LockedMemoryLimitExceeded,
136
133 Unexpected,137 Unexpected,
134 };138 };
135139
...@@ -219,7 +223,7 @@ pub const Thread = struct {...@@ -219,7 +223,7 @@ pub const Thread = struct {
219 }223 }
220 };224 };
221225
222 const MAP_GROWSDOWN = if (builtin.os == .linux) linux.MAP_GROWSDOWN else 0;226 const MAP_GROWSDOWN = if (os.linux.is_the_target) os.linux.MAP_GROWSDOWN else 0;
223227
224 var stack_end_offset: usize = undefined;228 var stack_end_offset: usize = undefined;
225 var thread_start_offset: usize = undefined;229 var thread_start_offset: usize = undefined;
...@@ -241,7 +245,7 @@ pub const Thread = struct {...@@ -241,7 +245,7 @@ pub const Thread = struct {
241 }245 }
242 // Finally, the Thread Local Storage, if any.246 // Finally, the Thread Local Storage, if any.
243 if (!Thread.use_pthreads) {247 if (!Thread.use_pthreads) {
244 if (linux.tls.tls_image) |tls_img| {248 if (os.linux.tls.tls_image) |tls_img| {
245 l = mem.alignForward(l, @alignOf(usize));249 l = mem.alignForward(l, @alignOf(usize));
246 tls_start_offset = l;250 tls_start_offset = l;
247 l += tls_img.alloc_size;251 l += tls_img.alloc_size;
...@@ -249,12 +253,24 @@ pub const Thread = struct {...@@ -249,12 +253,24 @@ pub const Thread = struct {
249 }253 }
250 break :blk l;254 break :blk l;
251 };255 };
252 const mmap_addr = try os.mmap(null, mmap_len, os.PROT_READ | os.PROT_WRITE, os.MAP_PRIVATE | os.MAP_ANONYMOUS | MAP_GROWSDOWN, -1, 0);256 const mmap_slice = os.mmap(
253 errdefer os.munmap(mmap_addr, mmap_len);257 null,
258 mem.alignForward(mmap_len, mem.page_size),
259 os.PROT_READ | os.PROT_WRITE,
260 os.MAP_PRIVATE | os.MAP_ANONYMOUS | MAP_GROWSDOWN,
261 -1,
262 0,
263 ) catch |err| switch (err) {
264 error.MemoryMappingNotSupported => unreachable, // no file descriptor
265 error.AccessDenied => unreachable, // no file descriptor
266 error.PermissionDenied => unreachable, // no file descriptor
267 else => |e| return e,
268 };
269 errdefer os.munmap(mmap_slice);
270 const mmap_addr = @ptrToInt(mmap_slice.ptr);
254271
255 const thread_ptr = @alignCast(@alignOf(Thread), @intToPtr(*Thread, mmap_addr + thread_start_offset));272 const thread_ptr = @alignCast(@alignOf(Thread), @intToPtr(*Thread, mmap_addr + thread_start_offset));
256 thread_ptr.data.mmap_addr = mmap_addr;273 thread_ptr.data.memory = mmap_slice;
257 thread_ptr.data.mmap_len = mmap_len;
258274
259 var arg: usize = undefined;275 var arg: usize = undefined;
260 if (@sizeOf(Context) != 0) {276 if (@sizeOf(Context) != 0) {
...@@ -269,7 +285,7 @@ pub const Thread = struct {...@@ -269,7 +285,7 @@ pub const Thread = struct {
269 if (c.pthread_attr_init(&attr) != 0) return error.SystemResources;285 if (c.pthread_attr_init(&attr) != 0) return error.SystemResources;
270 defer assert(c.pthread_attr_destroy(&attr) == 0);286 defer assert(c.pthread_attr_destroy(&attr) == 0);
271287
272 assert(c.pthread_attr_setstack(&attr, @intToPtr(*c_void, mmap_addr), stack_end_offset) == 0);288 assert(c.pthread_attr_setstack(&attr, mmap_slice.ptr, stack_end_offset) == 0);
273289
274 const err = c.pthread_create(&thread_ptr.data.handle, &attr, MainFuncs.posixThreadMain, @intToPtr(*c_void, arg));290 const err = c.pthread_create(&thread_ptr.data.handle, &attr, MainFuncs.posixThreadMain, @intToPtr(*c_void, arg));
275 switch (err) {291 switch (err) {
...@@ -279,13 +295,13 @@ pub const Thread = struct {...@@ -279,13 +295,13 @@ pub const Thread = struct {
279 os.EINVAL => unreachable,295 os.EINVAL => unreachable,
280 else => return os.unexpectedErrno(@intCast(usize, err)),296 else => return os.unexpectedErrno(@intCast(usize, err)),
281 }297 }
282 } else if (builtin.os == .linux) {298 } else if (os.linux.is_the_target) {
283 var flags: u32 = os.CLONE_VM | os.CLONE_FS | os.CLONE_FILES | os.CLONE_SIGHAND |299 var flags: u32 = os.CLONE_VM | os.CLONE_FS | os.CLONE_FILES | os.CLONE_SIGHAND |
284 os.CLONE_THREAD | os.CLONE_SYSVSEM | os.CLONE_PARENT_SETTID | os.CLONE_CHILD_CLEARTID |300 os.CLONE_THREAD | os.CLONE_SYSVSEM | os.CLONE_PARENT_SETTID | os.CLONE_CHILD_CLEARTID |
285 os.CLONE_DETACHED;301 os.CLONE_DETACHED;
286 var newtls: usize = undefined;302 var newtls: usize = undefined;
287 if (linux.tls.tls_image) |tls_img| {303 if (os.linux.tls.tls_image) |tls_img| {
288 newtls = linux.tls.copyTLS(mmap_addr + tls_start_offset);304 newtls = os.linux.tls.copyTLS(mmap_addr + tls_start_offset);
289 flags |= os.CLONE_SETTLS;305 flags |= os.CLONE_SETTLS;
290 }306 }
291 const rc = os.linux.clone(MainFuncs.linuxThreadMain, mmap_addr + stack_end_offset, flags, arg, &thread_ptr.data.handle, newtls, &thread_ptr.data.handle);307 const rc = os.linux.clone(MainFuncs.linuxThreadMain, mmap_addr + stack_end_offset, flags, arg, &thread_ptr.data.handle, newtls, &thread_ptr.data.handle);
...@@ -313,7 +329,7 @@ pub const Thread = struct {...@@ -313,7 +329,7 @@ pub const Thread = struct {
313 pub fn cpuCount() CpuCountError!usize {329 pub fn cpuCount() CpuCountError!usize {
314 if (os.linux.is_the_target) {330 if (os.linux.is_the_target) {
315 const cpu_set = try os.sched_getaffinity(0);331 const cpu_set = try os.sched_getaffinity(0);
316 return os.CPU_COUNT(cpu_set);332 return usize(os.CPU_COUNT(cpu_set)); // TODO should not need this usize cast
317 }333 }
318 if (os.windows.is_the_target) {334 if (os.windows.is_the_target) {
319 var system_info: windows.SYSTEM_INFO = undefined;335 var system_info: windows.SYSTEM_INFO = undefined;
std/time.zig+7-17
...@@ -95,7 +95,7 @@ pub const Timer = struct {...@@ -95,7 +95,7 @@ pub const Timer = struct {
95 /// be less precise95 /// be less precise
96 frequency: switch (builtin.os) {96 frequency: switch (builtin.os) {
97 .windows => u64,97 .windows => u64,
98 .macosx, .ios, .tvos, .watchos => darwin.mach_timebase_info_data,98 .macosx, .ios, .tvos, .watchos => os.darwin.mach_timebase_info_data,
99 else => void,99 else => void,
100 },100 },
101 resolution: u64,101 resolution: u64,
...@@ -119,20 +119,13 @@ pub const Timer = struct {...@@ -119,20 +119,13 @@ pub const Timer = struct {
119 var self: Timer = undefined;119 var self: Timer = undefined;
120120
121 if (os.windows.is_the_target) {121 if (os.windows.is_the_target) {
122 var freq: i64 = undefined;122 self.frequency = os.windows.QueryPerformanceFrequency();
123 var err = windows.QueryPerformanceFrequency(&freq);
124 if (err == windows.FALSE) return error.TimerUnsupported;
125 self.frequency = @intCast(u64, freq);
126 self.resolution = @divFloor(ns_per_s, self.frequency);123 self.resolution = @divFloor(ns_per_s, self.frequency);
127124 self.start_time = os.windows.QueryPerformanceCounter();
128 var start_time: i64 = undefined;
129 err = windows.QueryPerformanceCounter(&start_time);
130 assert(err != windows.FALSE);
131 self.start_time = @intCast(u64, start_time);
132 } else if (os.darwin.is_the_target) {125 } else if (os.darwin.is_the_target) {
133 darwin.mach_timebase_info(&self.frequency);126 os.darwin.mach_timebase_info(&self.frequency);
134 self.resolution = @divFloor(self.frequency.numer, self.frequency.denom);127 self.resolution = @divFloor(self.frequency.numer, self.frequency.denom);
135 self.start_time = darwin.mach_absolute_time();128 self.start_time = os.darwin.mach_absolute_time();
136 } else {129 } else {
137 //On Linux, seccomp can do arbitrary things to our ability to call130 //On Linux, seccomp can do arbitrary things to our ability to call
138 // syscalls, including return any errno value it wants and131 // syscalls, including return any errno value it wants and
...@@ -177,13 +170,10 @@ pub const Timer = struct {...@@ -177,13 +170,10 @@ pub const Timer = struct {
177170
178 fn clockNative() u64 {171 fn clockNative() u64 {
179 if (os.windows.is_the_target) {172 if (os.windows.is_the_target) {
180 var result: i64 = undefined;173 return os.windows.QueryPerformanceCounter();
181 var err = windows.QueryPerformanceCounter(&result);
182 assert(err != windows.FALSE);
183 return @intCast(u64, result);
184 }174 }
185 if (os.darwin.is_the_target) {175 if (os.darwin.is_the_target) {
186 return darwin.mach_absolute_time();176 return os.darwin.mach_absolute_time();
187 }177 }
188 var ts: os.timespec = undefined;178 var ts: os.timespec = undefined;
189 os.clock_gettime(monotonic_clock_id, &ts) catch unreachable;179 os.clock_gettime(monotonic_clock_id, &ts) catch unreachable;
test/compare_output.zig+3-3
...@@ -377,7 +377,7 @@ pub fn addCases(cases: *tests.CompareOutputContext) void {...@@ -377,7 +377,7 @@ pub fn addCases(cases: *tests.CompareOutputContext) void {
377 \\ stdout.print("before\n") catch unreachable;377 \\ stdout.print("before\n") catch unreachable;
378 \\ defer stdout.print("defer1\n") catch unreachable;378 \\ defer stdout.print("defer1\n") catch unreachable;
379 \\ defer stdout.print("defer2\n") catch unreachable;379 \\ defer stdout.print("defer2\n") catch unreachable;
380 \\ var args_it = @import("std").os.args();380 \\ var args_it = @import("std").process.args();
381 \\ if (args_it.skip() and !args_it.skip()) return;381 \\ if (args_it.skip() and !args_it.skip()) return;
382 \\ defer stdout.print("defer3\n") catch unreachable;382 \\ defer stdout.print("defer3\n") catch unreachable;
383 \\ stdout.print("after\n") catch unreachable;383 \\ stdout.print("after\n") catch unreachable;
...@@ -444,7 +444,7 @@ pub fn addCases(cases: *tests.CompareOutputContext) void {...@@ -444,7 +444,7 @@ pub fn addCases(cases: *tests.CompareOutputContext) void {
444 \\const allocator = std.debug.global_allocator;444 \\const allocator = std.debug.global_allocator;
445 \\445 \\
446 \\pub fn main() !void {446 \\pub fn main() !void {
447 \\ var args_it = os.args();447 \\ var args_it = std.process.args();
448 \\ var stdout_file = try io.getStdOut();448 \\ var stdout_file = try io.getStdOut();
449 \\ var stdout_adapter = stdout_file.outStream();449 \\ var stdout_adapter = stdout_file.outStream();
450 \\ const stdout = &stdout_adapter.stream;450 \\ const stdout = &stdout_adapter.stream;
...@@ -485,7 +485,7 @@ pub fn addCases(cases: *tests.CompareOutputContext) void {...@@ -485,7 +485,7 @@ pub fn addCases(cases: *tests.CompareOutputContext) void {
485 \\const allocator = std.debug.global_allocator;485 \\const allocator = std.debug.global_allocator;
486 \\486 \\
487 \\pub fn main() !void {487 \\pub fn main() !void {
488 \\ var args_it = os.args();488 \\ var args_it = std.process.args();
489 \\ var stdout_file = try io.getStdOut();489 \\ var stdout_file = try io.getStdOut();
490 \\ var stdout_adapter = stdout_file.outStream();490 \\ var stdout_adapter = stdout_file.outStream();
491 \\ const stdout = &stdout_adapter.stream;491 \\ const stdout = &stdout_adapter.stream;
test/standalone/empty_env/main.zig+1-1
...@@ -1,6 +1,6 @@...@@ -1,6 +1,6 @@
1const std = @import("std");1const std = @import("std");
22
3pub fn main() void {3pub fn main() void {
4 const env_map = std.os.getEnvMap(std.debug.global_allocator) catch @panic("unable to get env map");4 const env_map = std.process.getEnvMap(std.debug.global_allocator) catch @panic("unable to get env map");
5 std.testing.expect(env_map.count() == 0);5 std.testing.expect(env_map.count() == 0);
6}6}
test/tests.zig+1-1
...@@ -393,7 +393,7 @@ pub const CompareOutputContext = struct {...@@ -393,7 +393,7 @@ pub const CompareOutputContext = struct {
393 debug.panic("Unable to spawn {}: {}\n", full_exe_path, @errorName(err));393 debug.panic("Unable to spawn {}: {}\n", full_exe_path, @errorName(err));
394 };394 };
395395
396 const expected_exit_code: i32 = 126;396 const expected_exit_code: u32 = 126;
397 switch (term) {397 switch (term) {
398 .Exited => |code| {398 .Exited => |code| {
399 if (code != expected_exit_code) {399 if (code != expected_exit_code) {