diff options
Diffstat (limited to 'std')
| -rw-r--r-- | std/atomic/queue.zig | 4 | ||||
| -rw-r--r-- | std/atomic/stack.zig | 4 | ||||
| -rw-r--r-- | std/build.zig | 5 | ||||
| -rw-r--r-- | std/c.zig | 2 | ||||
| -rw-r--r-- | std/child_process.zig | 92 | ||||
| -rw-r--r-- | std/coff.zig | 5 | ||||
| -rw-r--r-- | std/crypto/throughput_test.zig | 2 | ||||
| -rw-r--r-- | std/debug.zig | 13 | ||||
| -rw-r--r-- | std/dynamic_library.zig | 28 | ||||
| -rw-r--r-- | std/elf.zig | 5 | ||||
| -rw-r--r-- | std/event/fs.zig | 43 | ||||
| -rw-r--r-- | std/event/group.zig | 2 | ||||
| -rw-r--r-- | std/event/loop.zig | 4 | ||||
| -rw-r--r-- | std/event/net.zig | 15 | ||||
| -rw-r--r-- | std/event/rwlock.zig | 4 | ||||
| -rw-r--r-- | std/fs.zig | 367 | ||||
| -rw-r--r-- | std/io.zig | 12 | ||||
| -rw-r--r-- | std/io/c_out_stream.zig | 39 | ||||
| -rw-r--r-- | std/io/test.zig | 23 | ||||
| -rw-r--r-- | std/os.zig | 110 | ||||
| -rw-r--r-- | std/os/bits/linux.zig | 12 | ||||
| -rw-r--r-- | std/os/test.zig | 7 | ||||
| -rw-r--r-- | std/os/windows.zig | 26 | ||||
| -rw-r--r-- | std/pdb.zig | 11 | ||||
| -rw-r--r-- | std/special/build_runner.zig | 5 | ||||
| -rw-r--r-- | std/time.zig | 284 | ||||
| -rw-r--r-- | std/zig/bench.zig | 4 |
27 files changed, 547 insertions, 581 deletions
diff --git a/std/atomic/queue.zig b/std/atomic/queue.zig index 431a96e64b..34cd0d22f8 100644 --- a/std/atomic/queue.zig +++ b/std/atomic/queue.zig @@ -220,7 +220,7 @@ fn startPuts(ctx: *Context) u8 { var put_count: usize = puts_per_thread; var r = std.rand.DefaultPrng.init(0xdeadbeef); while (put_count != 0) : (put_count -= 1) { - std.os.time.sleep(1); // let the os scheduler be our fuzz + std.time.sleep(1); // let the os scheduler be our fuzz const x = @bitCast(i32, r.random.scalar(u32)); const node = ctx.allocator.create(Queue(i32).Node) catch unreachable; node.* = Queue(i32).Node{ @@ -239,7 +239,7 @@ fn startGets(ctx: *Context) u8 { const last = @atomicLoad(u8, &ctx.puts_done, builtin.AtomicOrder.SeqCst) == 1; while (ctx.queue.get()) |node| { - std.os.time.sleep(1); // let the os scheduler be our fuzz + std.time.sleep(1); // let the os scheduler be our fuzz _ = @atomicRmw(isize, &ctx.get_sum, builtin.AtomicRmwOp.Add, node.data, builtin.AtomicOrder.SeqCst); _ = @atomicRmw(usize, &ctx.get_count, builtin.AtomicRmwOp.Add, 1, builtin.AtomicOrder.SeqCst); } diff --git a/std/atomic/stack.zig b/std/atomic/stack.zig index 8ae6c997aa..773bdf6f1b 100644 --- a/std/atomic/stack.zig +++ b/std/atomic/stack.zig @@ -154,7 +154,7 @@ fn startPuts(ctx: *Context) u8 { var put_count: usize = puts_per_thread; var r = std.rand.DefaultPrng.init(0xdeadbeef); while (put_count != 0) : (put_count -= 1) { - std.os.time.sleep(1); // let the os scheduler be our fuzz + std.time.sleep(1); // let the os scheduler be our fuzz const x = @bitCast(i32, r.random.scalar(u32)); const node = ctx.allocator.create(Stack(i32).Node) catch unreachable; node.* = Stack(i32).Node{ @@ -172,7 +172,7 @@ fn startGets(ctx: *Context) u8 { const last = @atomicLoad(u8, &ctx.puts_done, builtin.AtomicOrder.SeqCst) == 1; while (ctx.stack.pop()) |node| { - std.os.time.sleep(1); // let the os scheduler be our fuzz + std.time.sleep(1); // let the os scheduler be our fuzz _ = @atomicRmw(isize, &ctx.get_sum, builtin.AtomicRmwOp.Add, node.data, builtin.AtomicOrder.SeqCst); _ = @atomicRmw(usize, &ctx.get_count, builtin.AtomicRmwOp.Add, 1, builtin.AtomicOrder.SeqCst); } diff --git a/std/build.zig b/std/build.zig index ff64c6cb93..0f2d6093c4 100644 --- a/std/build.zig +++ b/std/build.zig @@ -14,6 +14,7 @@ const Term = os.ChildProcess.Term; const BufSet = std.BufSet; const BufMap = std.BufMap; const fmt_lib = std.fmt; +const File = std.fs.File; pub const FmtStep = @import("build/fmt.zig").FmtStep; @@ -668,10 +669,10 @@ pub const Builder = struct { } fn copyFile(self: *Builder, source_path: []const u8, dest_path: []const u8) !void { - return self.copyFileMode(source_path, dest_path, os.File.default_mode); + return self.copyFileMode(source_path, dest_path, File.default_mode); } - fn copyFileMode(self: *Builder, source_path: []const u8, dest_path: []const u8, mode: os.File.Mode) !void { + fn copyFileMode(self: *Builder, source_path: []const u8, dest_path: []const u8, mode: File.Mode) !void { if (self.verbose) { warn("cp {} {}\n", source_path, dest_path); } @@ -75,7 +75,7 @@ pub extern "c" fn sysctlnametomib(name: [*]const u8, mibp: ?*c_int, sizep: ?*usi pub extern "c" fn bind(socket: fd_t, address: ?*const sockaddr, address_len: socklen_t) c_int; pub extern "c" fn socket(domain: c_int, sock_type: c_int, protocol: c_int) c_int; pub extern "c" fn kill(pid: pid_t, sig: c_int) c_int; -pub extern "c" fn getdirentries(fd: fd_t, buf_ptr: [*]u8, nbytes: usize, basep: *i64) usize; +pub extern "c" fn getdirentries(fd: fd_t, buf_ptr: [*]u8, nbytes: usize, basep: *i64) isize; pub extern "c" fn openat(fd: c_int, path: [*]const u8, flags: c_int) c_int; pub extern "c" fn setgid(ruid: c_uint, euid: c_uint) c_int; pub extern "c" fn setuid(uid: c_uint) c_int; diff --git a/std/child_process.zig b/std/child_process.zig index 9a0f20d1c5..fa20a5e814 100644 --- a/std/child_process.zig +++ b/std/child_process.zig @@ -3,7 +3,7 @@ const cstr = std.cstr; const unicode = std.unicode; const io = std.io; const os = std.os; -const posix = os.posix; +const File = std.fs.File; const windows = os.windows; const mem = std.mem; const debug = std.debug; @@ -23,9 +23,9 @@ pub const ChildProcess = struct { pub allocator: *mem.Allocator, - pub stdin: ?os.File, - pub stdout: ?os.File, - pub stderr: ?os.File, + pub stdin: ?File, + pub stdout: ?File, + pub stderr: ?File, pub term: ?(SpawnError!Term), @@ -148,12 +148,7 @@ pub const ChildProcess = struct { return term; } - if (!windows.TerminateProcess(self.handle, exit_code)) { - const err = windows.GetLastError(); - return switch (err) { - else => os.unexpectedErrorWindows(err), - }; - } + try windows.TerminateProcess(self.handle, exit_code); try self.waitUnwrappedWindows(); return self.term.?; } @@ -163,16 +158,7 @@ pub const ChildProcess = struct { self.cleanupStreams(); return term; } - const ret = posix.kill(self.pid, posix.SIGTERM); - const err = posix.getErrno(ret); - if (err > 0) { - return switch (err) { - posix.EINVAL => unreachable, - posix.EPERM => error.PermissionDenied, - posix.ESRCH => error.ProcessNotFound, - else => os.unexpectedErrorPosix(err), - }; - } + try os.kill(self.pid, os.SIGTERM); self.waitUnwrapped(); return self.term.?; } @@ -267,19 +253,9 @@ pub const ChildProcess = struct { } fn waitUnwrapped(self: *ChildProcess) void { - var status: i32 = undefined; - while (true) { - const err = posix.getErrno(posix.waitpid(self.pid, &status, 0)); - if (err > 0) { - switch (err) { - posix.EINTR => continue, - else => unreachable, - } - } - self.cleanupStreams(); - self.handleWaitResult(status); - return; - } + const status = os.waitpid(self.pid, 0); + self.cleanupStreams(); + self.handleWaitResult(status); } fn handleWaitResult(self: *ChildProcess, status: i32) void { @@ -324,34 +300,34 @@ pub const ChildProcess = struct { } fn statusToTerm(status: i32) Term { - return if (posix.WIFEXITED(status)) - Term{ .Exited = posix.WEXITSTATUS(status) } - else if (posix.WIFSIGNALED(status)) - Term{ .Signal = posix.WTERMSIG(status) } - else if (posix.WIFSTOPPED(status)) - Term{ .Stopped = posix.WSTOPSIG(status) } + return if (os.WIFEXITED(status)) + Term{ .Exited = os.WEXITSTATUS(status) } + else if (os.WIFSIGNALED(status)) + Term{ .Signal = os.WTERMSIG(status) } + else if (os.WIFSTOPPED(status)) + Term{ .Stopped = os.WSTOPSIG(status) } else Term{ .Unknown = status }; } fn spawnPosix(self: *ChildProcess) !void { - const stdin_pipe = if (self.stdin_behavior == StdIo.Pipe) try makePipe() else undefined; + const stdin_pipe = if (self.stdin_behavior == StdIo.Pipe) try os.pipe() else undefined; errdefer if (self.stdin_behavior == StdIo.Pipe) { destroyPipe(stdin_pipe); }; - const stdout_pipe = if (self.stdout_behavior == StdIo.Pipe) try makePipe() else undefined; + const stdout_pipe = if (self.stdout_behavior == StdIo.Pipe) try os.pipe() else undefined; errdefer if (self.stdout_behavior == StdIo.Pipe) { destroyPipe(stdout_pipe); }; - const stderr_pipe = if (self.stderr_behavior == StdIo.Pipe) try makePipe() else undefined; + const stderr_pipe = if (self.stderr_behavior == StdIo.Pipe) try os.pipe() else undefined; errdefer if (self.stderr_behavior == StdIo.Pipe) { destroyPipe(stderr_pipe); }; const any_ignore = (self.stdin_behavior == StdIo.Ignore or self.stdout_behavior == StdIo.Ignore or self.stderr_behavior == StdIo.Ignore); - const dev_null_fd = if (any_ignore) try os.posixOpenC(c"/dev/null", posix.O_RDWR, 0) else undefined; + const dev_null_fd = if (any_ignore) try os.openC(c"/dev/null", os.O_RDWR, 0) else undefined; defer { if (any_ignore) os.close(dev_null_fd); } @@ -372,7 +348,7 @@ pub const ChildProcess = struct { // This pipe is used to communicate errors between the time of fork // and execve from the child process to the parent process. - const err_pipe = try makePipe(); + const err_pipe = try os.pipe(); errdefer destroyPipe(err_pipe); const pid_result = try posix.fork(); @@ -413,17 +389,17 @@ pub const ChildProcess = struct { // we are the parent const pid = @intCast(i32, pid_result); if (self.stdin_behavior == StdIo.Pipe) { - self.stdin = os.File.openHandle(stdin_pipe[1]); + self.stdin = File.openHandle(stdin_pipe[1]); } else { self.stdin = null; } if (self.stdout_behavior == StdIo.Pipe) { - self.stdout = os.File.openHandle(stdout_pipe[0]); + self.stdout = File.openHandle(stdout_pipe[0]); } else { self.stdout = null; } if (self.stderr_behavior == StdIo.Pipe) { - self.stderr = os.File.openHandle(stderr_pipe[0]); + self.stderr = File.openHandle(stderr_pipe[0]); } else { self.stderr = null; } @@ -608,17 +584,17 @@ pub const ChildProcess = struct { }; if (g_hChildStd_IN_Wr) |h| { - self.stdin = os.File.openHandle(h); + self.stdin = File.openHandle(h); } else { self.stdin = null; } if (g_hChildStd_OUT_Rd) |h| { - self.stdout = os.File.openHandle(h); + self.stdout = File.openHandle(h); } else { self.stdout = null; } if (g_hChildStd_ERR_Rd) |h| { - self.stderr = os.File.openHandle(h); + self.stderr = File.openHandle(h); } else { self.stderr = null; } @@ -751,18 +727,6 @@ fn windowsMakePipeOut(rd: *?windows.HANDLE, wr: *?windows.HANDLE, sattr: *const wr.* = wr_h; } -fn makePipe() ![2]i32 { - var fds: [2]i32 = undefined; - const err = posix.getErrno(posix.pipe(&fds)); - if (err > 0) { - return switch (err) { - posix.EMFILE, posix.ENFILE => error.SystemResources, - else => os.unexpectedErrorPosix(err), - }; - } - return fds; -} - fn destroyPipe(pipe: [2]i32) void { os.close(pipe[0]); os.close(pipe[1]); @@ -778,12 +742,12 @@ fn forkChildErrReport(fd: i32, err: ChildProcess.SpawnError) noreturn { const ErrInt = @IntType(false, @sizeOf(anyerror) * 8); fn writeIntFd(fd: i32, value: ErrInt) !void { - const stream = &os.File.openHandle(fd).outStream().stream; + const stream = &File.openHandle(fd).outStream().stream; stream.writeIntNative(ErrInt, value) catch return error.SystemResources; } fn readIntFd(fd: i32) !ErrInt { - const stream = &os.File.openHandle(fd).inStream().stream; + const stream = &File.openHandle(fd).inStream().stream; return stream.readIntNative(ErrInt) catch return error.SystemResources; } diff --git a/std/coff.zig b/std/coff.zig index b5b5733989..87f3f089de 100644 --- a/std/coff.zig +++ b/std/coff.zig @@ -3,6 +3,7 @@ const std = @import("std.zig"); const io = std.io; const mem = std.mem; const os = std.os; +const File = std.fs.File; const ArrayList = std.ArrayList; @@ -28,7 +29,7 @@ pub const CoffError = error{ }; pub const Coff = struct { - in_file: os.File, + in_file: File, allocator: *mem.Allocator, coff_header: CoffHeader, @@ -77,7 +78,7 @@ pub const Coff = struct { try self.loadOptionalHeader(&file_stream); } - fn loadOptionalHeader(self: *Coff, file_stream: *os.File.InStream) !void { + fn loadOptionalHeader(self: *Coff, file_stream: *File.InStream) !void { const in = &file_stream.stream; self.pe_header.magic = try in.readIntLittle(u16); // For now we're only interested in finding the reference to the .pdb, diff --git a/std/crypto/throughput_test.zig b/std/crypto/throughput_test.zig index 73a2a86124..aee06571a0 100644 --- a/std/crypto/throughput_test.zig +++ b/std/crypto/throughput_test.zig @@ -1,6 +1,6 @@ const builtin = @import("builtin"); const std = @import("std"); -const time = std.os.time; +const time = std.time; const Timer = time.Timer; const crypto = @import("../crypto.zig"); diff --git a/std/debug.zig b/std/debug.zig index e30efebdbc..83daad6dc5 100644 --- a/std/debug.zig +++ b/std/debug.zig @@ -12,6 +12,7 @@ const windows = os.windows; const ArrayList = std.ArrayList; const builtin = @import("builtin"); const maxInt = std.math.maxInt; +const File = std.fs.File; const leb = @import("debug/leb128.zig"); @@ -36,10 +37,10 @@ const Module = struct { /// Tries to write to stderr, unbuffered, and ignores any error returned. /// Does not append a newline. -var stderr_file: os.File = undefined; -var stderr_file_out_stream: os.File.OutStream = undefined; +var stderr_file: File = undefined; +var stderr_file_out_stream: File.OutStream = undefined; -var stderr_stream: ?*io.OutStream(os.File.WriteError) = null; +var stderr_stream: ?*io.OutStream(File.WriteError) = null; var stderr_mutex = std.Mutex.init(); pub fn warn(comptime fmt: []const u8, args: ...) void { const held = stderr_mutex.acquire(); @@ -48,7 +49,7 @@ pub fn warn(comptime fmt: []const u8, args: ...) void { stderr.print(fmt, args) catch return; } -pub fn getStderrStream() !*io.OutStream(os.File.WriteError) { +pub fn getStderrStream() !*io.OutStream(File.WriteError) { if (stderr_stream) |st| { return st; } else { @@ -1003,7 +1004,7 @@ pub fn openElfDebugInfo( fn openSelfDebugInfoLinux(allocator: *mem.Allocator) !DwarfInfo { const S = struct { - var self_exe_file: os.File = undefined; + var self_exe_file: File = undefined; var self_exe_mmap_seekable: io.SliceSeekableInStream = undefined; }; @@ -1112,7 +1113,7 @@ fn openSelfDebugInfoMacOs(allocator: *mem.Allocator) !DebugInfo { } fn printLineFromFileAnyOs(out_stream: var, line_info: LineInfo) !void { - var f = try os.File.openRead(line_info.file_name); + var f = try File.openRead(line_info.file_name); defer f.close(); // TODO fstat and make sure that the file has the correct size diff --git a/std/dynamic_library.zig b/std/dynamic_library.zig index 14bde98f1a..2832b54dbb 100644 --- a/std/dynamic_library.zig +++ b/std/dynamic_library.zig @@ -1,5 +1,4 @@ const builtin = @import("builtin"); -const Os = builtin.Os; const std = @import("std.zig"); const mem = std.mem; @@ -8,14 +7,13 @@ const os = std.os; const assert = std.debug.assert; const testing = std.testing; const elf = std.elf; -const linux = os.linux; const windows = os.windows; const win_util = @import("os/windows/util.zig"); const maxInt = std.math.maxInt; pub const DynLib = switch (builtin.os) { - Os.linux => LinuxDynLib, - Os.windows => WindowsDynLib, + .linux => LinuxDynLib, + .windows => WindowsDynLib, else => void, }; @@ -110,20 +108,20 @@ pub const LinuxDynLib = struct { /// Trusts the file pub fn open(allocator: *mem.Allocator, path: []const u8) !DynLib { - const fd = try std.os.posixOpen(path, 0, linux.O_RDONLY | linux.O_CLOEXEC); + const fd = try os.open(path, 0, os.O_RDONLY | os.O_CLOEXEC); errdefer std.os.close(fd); const size = @intCast(usize, (try std.os.posixFStat(fd)).size); - const addr = linux.mmap( + const addr = os.mmap( null, size, - linux.PROT_READ | linux.PROT_EXEC, - linux.MAP_PRIVATE | linux.MAP_LOCKED, + os.PROT_READ | os.PROT_EXEC, + os.MAP_PRIVATE | os.MAP_LOCKED, fd, 0, ); - errdefer _ = linux.munmap(addr, size); + errdefer os.munmap(addr, size); const bytes = @intToPtr([*]align(mem.page_size) u8, addr)[0..size]; @@ -136,7 +134,7 @@ pub const LinuxDynLib = struct { } pub fn close(self: *DynLib) void { - _ = linux.munmap(self.map_addr, self.map_size); + os.munmap(self.map_addr, self.map_size); std.os.close(self.fd); self.* = undefined; } @@ -149,7 +147,7 @@ pub const LinuxDynLib = struct { pub const ElfLib = struct { strings: [*]u8, syms: [*]elf.Sym, - hashtab: [*]linux.Elf_Symndx, + hashtab: [*]os.Elf_Symndx, versym: ?[*]u16, verdef: ?*elf.Verdef, base: usize, @@ -184,7 +182,7 @@ pub const ElfLib = struct { var maybe_strings: ?[*]u8 = null; var maybe_syms: ?[*]elf.Sym = null; - var maybe_hashtab: ?[*]linux.Elf_Symndx = null; + var maybe_hashtab: ?[*]os.Elf_Symndx = null; var maybe_versym: ?[*]u16 = null; var maybe_verdef: ?*elf.Verdef = null; @@ -195,7 +193,7 @@ pub const ElfLib = struct { switch (dynv[i]) { elf.DT_STRTAB => maybe_strings = @intToPtr([*]u8, p), elf.DT_SYMTAB => maybe_syms = @intToPtr([*]elf.Sym, p), - elf.DT_HASH => maybe_hashtab = @intToPtr([*]linux.Elf_Symndx, p), + elf.DT_HASH => maybe_hashtab = @intToPtr([*]os.Elf_Symndx, p), elf.DT_VERSYM => maybe_versym = @intToPtr([*]u16, p), elf.DT_VERDEF => maybe_verdef = @intToPtr(*elf.Verdef, p), else => {}, @@ -283,8 +281,8 @@ pub const WindowsDynLib = struct { test "dynamic_library" { const libname = switch (builtin.os) { - Os.linux => "invalid_so.so", - Os.windows => "invalid_dll.dll", + .linux => "invalid_so.so", + .windows => "invalid_dll.dll", else => return, }; diff --git a/std/elf.zig b/std/elf.zig index 898f9d83f8..c605a177a5 100644 --- a/std/elf.zig +++ b/std/elf.zig @@ -6,6 +6,7 @@ const math = std.math; const mem = std.mem; const debug = std.debug; const InStream = std.stream.InStream; +const File = std.fs.File; pub const AT_NULL = 0; pub const AT_IGNORE = 1; @@ -367,7 +368,7 @@ pub const Elf = struct { string_section: *SectionHeader, section_headers: []SectionHeader, allocator: *mem.Allocator, - prealloc_file: os.File, + prealloc_file: File, /// Call close when done. pub fn openPath(elf: *Elf, allocator: *mem.Allocator, path: []const u8) !void { @@ -375,7 +376,7 @@ pub const Elf = struct { } /// Call close when done. - pub fn openFile(elf: *Elf, allocator: *mem.Allocator, file: os.File) !void { + pub fn openFile(elf: *Elf, allocator: *mem.Allocator, file: File) !void { @compileError("TODO implement"); } diff --git a/std/event/fs.zig b/std/event/fs.zig index f3118fe97a..346a6c6b69 100644 --- a/std/event/fs.zig +++ b/std/event/fs.zig @@ -9,6 +9,7 @@ const posix = os.posix; const windows = os.windows; const Loop = event.Loop; const fd_t = posix.fd_t; +const File = std.fs.File; pub const RequestNode = std.atomic.Queue(Request).Node; @@ -52,20 +53,20 @@ pub const Request = struct { /// must be null terminated. TODO https://github.com/ziglang/zig/issues/265 path: []const u8, flags: u32, - mode: os.File.Mode, + mode: File.Mode, result: Error!fd_t, - pub const Error = os.File.OpenError; + pub const Error = File.OpenError; }; pub const WriteFile = struct { /// must be null terminated. TODO https://github.com/ziglang/zig/issues/265 path: []const u8, contents: []const u8, - mode: os.File.Mode, + mode: File.Mode, result: Error!void, - pub const Error = os.File.OpenError || os.File.WriteError; + pub const Error = File.OpenError || File.WriteError; }; pub const Close = struct { @@ -74,7 +75,7 @@ pub const Request = struct { }; }; -pub const PWriteVError = error{OutOfMemory} || os.File.WriteError; +pub const PWriteVError = error{OutOfMemory} || File.WriteError; /// data - just the inner references - must live until pwritev promise completes. pub async fn pwritev(loop: *Loop, fd: fd_t, data: []const []const u8, offset: usize) PWriteVError!void { @@ -209,7 +210,7 @@ pub async fn pwritevPosix( return req_node.data.msg.PWriteV.result; } -pub const PReadVError = error{OutOfMemory} || os.File.ReadError; +pub const PReadVError = error{OutOfMemory} || File.ReadError; /// data - just the inner references - must live until preadv promise completes. pub async fn preadv(loop: *Loop, fd: fd_t, data: []const []u8, offset: usize) PReadVError!usize { @@ -361,8 +362,8 @@ pub async fn openPosix( loop: *Loop, path: []const u8, flags: u32, - mode: os.File.Mode, -) os.File.OpenError!fd_t { + mode: File.Mode, +) File.OpenError!fd_t { // workaround for https://github.com/ziglang/zig/issues/1194 suspend { resume @handle(); @@ -401,11 +402,11 @@ pub async fn openPosix( return req_node.data.msg.Open.result; } -pub async fn openRead(loop: *Loop, path: []const u8) os.File.OpenError!fd_t { +pub async fn openRead(loop: *Loop, path: []const u8) File.OpenError!fd_t { switch (builtin.os) { builtin.Os.macosx, builtin.Os.linux, builtin.Os.freebsd, builtin.Os.netbsd => { const flags = posix.O_LARGEFILE | posix.O_RDONLY | posix.O_CLOEXEC; - return await (async openPosix(loop, path, flags, os.File.default_mode) catch unreachable); + return await (async openPosix(loop, path, flags, File.default_mode) catch unreachable); }, builtin.Os.windows => return os.windowsOpen( @@ -422,12 +423,12 @@ pub async fn openRead(loop: *Loop, path: []const u8) os.File.OpenError!fd_t { /// Creates if does not exist. Truncates the file if it exists. /// Uses the default mode. -pub async fn openWrite(loop: *Loop, path: []const u8) os.File.OpenError!fd_t { - return await (async openWriteMode(loop, path, os.File.default_mode) catch unreachable); +pub async fn openWrite(loop: *Loop, path: []const u8) File.OpenError!fd_t { + return await (async openWriteMode(loop, path, File.default_mode) catch unreachable); } /// Creates if does not exist. Truncates the file if it exists. -pub async fn openWriteMode(loop: *Loop, path: []const u8, mode: os.File.Mode) os.File.OpenError!fd_t { +pub async fn openWriteMode(loop: *Loop, path: []const u8, mode: File.Mode) File.OpenError!fd_t { switch (builtin.os) { builtin.Os.macosx, builtin.Os.linux, @@ -435,7 +436,7 @@ pub async fn openWriteMode(loop: *Loop, path: []const u8, mode: os.File.Mode) os builtin.Os.netbsd, => { const flags = posix.O_LARGEFILE | posix.O_WRONLY | posix.O_CREAT | posix.O_CLOEXEC | posix.O_TRUNC; - return await (async openPosix(loop, path, flags, os.File.default_mode) catch unreachable); + return await (async openPosix(loop, path, flags, File.default_mode) catch unreachable); }, builtin.Os.windows => return os.windowsOpen( path, @@ -452,8 +453,8 @@ pub async fn openWriteMode(loop: *Loop, path: []const u8, mode: os.File.Mode) os pub async fn openReadWrite( loop: *Loop, path: []const u8, - mode: os.File.Mode, -) os.File.OpenError!fd_t { + mode: File.Mode, +) File.OpenError!fd_t { switch (builtin.os) { builtin.Os.macosx, builtin.Os.linux, builtin.Os.freebsd, builtin.Os.netbsd => { const flags = posix.O_LARGEFILE | posix.O_RDWR | posix.O_CREAT | posix.O_CLOEXEC; @@ -605,11 +606,11 @@ pub const CloseOperation = struct { /// contents must remain alive until writeFile completes. /// TODO make this atomic or provide writeFileAtomic and rename this one to writeFileTruncate pub async fn writeFile(loop: *Loop, path: []const u8, contents: []const u8) !void { - return await (async writeFileMode(loop, path, contents, os.File.default_mode) catch unreachable); + return await (async writeFileMode(loop, path, contents, File.default_mode) catch unreachable); } /// contents must remain alive until writeFile completes. -pub async fn writeFileMode(loop: *Loop, path: []const u8, contents: []const u8, mode: os.File.Mode) !void { +pub async fn writeFileMode(loop: *Loop, path: []const u8, contents: []const u8, mode: File.Mode) !void { switch (builtin.os) { builtin.Os.linux, builtin.Os.macosx, @@ -634,7 +635,7 @@ async fn writeFileWindows(loop: *Loop, path: []const u8, contents: []const u8) ! try await (async pwriteWindows(loop, handle, contents, 0) catch unreachable); } -async fn writeFileModeThread(loop: *Loop, path: []const u8, contents: []const u8, mode: os.File.Mode) !void { +async fn writeFileModeThread(loop: *Loop, path: []const u8, contents: []const u8, mode: File.Mode) !void { // workaround for https://github.com/ziglang/zig/issues/1194 suspend { resume @handle(); @@ -1363,7 +1364,7 @@ async fn testFsWatch(loop: *Loop) !void { defer if (!ev_consumed) cancel ev; // overwrite line 2 - const fd = try await try async openReadWrite(loop, file_path, os.File.default_mode); + const fd = try await try async openReadWrite(loop, file_path, File.default_mode); { defer os.close(fd); @@ -1390,7 +1391,7 @@ pub const OutStream = struct { loop: *Loop, offset: usize, - pub const Error = os.File.WriteError; + pub const Error = File.WriteError; pub const Stream = event.io.OutStream(Error); pub fn init(loop: *Loop, fd: fd_t, offset: usize) OutStream { diff --git a/std/event/group.zig b/std/event/group.zig index 455d1bd60c..143efd76c3 100644 --- a/std/event/group.zig +++ b/std/event/group.zig @@ -155,7 +155,7 @@ async fn testGroup(loop: *Loop) void { } async fn sleepALittle(count: *usize) void { - std.os.time.sleep(1 * std.os.time.millisecond); + std.time.sleep(1 * std.time.millisecond); _ = @atomicRmw(usize, count, AtomicRmwOp.Add, 1, AtomicOrder.SeqCst); } diff --git a/std/event/loop.zig b/std/event/loop.zig index 76b1f6455b..71bc45d48f 100644 --- a/std/event/loop.zig +++ b/std/event/loop.zig @@ -789,13 +789,13 @@ pub const Loop = struct { msg.result = os.posix_preadv(msg.fd, msg.iov.ptr, msg.iov.len, msg.offset); }, @TagType(fs.Request.Msg).Open => |*msg| { - msg.result = os.posixOpenC(msg.path.ptr, msg.flags, msg.mode); + msg.result = os.openC(msg.path.ptr, msg.flags, msg.mode); }, @TagType(fs.Request.Msg).Close => |*msg| os.close(msg.fd), @TagType(fs.Request.Msg).WriteFile => |*msg| blk: { const flags = posix.O_LARGEFILE | posix.O_WRONLY | posix.O_CREAT | posix.O_CLOEXEC | posix.O_TRUNC; - const fd = os.posixOpenC(msg.path.ptr, flags, msg.mode) catch |err| { + const fd = os.openC(msg.path.ptr, flags, msg.mode) catch |err| { msg.result = err; break :blk; }; diff --git a/std/event/net.zig b/std/event/net.zig index d4b79d6872..bb492f1715 100644 --- a/std/event/net.zig +++ b/std/event/net.zig @@ -6,11 +6,12 @@ const mem = std.mem; const os = std.os; const posix = os.posix; const Loop = std.event.Loop; +const File = std.fs.File; const fd_t = posix.fd_t; pub const Server = struct { - handleRequestFn: async<*mem.Allocator> fn (*Server, *const std.net.Address, os.File) void, + handleRequestFn: async<*mem.Allocator> fn (*Server, *const std.net.Address, File) void, loop: *Loop, sockfd: ?i32, @@ -42,7 +43,7 @@ pub const Server = struct { pub fn listen( self: *Server, address: *const std.net.Address, - handleRequestFn: async<*mem.Allocator> fn (*Server, *const std.net.Address, os.File) void, + handleRequestFn: async<*mem.Allocator> fn (*Server, *const std.net.Address, File) void, ) !void { self.handleRequestFn = handleRequestFn; @@ -83,7 +84,7 @@ pub const Server = struct { suspend; // we will get resumed by epoll_wait in the event loop continue; } - var socket = os.File.openHandle(accepted_fd); + var socket = File.openHandle(accepted_fd); _ = async<self.loop.allocator> self.handleRequestFn(self, &accepted_addr, socket) catch |err| switch (err) { error.OutOfMemory => { socket.close(); @@ -250,7 +251,7 @@ pub async fn readv(loop: *Loop, fd: fd_t, data: []const []u8) !usize { return await (async readvPosix(loop, fd, iovecs.ptr, data.len) catch unreachable); } -pub async fn connect(loop: *Loop, _address: *const std.net.Address) !os.File { +pub async fn connect(loop: *Loop, _address: *const std.net.Address) !File { var address = _address.*; // TODO https://github.com/ziglang/zig/issues/1592 const sockfd = try os.posixSocket(posix.AF_INET, posix.SOCK_STREAM | posix.SOCK_CLOEXEC | posix.SOCK_NONBLOCK, posix.PROTO_tcp); @@ -260,7 +261,7 @@ pub async fn connect(loop: *Loop, _address: *const std.net.Address) !os.File { try await try async loop.linuxWaitFd(sockfd, posix.EPOLLIN | posix.EPOLLOUT | posix.EPOLLET); try os.posixGetSockOptConnectError(sockfd); - return os.File.openHandle(sockfd); + return File.openHandle(sockfd); } test "listen on a port, send bytes, receive bytes" { @@ -276,7 +277,7 @@ test "listen on a port, send bytes, receive bytes" { tcp_server: Server, const Self = @This(); - async<*mem.Allocator> fn handler(tcp_server: *Server, _addr: *const std.net.Address, _socket: os.File) void { + async<*mem.Allocator> fn handler(tcp_server: *Server, _addr: *const std.net.Address, _socket: File) void { const self = @fieldParentPtr(Self, "tcp_server", tcp_server); var socket = _socket; // TODO https://github.com/ziglang/zig/issues/1592 defer socket.close(); @@ -289,7 +290,7 @@ test "listen on a port, send bytes, receive bytes" { cancel @handle(); } } - async fn errorableHandler(self: *Self, _addr: *const std.net.Address, _socket: os.File) !void { + async fn errorableHandler(self: *Self, _addr: *const std.net.Address, _socket: File) !void { const addr = _addr.*; // TODO https://github.com/ziglang/zig/issues/1592 var socket = _socket; // TODO https://github.com/ziglang/zig/issues/1592 diff --git a/std/event/rwlock.zig b/std/event/rwlock.zig index 76b364fedc..00f3c0bc60 100644 --- a/std/event/rwlock.zig +++ b/std/event/rwlock.zig @@ -271,7 +271,7 @@ async fn writeRunner(lock: *RwLock) void { var i: usize = 0; while (i < shared_test_data.len) : (i += 1) { - std.os.time.sleep(100 * std.os.time.microsecond); + std.time.sleep(100 * std.time.microsecond); const lock_promise = async lock.acquireWrite() catch @panic("out of memory"); const handle = await lock_promise; defer handle.release(); @@ -286,7 +286,7 @@ async fn writeRunner(lock: *RwLock) void { async fn readRunner(lock: *RwLock) void { suspend; // resumed by onNextTick - std.os.time.sleep(1); + std.time.sleep(1); var i: usize = 0; while (i < shared_test_data.len) : (i += 1) { diff --git a/std/fs.zig b/std/fs.zig index 50d0b0df70..91e4aca824 100644 --- a/std/fs.zig +++ b/std/fs.zig @@ -11,6 +11,7 @@ pub const deleteFile = os.unlink; pub const deleteFileC = os.unlinkC; pub const rename = os.rename; pub const renameC = os.renameC; +pub const renameW = os.renameW; pub const changeCurDir = os.chdir; pub const changeCurDirC = os.chdirC; pub const realpath = os.realpath; @@ -25,24 +26,24 @@ pub const GetAppDataDirError = @import("fs/get_app_data_dir.zig").GetAppDataDirE /// fit into a UTF-8 encoded array of this length. /// path being too long if it is this 0long pub const MAX_PATH_BYTES = switch (builtin.os) { - .linux, .macosx, .ios, .freebsd, .netbsd => posix.PATH_MAX, + .linux, .macosx, .ios, .freebsd, .netbsd => os.PATH_MAX, // Each UTF-16LE character may be expanded to 3 UTF-8 bytes. // If it would require 4 UTF-8 bytes, then there would be a surrogate // pair in the UTF-16LE, and we (over)account 3 bytes for it that way. // +1 for the null byte at the end, which can be encoded in 1 byte. - .windows => posix.PATH_MAX_WIDE * 3 + 1, + .windows => os.windows.PATH_MAX_WIDE * 3 + 1, else => @compileError("Unsupported OS"), }; /// The result is a slice of `out_buffer`, from index `0`. pub fn getCwd(out_buffer: *[MAX_PATH_BYTES]u8) ![]u8 { - return posix.getcwd(out_buffer); + return os.getcwd(out_buffer); } /// Caller must free the returned memory. pub fn getCwdAlloc(allocator: *Allocator) ![]u8 { var buf: [MAX_PATH_BYTES]u8 = undefined; - return mem.dupe(allocator, u8, try posix.getcwd(&buf)); + return mem.dupe(allocator, u8, try os.getcwd(&buf)); } test "getCwdAlloc" { @@ -90,7 +91,7 @@ pub fn atomicSymLink(allocator: *Allocator, existing_path: []const u8, new_path: /// in the same directory as dest_path. /// Destination file will have the same mode as the source file. pub fn copyFile(source_path: []const u8, dest_path: []const u8) !void { - var in_file = try os.File.openRead(source_path); + var in_file = try File.openRead(source_path); defer in_file.close(); const mode = try in_file.mode(); @@ -113,7 +114,7 @@ pub fn copyFile(source_path: []const u8, dest_path: []const u8) !void { /// merged and readily available, /// there is a possibility of power loss or application termination leaving temporary files present pub fn copyFileMode(source_path: []const u8, dest_path: []const u8, mode: File.Mode) !void { - var in_file = try os.File.openRead(source_path); + var in_file = try File.openRead(source_path); defer in_file.close(); var atomic_file = try AtomicFile.init(dest_path, mode); @@ -130,12 +131,12 @@ pub fn copyFileMode(source_path: []const u8, dest_path: []const u8, mode: File.M } pub const AtomicFile = struct { - file: os.File, + file: File, tmp_path_buf: [MAX_PATH_BYTES]u8, dest_path: []const u8, finished: bool, - const InitError = os.File.OpenError; + const InitError = File.OpenError; /// dest_path must remain valid for the lifetime of AtomicFile /// call finish to atomically replace dest_path with contents @@ -161,7 +162,7 @@ pub const AtomicFile = struct { try getRandomBytes(rand_buf[0..]); b64_fs_encoder.encode(tmp_path_buf[dirname_component_len..tmp_path_len], rand_buf); - const file = os.File.openWriteNoClobberC(&tmp_path_buf, mode) catch |err| switch (err) { + const file = File.openWriteNoClobberC(&tmp_path_buf, mode) catch |err| switch (err) { error.PathAlreadyExists => continue, // TODO zig should figure out that this error set does not include PathAlreadyExists since // it is handled in the above switch @@ -190,16 +191,13 @@ pub const AtomicFile = struct { assert(!self.finished); self.file.close(); self.finished = true; - if (is_posix) { - const dest_path_c = try toPosixPath(self.dest_path); - return renameC(&self.tmp_path_buf, &dest_path_c); - } else if (is_windows) { - const dest_path_w = try posix.sliceToPrefixedFileW(self.dest_path); - const tmp_path_w = try posix.cStrToPrefixedFileW(&self.tmp_path_buf); - return renameW(&tmp_path_w, &dest_path_w); - } else { - @compileError("Unsupported OS"); + if (os.windows.is_the_target) { + const dest_path_w = try os.windows.sliceToPrefixedFileW(self.dest_path); + const tmp_path_w = try os.windows.cStrToPrefixedFileW(&self.tmp_path_buf); + return os.renameW(&tmp_path_w, &dest_path_w); } + const dest_path_c = try os.toPosixPath(self.dest_path); + return os.renameC(&self.tmp_path_buf, &dest_path_c); } }; @@ -207,17 +205,17 @@ const default_new_dir_mode = 0o755; /// Create a new directory. pub fn makeDir(dir_path: []const u8) !void { - return posix.mkdir(dir_path, default_new_dir_mode); + return os.mkdir(dir_path, default_new_dir_mode); } /// Same as `makeDir` except the parameter is a null-terminated UTF8-encoded string. pub fn makeDirC(dir_path: [*]const u8) !void { - return posix.mkdirC(dir_path, default_new_dir_mode); + return os.mkdirC(dir_path, default_new_dir_mode); } /// Same as `makeDir` except the parameter is a null-terminated UTF16LE-encoded string. pub fn makeDirW(dir_path: [*]const u16) !void { - return posix.mkdirW(dir_path, default_new_dir_mode); + return os.mkdirW(dir_path, default_new_dir_mode); } /// Calls makeDir recursively to make an entire path. Returns success if the path @@ -260,17 +258,17 @@ pub fn makePath(allocator: *Allocator, full_path: []const u8) !void { /// Returns `error.DirNotEmpty` if the directory is not empty. /// To delete a directory recursively, see `deleteTree`. pub fn deleteDir(dir_path: []const u8) DeleteDirError!void { - return posix.rmdir(dir_path); + return os.rmdir(dir_path); } /// Same as `deleteDir` except the parameter is a null-terminated UTF8-encoded string. pub fn deleteDirC(dir_path: [*]const u8) DeleteDirError!void { - return posix.rmdirC(dir_path); + return os.rmdirC(dir_path); } /// Same as `deleteDir` except the parameter is a null-terminated UTF16LE-encoded string. pub fn deleteDirW(dir_path: [*]const u16) DeleteDirError!void { - return posix.rmdirW(dir_path); + return os.rmdirW(dir_path); } /// Whether ::full_path describes a symlink, file, or directory, this function @@ -383,22 +381,22 @@ pub const Dir = struct { allocator: *Allocator, pub const Handle = switch (builtin.os) { - Os.macosx, Os.ios, Os.freebsd, Os.netbsd => struct { + .macosx, .ios, .freebsd, .netbsd => struct { fd: i32, seek: i64, buf: []u8, index: usize, end_index: usize, }, - Os.linux => struct { + .linux => struct { fd: i32, buf: []u8, index: usize, end_index: usize, }, - Os.windows => struct { - handle: windows.HANDLE, - find_file_data: windows.WIN32_FIND_DATAW, + .windows => struct { + handle: os.windows.HANDLE, + find_file_data: os.windows.WIN32_FIND_DATAW, first: bool, name_data: [256]u8, }, @@ -449,9 +447,9 @@ pub const Dir = struct { return Dir{ .allocator = allocator, .handle = switch (builtin.os) { - Os.windows => blk: { - var find_file_data: windows.WIN32_FIND_DATAW = undefined; - const handle = try windows_util.windowsFindFirstFile(dir_path, &find_file_data); + .windows => blk: { + var find_file_data: os.windows.WIN32_FIND_DATAW = undefined; + const handle = try os.windows.FindFirstFile(dir_path, &find_file_data); break :blk Handle{ .handle = handle, .find_file_data = find_file_data, // TODO guaranteed copy elision @@ -459,23 +457,15 @@ pub const Dir = struct { .name_data = undefined, }; }, - Os.macosx, Os.ios, Os.freebsd, Os.netbsd => Handle{ - .fd = try posixOpen( - dir_path, - posix.O_RDONLY | posix.O_NONBLOCK | posix.O_DIRECTORY | posix.O_CLOEXEC, - 0, - ), + .macosx, .ios, .freebsd, .netbsd => Handle{ + .fd = try os.open(dir_path, os.O_RDONLY | os.O_NONBLOCK | os.O_DIRECTORY | os.O_CLOEXEC, 0), .seek = 0, .index = 0, .end_index = 0, .buf = []u8{}, }, - Os.linux => Handle{ - .fd = try posixOpen( - dir_path, - posix.O_RDONLY | posix.O_DIRECTORY | posix.O_CLOEXEC, - 0, - ), + .linux => Handle{ + .fd = try os.open(dir_path, os.O_RDONLY | os.O_DIRECTORY | os.O_CLOEXEC, 0), .index = 0, .end_index = 0, .buf = []u8{}, @@ -486,27 +476,22 @@ pub const Dir = struct { } pub fn close(self: *Dir) void { - switch (builtin.os) { - Os.windows => { - _ = windows.FindClose(self.handle.handle); - }, - Os.macosx, Os.ios, Os.linux, Os.freebsd, Os.netbsd => { - self.allocator.free(self.handle.buf); - os.close(self.handle.fd); - }, - else => @compileError("unimplemented"), + if (os.windows.is_the_target) { + return os.windows.FindClose(self.handle.handle); } + self.allocator.free(self.handle.buf); + os.close(self.handle.fd); } /// Memory such as file names referenced in this returned entry becomes invalid /// with subsequent calls to next, as well as when this `Dir` is deinitialized. pub fn next(self: *Dir) !?Entry { switch (builtin.os) { - Os.linux => return self.nextLinux(), - Os.macosx, Os.ios => return self.nextDarwin(), - Os.windows => return self.nextWindows(), - Os.freebsd => return self.nextFreebsd(), - Os.netbsd => return self.nextFreebsd(), + .linux => return self.nextLinux(), + .macosx, .ios => return self.nextDarwin(), + .windows => return self.nextWindows(), + .freebsd => return self.nextBsd(), + .netbsd => return self.nextBsd(), else => @compileError("unimplemented"), } } @@ -519,18 +504,23 @@ pub const Dir = struct { } while (true) { - const result = system.__getdirentries64(self.handle.fd, self.handle.buf.ptr, self.handle.buf.len, &self.handle.seek); - if (result == 0) return null; - if (result < 0) { - switch (system.getErrno(result)) { - posix.EBADF => unreachable, - posix.EFAULT => unreachable, - posix.ENOTDIR => unreachable, - posix.EINVAL => { + const rc = os.system.__getdirentries64( + self.handle.fd, + self.handle.buf.ptr, + self.handle.buf.len, + &self.handle.seek, + ); + if (rc == 0) return null; + if (rc < 0) { + switch (os.errno(rc)) { + os.EBADF => unreachable, + os.EFAULT => unreachable, + os.ENOTDIR => unreachable, + os.EINVAL => { self.handle.buf = try self.allocator.realloc(self.handle.buf, self.handle.buf.len * 2); continue; }, - else => return unexpectedErrorPosix(err), + else => |err| return os.unexpectedErrno(err), } } self.handle.index = 0; @@ -538,7 +528,7 @@ pub const Dir = struct { break; } } - const darwin_entry = @ptrCast(*align(1) posix.dirent, &self.handle.buf[self.handle.index]); + const darwin_entry = @ptrCast(*align(1) os.dirent, &self.handle.buf[self.handle.index]); const next_index = self.handle.index + darwin_entry.d_reclen; self.handle.index = next_index; @@ -549,14 +539,14 @@ pub const Dir = struct { } const entry_kind = switch (darwin_entry.d_type) { - posix.DT_BLK => Entry.Kind.BlockDevice, - posix.DT_CHR => Entry.Kind.CharacterDevice, - posix.DT_DIR => Entry.Kind.Directory, - posix.DT_FIFO => Entry.Kind.NamedPipe, - posix.DT_LNK => Entry.Kind.SymLink, - posix.DT_REG => Entry.Kind.File, - posix.DT_SOCK => Entry.Kind.UnixDomainSocket, - posix.DT_WHT => Entry.Kind.Whiteout, + os.DT_BLK => Entry.Kind.BlockDevice, + os.DT_CHR => Entry.Kind.CharacterDevice, + os.DT_DIR => Entry.Kind.Directory, + os.DT_FIFO => Entry.Kind.NamedPipe, + os.DT_LNK => Entry.Kind.SymLink, + os.DT_REG => Entry.Kind.File, + os.DT_SOCK => Entry.Kind.UnixDomainSocket, + os.DT_WHT => Entry.Kind.Whiteout, else => Entry.Kind.Unknown, }; return Entry{ @@ -571,7 +561,7 @@ pub const Dir = struct { if (self.handle.first) { self.handle.first = false; } else { - if (!try posix.FindNextFile(self.handle.handle, &self.handle.find_file_data)) + if (!try os.windows.FindNextFile(self.handle.handle, &self.handle.find_file_data)) return null; } const name_utf16le = mem.toSlice(u16, self.handle.find_file_data.cFileName[0..].ptr); @@ -582,9 +572,9 @@ pub const Dir = struct { const name_utf8 = self.handle.name_data[0..name_utf8_len]; const kind = blk: { const attrs = self.handle.find_file_data.dwFileAttributes; - if (attrs & windows.FILE_ATTRIBUTE_DIRECTORY != 0) break :blk Entry.Kind.Directory; - if (attrs & windows.FILE_ATTRIBUTE_REPARSE_POINT != 0) break :blk Entry.Kind.SymLink; - if (attrs & windows.FILE_ATTRIBUTE_NORMAL != 0) break :blk Entry.Kind.File; + if (attrs & os.windows.FILE_ATTRIBUTE_DIRECTORY != 0) break :blk Entry.Kind.Directory; + if (attrs & os.windows.FILE_ATTRIBUTE_REPARSE_POINT != 0) break :blk Entry.Kind.SymLink; + if (attrs & os.windows.FILE_ATTRIBUTE_NORMAL != 0) break :blk Entry.Kind.File; break :blk Entry.Kind.Unknown; }; return Entry{ @@ -602,25 +592,25 @@ pub const Dir = struct { } while (true) { - const result = posix.getdents64(self.handle.fd, self.handle.buf.ptr, self.handle.buf.len); - const err = posix.getErrno(result); - if (err > 0) { - switch (err) { - posix.EBADF, posix.EFAULT, posix.ENOTDIR => unreachable, - posix.EINVAL => { - self.handle.buf = try self.allocator.realloc(self.handle.buf, self.handle.buf.len * 2); - continue; - }, - else => return unexpectedErrorPosix(err), - } + const rc = os.system.getdents64(self.handle.fd, self.handle.buf.ptr, self.handle.buf.len); + switch (os.errno(rc)) { + 0 => {}, + os.EBADF => unreachable, + os.EFAULT => unreachable, + os.ENOTDIR => unreachable, + os.EINVAL => { + self.handle.buf = try self.allocator.realloc(self.handle.buf, self.handle.buf.len * 2); + continue; + }, + else => |err| return os.unexpectedErrno(err), } - if (result == 0) return null; + if (rc == 0) return null; self.handle.index = 0; - self.handle.end_index = result; + self.handle.end_index = rc; break; } } - const linux_entry = @ptrCast(*align(1) posix.dirent64, &self.handle.buf[self.handle.index]); + const linux_entry = @ptrCast(*align(1) os.dirent64, &self.handle.buf[self.handle.index]); const next_index = self.handle.index + linux_entry.d_reclen; self.handle.index = next_index; @@ -632,13 +622,13 @@ pub const Dir = struct { } const entry_kind = switch (linux_entry.d_type) { - posix.DT_BLK => Entry.Kind.BlockDevice, - posix.DT_CHR => Entry.Kind.CharacterDevice, - posix.DT_DIR => Entry.Kind.Directory, - posix.DT_FIFO => Entry.Kind.NamedPipe, - posix.DT_LNK => Entry.Kind.SymLink, - posix.DT_REG => Entry.Kind.File, - posix.DT_SOCK => Entry.Kind.UnixDomainSocket, + os.DT_BLK => Entry.Kind.BlockDevice, + os.DT_CHR => Entry.Kind.CharacterDevice, + os.DT_DIR => Entry.Kind.Directory, + os.DT_FIFO => Entry.Kind.NamedPipe, + os.DT_LNK => Entry.Kind.SymLink, + os.DT_REG => Entry.Kind.File, + os.DT_SOCK => Entry.Kind.UnixDomainSocket, else => Entry.Kind.Unknown, }; return Entry{ @@ -648,7 +638,7 @@ pub const Dir = struct { } } - fn nextFreebsd(self: *Dir) !?Entry { + fn nextBsd(self: *Dir) !?Entry { start_over: while (true) { if (self.handle.index >= self.handle.end_index) { if (self.handle.buf.len == 0) { @@ -656,25 +646,30 @@ pub const Dir = struct { } while (true) { - const result = posix.getdirentries(self.handle.fd, self.handle.buf.ptr, self.handle.buf.len, &self.handle.seek); - const err = posix.getErrno(result); - if (err > 0) { - switch (err) { - posix.EBADF, posix.EFAULT, posix.ENOTDIR => unreachable, - posix.EINVAL => { - self.handle.buf = try self.allocator.realloc(self.handle.buf, self.handle.buf.len * 2); - continue; - }, - else => return unexpectedErrorPosix(err), - } + const rc = os.system.getdirentries( + self.handle.fd, + self.handle.buf.ptr, + self.handle.buf.len, + &self.handle.seek, + ); + switch (os.errno(rc)) { + 0 => {}, + os.EBADF => unreachable, + os.EFAULT => unreachable, + os.ENOTDIR => unreachable, + os.EINVAL => { + self.handle.buf = try self.allocator.realloc(self.handle.buf, self.handle.buf.len * 2); + continue; + }, + else => |err| return os.unexpectedErrno(err), } - if (result == 0) return null; + if (rc == 0) return null; self.handle.index = 0; - self.handle.end_index = result; + self.handle.end_index = @intCast(usize, rc); break; } } - const freebsd_entry = @ptrCast(*align(1) posix.dirent, &self.handle.buf[self.handle.index]); + const freebsd_entry = @ptrCast(*align(1) os.dirent, &self.handle.buf[self.handle.index]); const next_index = self.handle.index + freebsd_entry.d_reclen; self.handle.index = next_index; @@ -685,14 +680,14 @@ pub const Dir = struct { } const entry_kind = switch (freebsd_entry.d_type) { - posix.DT_BLK => Entry.Kind.BlockDevice, - posix.DT_CHR => Entry.Kind.CharacterDevice, - posix.DT_DIR => Entry.Kind.Directory, - posix.DT_FIFO => Entry.Kind.NamedPipe, - posix.DT_LNK => Entry.Kind.SymLink, - posix.DT_REG => Entry.Kind.File, - posix.DT_SOCK => Entry.Kind.UnixDomainSocket, - posix.DT_WHT => Entry.Kind.Whiteout, + os.DT_BLK => Entry.Kind.BlockDevice, + os.DT_CHR => Entry.Kind.CharacterDevice, + os.DT_DIR => Entry.Kind.Directory, + os.DT_FIFO => Entry.Kind.NamedPipe, + os.DT_LNK => Entry.Kind.SymLink, + os.DT_REG => Entry.Kind.File, + os.DT_SOCK => Entry.Kind.UnixDomainSocket, + os.DT_WHT => Entry.Kind.Whiteout, else => Entry.Kind.Unknown, }; return Entry{ @@ -705,52 +700,40 @@ pub const Dir = struct { /// Read value of a symbolic link. /// The return value is a slice of buffer, from index `0`. -pub fn readLink(buffer: *[posix.PATH_MAX]u8, pathname: []const u8) ![]u8 { - return posix.readlink(pathname, buffer); +pub fn readLink(pathname: []const u8, buffer: *[os.PATH_MAX]u8) ![]u8 { + return os.readlink(pathname, buffer); } /// Same as `readLink`, except the `pathname` parameter is null-terminated. -pub fn readLinkC(buffer: *[posix.PATH_MAX]u8, pathname: [*]const u8) ![]u8 { - return posix.readlinkC(pathname, buffer); +pub fn readLinkC(pathname: [*]const u8, buffer: *[os.PATH_MAX]u8) ![]u8 { + return os.readlinkC(pathname, buffer); } -pub fn openSelfExe() !os.File { - switch (builtin.os) { - Os.linux => return os.File.openReadC(c"/proc/self/exe"), - Os.macosx, Os.ios, Os.freebsd, Os.netbsd => { - var buf: [MAX_PATH_BYTES]u8 = undefined; - const self_exe_path = try selfExePath(&buf); - buf[self_exe_path.len] = 0; - return os.File.openReadC(self_exe_path.ptr); - }, - Os.windows => { - var buf: [posix.PATH_MAX_WIDE]u16 = undefined; - const wide_slice = try selfExePathW(&buf); - return os.File.openReadW(wide_slice.ptr); - }, - else => @compileError("Unsupported OS"), +pub const OpenSelfExeError = error{}; + +pub fn openSelfExe() OpenSelfExeError!File { + if (os.linux.is_the_target) { + return File.openReadC(c"/proc/self/exe"); + } + if (os.windows.is_the_target) { + var buf: [os.windows.PATH_MAX_WIDE]u16 = undefined; + const wide_slice = try selfExePathW(&buf); + return File.openReadW(wide_slice.ptr); } + var buf: [MAX_PATH_BYTES]u8 = undefined; + const self_exe_path = try selfExePath(&buf); + buf[self_exe_path.len] = 0; + return File.openReadC(self_exe_path.ptr); } test "openSelfExe" { switch (builtin.os) { - Os.linux, Os.macosx, Os.ios, Os.windows, Os.freebsd => (try openSelfExe()).close(), + .linux, .macosx, .ios, .windows, .freebsd => (try openSelfExe()).close(), else => return error.SkipZigTest, // Unsupported OS. } } -pub fn selfExePathW(out_buffer: *[posix.PATH_MAX_WIDE]u16) ![]u16 { - const casted_len = @intCast(windows.DWORD, out_buffer.len); // TODO shouldn't need this cast - const rc = windows.GetModuleFileNameW(null, out_buffer, casted_len); - assert(rc <= out_buffer.len); - if (rc == 0) { - const err = windows.GetLastError(); - switch (err) { - else => return windows.unexpectedError(err), - } - } - return out_buffer[0..rc]; -} +pub const SelfExePathError = os.ReadLinkError || os.SysCtlError; /// Get the path to the current executable. /// If you only need the directory, use selfExeDirPath. @@ -763,39 +746,44 @@ pub fn selfExePathW(out_buffer: *[posix.PATH_MAX_WIDE]u16) ![]u16 { /// been deleted, the file path looks something like `/a/b/c/exe (deleted)`. /// TODO make the return type of this a null terminated pointer pub fn selfExePath(out_buffer: *[MAX_PATH_BYTES]u8) ![]u8 { + if (os.darwin.is_the_target) { + var u32_len: u32 = out_buffer.len; + const rc = c._NSGetExecutablePath(out_buffer, &u32_len); + if (rc != 0) return error.NameTooLong; + return mem.toSlice(u8, out_buffer); + } switch (builtin.os) { - Os.linux => return readLink(out_buffer, "/proc/self/exe"), - Os.freebsd => { - var mib = [4]c_int{ posix.CTL_KERN, posix.KERN_PROC, posix.KERN_PROC_PATHNAME, -1 }; + .linux => return os.readlinkC(c"/proc/self/exe", out_buffer), + .freebsd => { + var mib = [4]c_int{ os.CTL_KERN, os.KERN_PROC, os.KERN_PROC_PATHNAME, -1 }; var out_len: usize = out_buffer.len; - try posix.sysctl(&mib, out_buffer, &out_len, null, 0); + try os.sysctl(&mib, out_buffer, &out_len, null, 0); // TODO could this slice from 0 to out_len instead? return mem.toSlice(u8, out_buffer); }, - Os.netbsd => { - var mib = [4]c_int{ posix.CTL_KERN, posix.KERN_PROC_ARGS, -1, posix.KERN_PROC_PATHNAME }; + .netbsd => { + var mib = [4]c_int{ os.CTL_KERN, os.KERN_PROC_ARGS, -1, os.KERN_PROC_PATHNAME }; var out_len: usize = out_buffer.len; - try posix.sysctl(&mib, out_buffer, &out_len, null, 0); + try os.sysctl(&mib, out_buffer, &out_len, null, 0); // TODO could this slice from 0 to out_len instead? return mem.toSlice(u8, out_buffer); }, - Os.windows => { - var utf16le_buf: [posix.PATH_MAX_WIDE]u16 = undefined; + .windows => { + var utf16le_buf: [os.windows.PATH_MAX_WIDE]u16 = undefined; const utf16le_slice = try selfExePathW(&utf16le_buf); // Trust that Windows gives us valid UTF-16LE. const end_index = std.unicode.utf16leToUtf8(out_buffer, utf16le_slice) catch unreachable; return out_buffer[0..end_index]; }, - Os.macosx, Os.ios => { - var u32_len: u32 = @intCast(u32, out_buffer.len); // TODO shouldn't need this cast - const rc = c._NSGetExecutablePath(out_buffer, &u32_len); - if (rc != 0) return error.NameTooLong; - return mem.toSlice(u8, out_buffer); - }, - else => @compileError("Unsupported OS"), + else => @compileError("std.fs.selfExePath not supported for this target"), } } +/// Same as `selfExePath` except the result is UTF16LE-encoded. +pub fn selfExePathW(out_buffer: *[os.windows.PATH_MAX_WIDE]u16) ![]u16 { + return os.windows.GetModuleFileNameW(null, out_buffer, out_buffer.len); +} + /// `selfExeDirPath` except allocates the result on the heap. /// Caller owns returned memory. pub fn selfExeDirPathAlloc(allocator: *Allocator) ![]u8 { @@ -806,31 +794,26 @@ pub fn selfExeDirPathAlloc(allocator: *Allocator) ![]u8 { /// Get the directory path that contains the current executable. /// Returned value is a slice of out_buffer. pub fn selfExeDirPath(out_buffer: *[MAX_PATH_BYTES]u8) ![]const u8 { - switch (builtin.os) { - Os.linux => { - // If the currently executing binary has been deleted, - // the file path looks something like `/a/b/c/exe (deleted)` - // This path cannot be opened, but it's valid for determining the directory - // the executable was in when it was run. - const full_exe_path = try readLinkC(out_buffer, c"/proc/self/exe"); - // Assume that /proc/self/exe has an absolute path, and therefore dirname - // will not return null. - return path.dirname(full_exe_path).?; - }, - Os.windows, Os.macosx, Os.ios, Os.freebsd, Os.netbsd => { - const self_exe_path = try selfExePath(out_buffer); - // Assume that the OS APIs return absolute paths, and therefore dirname - // will not return null. - return path.dirname(self_exe_path).?; - }, - else => @compileError("Unsupported OS"), + if (os.linux.is_the_target) { + // If the currently executing binary has been deleted, + // the file path looks something like `/a/b/c/exe (deleted)` + // This path cannot be opened, but it's valid for determining the directory + // the executable was in when it was run. + const full_exe_path = try os.readlinkC(c"/proc/self/exe", out_buffer); + // Assume that /proc/self/exe has an absolute path, and therefore dirname + // will not return null. + return path.dirname(full_exe_path).?; } + const self_exe_path = try selfExePath(out_buffer); + // Assume that the OS APIs return absolute paths, and therefore dirname + // will not return null. + return path.dirname(self_exe_path).?; } /// `realpath`, except caller must free the returned memory. -pub fn realAlloc(allocator: *Allocator, pathname: []const u8) ![]u8 { +pub fn realpathAlloc(allocator: *Allocator, pathname: []const u8) ![]u8 { var buf: [MAX_PATH_BYTES]u8 = undefined; - return mem.dupe(allocator, u8, try realpath(pathname, &buf)); + return mem.dupe(allocator, u8, try os.realpath(pathname, &buf)); } test "" { diff --git a/std/io.zig b/std/io.zig index 657352e295..5ca011cb4c 100644 --- a/std/io.zig +++ b/std/io.zig @@ -12,7 +12,7 @@ const meta = std.meta; const trait = meta.trait; const Buffer = std.Buffer; const fmt = std.fmt; -const File = std.os.File; +const File = std.fs.File; const testing = std.testing; const is_posix = builtin.os != builtin.Os.windows; @@ -963,8 +963,8 @@ pub fn BitOutStream(endian: builtin.Endian, comptime Error: type) type { pub const BufferedAtomicFile = struct { atomic_file: os.AtomicFile, - file_stream: os.File.OutStream, - buffered_stream: BufferedOutStream(os.File.WriteError), + file_stream: File.OutStream, + buffered_stream: BufferedOutStream(File.WriteError), allocator: *mem.Allocator, pub fn create(allocator: *mem.Allocator, dest_path: []const u8) !*BufferedAtomicFile { @@ -978,11 +978,11 @@ pub const BufferedAtomicFile = struct { }; errdefer allocator.destroy(self); - self.atomic_file = try os.AtomicFile.init(dest_path, os.File.default_mode); + self.atomic_file = try os.AtomicFile.init(dest_path, File.default_mode); errdefer self.atomic_file.deinit(); self.file_stream = self.atomic_file.file.outStream(); - self.buffered_stream = BufferedOutStream(os.File.WriteError).init(&self.file_stream.stream); + self.buffered_stream = BufferedOutStream(File.WriteError).init(&self.file_stream.stream); return self; } @@ -997,7 +997,7 @@ pub const BufferedAtomicFile = struct { try self.atomic_file.finish(); } - pub fn stream(self: *BufferedAtomicFile) *OutStream(os.File.WriteError) { + pub fn stream(self: *BufferedAtomicFile) *OutStream(File.WriteError) { return &self.buffered_stream.stream; } }; diff --git a/std/io/c_out_stream.zig b/std/io/c_out_stream.zig index c66b342f1e..cbc5254382 100644 --- a/std/io/c_out_stream.zig +++ b/std/io/c_out_stream.zig @@ -1,13 +1,13 @@ const std = @import("../std.zig"); +const os = std.os; const OutStream = std.io.OutStream; const builtin = @import("builtin"); -const posix = std.os.posix; -/// TODO make std.os.FILE use *FILE when linking libc and this just becomes -/// std.io.FileOutStream because std.os.File.write would do this when linking +/// TODO make a proposal to make `std.fs.File` use *FILE when linking libc and this just becomes +/// std.io.FileOutStream because std.fs.File.write would do this when linking /// libc. pub const COutStream = struct { - pub const Error = std.os.File.WriteError; + pub const Error = std.fs.File.WriteError; pub const Stream = OutStream(Error); stream: Stream, @@ -24,25 +24,20 @@ pub const COutStream = struct { const self = @fieldParentPtr(COutStream, "stream", out_stream); const amt_written = std.c.fwrite(bytes.ptr, 1, bytes.len, self.c_file); if (amt_written == bytes.len) return; - // TODO errno on windows. should we have a posix layer for windows? - if (builtin.os == .windows) { - return error.InputOutput; - } - const errno = std.c._errno().*; - switch (errno) { + switch (std.c._errno().*) { 0 => unreachable, - posix.EINVAL => unreachable, - posix.EFAULT => unreachable, - posix.EAGAIN => unreachable, // this is a blocking API - posix.EBADF => unreachable, // always a race condition - posix.EDESTADDRREQ => unreachable, // connect was never called - posix.EDQUOT => return error.DiskQuota, - posix.EFBIG => return error.FileTooBig, - posix.EIO => return error.InputOutput, - posix.ENOSPC => return error.NoSpaceLeft, - posix.EPERM => return error.AccessDenied, - posix.EPIPE => return error.BrokenPipe, - else => return std.os.unexpectedErrorPosix(@intCast(usize, errno)), + os.EINVAL => unreachable, + os.EFAULT => unreachable, + os.EAGAIN => unreachable, // this is a blocking API + os.EBADF => unreachable, // always a race condition + os.EDESTADDRREQ => unreachable, // connect was never called + os.EDQUOT => return error.DiskQuota, + os.EFBIG => return error.FileTooBig, + os.EIO => return error.InputOutput, + os.ENOSPC => return error.NoSpaceLeft, + os.EPERM => return error.AccessDenied, + os.EPIPE => return error.BrokenPipe, + else => return os.unexpectedErrno(@intCast(usize, errno)), } } }; diff --git a/std/io/test.zig b/std/io/test.zig index 07a3c0e8dd..7928baa597 100644 --- a/std/io/test.zig +++ b/std/io/test.zig @@ -1,3 +1,4 @@ +const builtin = @import("builtin"); const std = @import("../std.zig"); const io = std.io; const meta = std.meta; @@ -7,7 +8,7 @@ const expect = std.testing.expect; const expectError = std.testing.expectError; const mem = std.mem; const os = std.os; -const builtin = @import("builtin"); +const File = std.fs.File; test "write a file, read it, then delete it" { var raw_bytes: [200 * 1024]u8 = undefined; @@ -18,11 +19,11 @@ test "write a file, read it, then delete it" { prng.random.bytes(data[0..]); const tmp_file_name = "temp_test_file.txt"; { - var file = try os.File.openWrite(tmp_file_name); + var file = try File.openWrite(tmp_file_name); defer file.close(); var file_out_stream = file.outStream(); - var buf_stream = io.BufferedOutStream(os.File.WriteError).init(&file_out_stream.stream); + var buf_stream = io.BufferedOutStream(File.WriteError).init(&file_out_stream.stream); const st = &buf_stream.stream; try st.print("begin"); try st.write(data[0..]); @@ -32,15 +33,15 @@ test "write a file, read it, then delete it" { { // make sure openWriteNoClobber doesn't harm the file - if (os.File.openWriteNoClobber(tmp_file_name, os.File.default_mode)) |file| { + if (File.openWriteNoClobber(tmp_file_name, File.default_mode)) |file| { unreachable; } else |err| { - std.debug.assert(err == os.File.OpenError.PathAlreadyExists); + std.debug.assert(err == File.OpenError.PathAlreadyExists); } } { - var file = try os.File.openRead(tmp_file_name); + var file = try File.openRead(tmp_file_name); defer file.close(); const file_size = try file.getEndPos(); @@ -48,7 +49,7 @@ test "write a file, read it, then delete it" { expect(file_size == expected_file_size); var file_in_stream = file.inStream(); - var buf_stream = io.BufferedInStream(os.File.ReadError).init(&file_in_stream.stream); + var buf_stream = io.BufferedInStream(File.ReadError).init(&file_in_stream.stream); const st = &buf_stream.stream; const contents = try st.readAllAlloc(allocator, 2 * 1024); defer allocator.free(contents); @@ -273,12 +274,12 @@ test "BitOutStream" { test "BitStreams with File Stream" { const tmp_file_name = "temp_test_file.txt"; { - var file = try os.File.openWrite(tmp_file_name); + var file = try File.openWrite(tmp_file_name); defer file.close(); var file_out = file.outStream(); var file_out_stream = &file_out.stream; - const OutError = os.File.WriteError; + const OutError = File.WriteError; var bit_stream = io.BitOutStream(builtin.endian, OutError).init(file_out_stream); try bit_stream.writeBits(u2(1), 1); @@ -290,12 +291,12 @@ test "BitStreams with File Stream" { try bit_stream.flushBits(); } { - var file = try os.File.openRead(tmp_file_name); + var file = try File.openRead(tmp_file_name); defer file.close(); var file_in = file.inStream(); var file_in_stream = &file_in.stream; - const InError = os.File.ReadError; + const InError = File.ReadError; var bit_stream = io.BitInStream(builtin.endian, InError).init(file_in_stream); var out_bits: usize = undefined; diff --git a/std/os.zig b/std/os.zig index 5f6716e017..4cd847cf8f 100644 --- a/std/os.zig +++ b/std/os.zig @@ -16,6 +16,7 @@ const std = @import("std.zig"); const builtin = @import("builtin"); +const math = std.math; const MAX_PATH_BYTES = std.fs.MAX_PATH_BYTES; comptime { @@ -114,7 +115,7 @@ fn getRandomBytesDevURandom(buf: []u8) !void { const fd = try openC(c"/dev/urandom", O_RDONLY | O_CLOEXEC, 0); defer close(fd); - const stream = &os.File.openHandle(fd).inStream().stream; + const stream = &std.fs.File.openHandle(fd).inStream().stream; stream.readNoEof(buf) catch return error.Unexpected; } @@ -177,6 +178,21 @@ pub fn raise(sig: u8) RaiseError!void { } } +pub const KillError = error{ + PermissionDenied, + Unexpected, +}; + +pub fn kill(pid: pid_t, sig: u8) KillError!void { + switch (errno(system.kill(pid, sig))) { + 0 => return, + EINVAL => unreachable, // invalid signal + EPERM => return error.PermissionDenied, + ESRCH => unreachable, // always a race condition + else => |err| return unexpectedErrno(err), + } +} + /// Exits the program cleanly with the specified status code. pub fn exit(status: u8) noreturn { if (builtin.link_libc) { @@ -885,8 +901,7 @@ pub fn rename(old_path: []const u8, new_path: []const u8) RenameError!void { if (windows.is_the_target and !builtin.link_libc) { const old_path_w = try windows.sliceToPrefixedFileW(old_path); const new_path_w = try windows.sliceToPrefixedFileW(new_path); - const flags = windows.MOVEFILE_REPLACE_EXISTING | windows.MOVEFILE_WRITE_THROUGH; - return windows.MoveFileExW(&old_path_w, &new_path_w, flags); + return renameW(&old_path_w, &new_path_w); } else { const old_path_c = try toPosixPath(old_path); const new_path_c = try toPosixPath(new_path); @@ -899,8 +914,7 @@ pub fn renameC(old_path: [*]const u8, new_path: [*]const u8) RenameError!void { if (windows.is_the_target and !builtin.link_libc) { const old_path_w = try windows.cStrToPrefixedFileW(old_path); const new_path_w = try windows.cStrToPrefixedFileW(new_path); - const flags = windows.MOVEFILE_REPLACE_EXISTING | windows.MOVEFILE_WRITE_THROUGH; - return windows.MoveFileExW(&old_path_w, &new_path_w, flags); + return renameW(&old_path_w, &new_path_w); } switch (errno(system.rename(old_path, new_path))) { 0 => return, @@ -926,6 +940,13 @@ pub fn renameC(old_path: [*]const u8, new_path: [*]const u8) RenameError!void { } } +/// Same as `rename` except the parameters are null-terminated UTF16LE encoded byte arrays. +/// Assumes target is Windows. +pub fn renameW(old_path: [*]const u16, new_path: [*]const u16) RenameError!void { + const flags = windows.MOVEFILE_REPLACE_EXISTING | windows.MOVEFILE_WRITE_THROUGH; + return windows.MoveFileExW(old_path_w, new_path_w, flags); +} + pub const MakeDirError = error{ AccessDenied, DiskQuota, @@ -1684,10 +1705,10 @@ pub fn getsockoptError(sockfd: i32) ConnectError!void { } } -pub fn waitpid(pid: i32) i32 { +pub fn waitpid(pid: i32, flags: u32) i32 { var status: i32 = undefined; while (true) { - switch (errno(system.waitpid(pid, &status, 0))) { + switch (errno(system.waitpid(pid, &status, flags))) { 0 => return status, EINTR => continue, ECHILD => unreachable, // The process specified does not exist. It would be a race condition to handle this error. @@ -1988,9 +2009,10 @@ pub const PipeError = error{ }; /// Creates a unidirectional data channel that can be used for interprocess communication. -pub fn pipe(fds: *[2]fd_t) PipeError!void { - switch (errno(system.pipe(fds))) { - 0 => return, +pub fn pipe() PipeError![2]fd_t { + var fds: [2]i32 = undefined; + switch (errno(system.pipe(&fds))) { + 0 => return fds, EINVAL => unreachable, // Invalid parameters to pipe() EFAULT => unreachable, // Invalid fds pointer ENFILE => return error.SystemFdQuotaExceeded, @@ -1999,9 +2021,10 @@ pub fn pipe(fds: *[2]fd_t) PipeError!void { } } -pub fn pipe2(fds: *[2]fd_t, flags: u32) PipeError!void { - switch (errno(system.pipe2(fds, flags))) { - 0 => return, +pub fn pipe2(flags: u32) PipeError![2]fd_t { + var fds: [2]i32 = undefined; + switch (errno(system.pipe2(&fds, flags))) { + 0 => return fds, EINVAL => unreachable, // Invalid flags EFAULT => unreachable, // Invalid fds pointer ENFILE => return error.SystemFdQuotaExceeded, @@ -2281,6 +2304,67 @@ pub fn realpathW(pathname: [*]const u16, out_buffer: *[MAX_PATH_BYTES]u8) RealPa return out_buffer[0..end_index]; } +/// Spurious wakeups are possible and no precision of timing is guaranteed. +pub fn nanosleep(seconds: u64, nanoseconds: u64) void { + if (windows.is_the_target and !builtin.link_libc) { + // TODO https://github.com/ziglang/zig/issues/1284 + const small_s = math.cast(windows.DWORD, seconds) catch math.maxInt(windows.DWORD); + const ms_from_s = math.mul(small_s, std.time.ms_per_s) catch math.maxInt(windows.DWORD); + + const ns_per_ms = std.time.ns_per_s / std.time.ms_per_s; + const big_ms_from_ns = nanoseconds / ns_per_ms; + const ms_from_ns = math.cast(windows.DWORD, big_ms_from_ns) catch math.maxInt(windows.DWORD); + + const ms = math.add(ms_from_s, ms_from_ns) catch math.maxInt(windows.DWORD); + windows.kernel32.Sleep(ms); + return; + } + var req = timespec{ + .tv_sec = math.cast(isize, seconds) catch math.maxInt(isize), + .tv_nsec = math.cast(isize, nanoseconds) catch math.maxInt(isize), + }; + var rem: timespec = undefined; + while (true) { + switch (errno(system.nanosleep(&req, &rem))) { + EFAULT => unreachable, + EINVAL => { + // Sometimes Darwin returns EINVAL for no reason. + // We treat it as a spurious wakeup. + return; + }, + EINTR => { + req = rem; + continue; + }, + // This prong handles success as well as unexpected errors. + else => return, + } + } +} + +pub const ClockGetTimeError = error{ + UnsupportedClock, + Unexpected, +}; + +pub fn clock_gettime(clk_id: i32, tp: *timespec) ClockGetTimeError!void { + switch (errno(system.clock_gettime(clk_id, tp))) { + 0 => return, + EFAULT => unreachable, + EINVAL => return error.UnsupportedClock, + else => |err| return unexpectedErrno(err), + } +} + +pub fn clock_getres(clk_id: i32, res: *timespec) ClockGetTimeError!void { + switch (errno(system.clock_getres(clk_id, tp))) { + 0 => return, + EFAULT => unreachable, + EINVAL => return error.UnsupportedClock, + else => |err| return unexpectedErrno(err), + } +} + /// Used to convert a slice to a null terminated slice on the stack. /// TODO https://github.com/ziglang/zig/issues/287 pub fn toPosixPath(file_path: []const u8) ![PATH_MAX]u8 { diff --git a/std/os/bits/linux.zig b/std/os/bits/linux.zig index 40b554b27f..7957187896 100644 --- a/std/os/bits/linux.zig +++ b/std/os/bits/linux.zig @@ -1,4 +1,4 @@ -pub use @import("errno.zig"); +pub use @import("linux/errno.zig"); pub use switch (builtin.arch) { .x86_64 => @import("linux/x86_64.zig"), .aarch64 => @import("linux/arm64.zig"), @@ -744,16 +744,6 @@ pub const sockaddr_un = extern struct { path: [108]u8, }; -pub const iovec = extern struct { - iov_base: [*]u8, - iov_len: usize, -}; - -pub const iovec_const = extern struct { - iov_base: [*]const u8, - iov_len: usize, -}; - pub const mmsghdr = extern struct { msg_hdr: msghdr, msg_len: u32, diff --git a/std/os/test.zig b/std/os/test.zig index 35824001a5..54371e94ab 100644 --- a/std/os/test.zig +++ b/std/os/test.zig @@ -4,6 +4,7 @@ const testing = std.testing; const expect = std.testing.expect; const io = std.io; const mem = std.mem; +const File = std.fs.File; const a = std.debug.global_allocator; @@ -25,14 +26,14 @@ test "makePath, put some files in it, deleteTree" { test "access file" { try os.makePath(a, "os_test_tmp"); - if (os.File.access("os_test_tmp" ++ os.path.sep_str ++ "file.txt")) |ok| { + if (File.access("os_test_tmp" ++ os.path.sep_str ++ "file.txt")) |ok| { @panic("expected error"); } else |err| { expect(err == error.FileNotFound); } try io.writeFile("os_test_tmp" ++ os.path.sep_str ++ "file.txt", ""); - try os.File.access("os_test_tmp" ++ os.path.sep_str ++ "file.txt"); + try File.access("os_test_tmp" ++ os.path.sep_str ++ "file.txt"); try os.deleteTree(a, "os_test_tmp"); } @@ -102,7 +103,7 @@ test "AtomicFile" { \\ this is a test file ; { - var af = try os.AtomicFile.init(test_out_file, os.File.default_mode); + var af = try os.AtomicFile.init(test_out_file, File.default_mode); defer af.deinit(); try af.file.write(test_content); try af.finish(); diff --git a/std/os/windows.zig b/std/os/windows.zig index 70772ee807..e35d8bbbd2 100644 --- a/std/os/windows.zig +++ b/std/os/windows.zig @@ -753,6 +753,10 @@ pub fn CloseHandle(hObject: HANDLE) void { assert(kernel32.CloseHandle(hObject) != 0); } +pub fn FindClose(hFindFile: HANDLE) void { + assert(kernel32.FindClose(hFindFile) != 0); +} + pub const ReadFileError = error{Unexpected}; pub fn ReadFile(in_hFile: HANDLE, buffer: []u8) ReadFileError!usize { @@ -1063,6 +1067,28 @@ pub fn GetFileAttributesW(lpFileName: [*]const u16) GetFileAttributesError!DWORD return rc; } +const GetModuleFileNameError = error{Unexpected}; + +pub fn GetModuleFileNameW(hModule: ?HMODULE, buf_ptr: [*]u16, buf_len: DWORD) GetModuleFileNameError![]u16 { + const rc = kernel32.GetModuleFileNameW(hModule, buf_ptr, buf_len); + if (rc == 0) { + switch (kernel32.GetLastError()) { + else => |err| return unexpectedError(err), + } + } + return buf_ptr[0..rc]; +} + +pub const TerminateProcessError = error{Unexpected}; + +pub fn TerminateProcess(hProcess: HANDLE, uExitCode: UINT) TerminateProcessError!void { + if (kernel32.TerminateProcess(hProcess, uExitCode) == 0) { + switch (kernel32.GetLastError()) { + else => |err| return unexpectedError(err), + } + } +} + pub fn cStrToPrefixedFileW(s: [*]const u8) ![PATH_MAX_WIDE + 1]u16 { return sliceToPrefixedFileW(mem.toSliceConst(u8, s)); } diff --git a/std/pdb.zig b/std/pdb.zig index 0f3a6d00b5..2822d2546e 100644 --- a/std/pdb.zig +++ b/std/pdb.zig @@ -6,6 +6,7 @@ const mem = std.mem; const os = std.os; const warn = std.debug.warn; const coff = std.coff; +const File = std.fs.File; const ArrayList = std.ArrayList; @@ -459,7 +460,7 @@ pub const PDBStringTableHeader = packed struct { }; pub const Pdb = struct { - in_file: os.File, + in_file: File, allocator: *mem.Allocator, coff: *coff.Coff, string_table: *MsfStream, @@ -468,7 +469,7 @@ pub const Pdb = struct { msf: Msf, pub fn openFile(self: *Pdb, coff_ptr: *coff.Coff, file_name: []u8) !void { - self.in_file = try os.File.openRead(file_name); + self.in_file = try File.openRead(file_name); self.allocator = coff_ptr.allocator; self.coff = coff_ptr; @@ -492,7 +493,7 @@ const Msf = struct { directory: MsfStream, streams: []MsfStream, - fn openFile(self: *Msf, allocator: *mem.Allocator, file: os.File) !void { + fn openFile(self: *Msf, allocator: *mem.Allocator, file: File) !void { var file_stream = file.inStream(); const in = &file_stream.stream; @@ -587,7 +588,7 @@ const SuperBlock = packed struct { }; const MsfStream = struct { - in_file: os.File, + in_file: File, pos: u64, blocks: []u32, block_size: u32, @@ -598,7 +599,7 @@ const MsfStream = struct { pub const Error = @typeOf(read).ReturnType.ErrorSet; pub const Stream = io.InStream(Error); - fn init(block_size: u32, block_count: u32, pos: u64, file: os.File, allocator: *mem.Allocator) !MsfStream { + fn init(block_size: u32, block_count: u32, pos: u64, file: File, allocator: *mem.Allocator) !MsfStream { var stream = MsfStream{ .in_file = file, .pos = 0, diff --git a/std/special/build_runner.zig b/std/special/build_runner.zig index dfc3838577..f9a322cbeb 100644 --- a/std/special/build_runner.zig +++ b/std/special/build_runner.zig @@ -8,6 +8,7 @@ const Builder = std.build.Builder; const mem = std.mem; const ArrayList = std.ArrayList; const warn = std.debug.warn; +const File = std.fs.File; pub fn main() !void { var arg_it = os.args(); @@ -48,14 +49,14 @@ pub fn main() !void { var prefix: ?[]const u8 = null; var stderr_file = io.getStdErr(); - var stderr_file_stream: os.File.OutStream = undefined; + var stderr_file_stream: File.OutStream = undefined; var stderr_stream = if (stderr_file) |f| x: { stderr_file_stream = f.outStream(); break :x &stderr_file_stream.stream; } else |err| err; var stdout_file = io.getStdOut(); - var stdout_file_stream: os.File.OutStream = undefined; + var stdout_file_stream: File.OutStream = undefined; var stdout_stream = if (stdout_file) |f| x: { stdout_file_stream = f.outStream(); break :x &stdout_file_stream.stream; diff --git a/std/time.zig b/std/time.zig index abb6412843..1483a0a132 100644 --- a/std/time.zig +++ b/std/time.zig @@ -1,116 +1,61 @@ -const std = @import("../std.zig"); const builtin = @import("builtin"); -const Os = builtin.Os; -const debug = std.debug; +const std = @import("std.zig"); +const assert = std.debug.assert; const testing = std.testing; -const math = std.math; - -const windows = std.os.windows; -const linux = std.os.linux; -const darwin = std.os.darwin; -const wasi = std.os.wasi; -const posix = std.os.posix; +const os = std.os; pub const epoch = @import("epoch.zig"); /// Spurious wakeups are possible and no precision of timing is guaranteed. pub fn sleep(nanoseconds: u64) void { - switch (builtin.os) { - Os.linux, Os.macosx, Os.ios, Os.freebsd, Os.netbsd => { - const s = nanoseconds / ns_per_s; - const ns = nanoseconds % ns_per_s; - posixSleep(s, ns); - }, - Os.windows => { - const ns_per_ms = ns_per_s / ms_per_s; - const milliseconds = nanoseconds / ns_per_ms; - const ms_that_will_fit = std.math.cast(windows.DWORD, milliseconds) catch std.math.maxInt(windows.DWORD); - windows.Sleep(ms_that_will_fit); - }, - else => @compileError("Unsupported OS"), - } -} - -/// Spurious wakeups are possible and no precision of timing is guaranteed. -pub fn posixSleep(seconds: u64, nanoseconds: u64) void { - var req = posix.timespec{ - .tv_sec = std.math.cast(isize, seconds) catch std.math.maxInt(isize), - .tv_nsec = std.math.cast(isize, nanoseconds) catch std.math.maxInt(isize), - }; - var rem: posix.timespec = undefined; - while (true) { - const ret_val = posix.nanosleep(&req, &rem); - const err = posix.getErrno(ret_val); - switch (err) { - posix.EFAULT => unreachable, - posix.EINVAL => { - // Sometimes Darwin returns EINVAL for no reason. - // We treat it as a spurious wakeup. - return; - }, - posix.EINTR => { - req = rem; - continue; - }, - // This prong handles success as well as unexpected errors. - else => return, - } - } + const s = nanoseconds / ns_per_s; + const ns = nanoseconds % ns_per_s; + std.os.nanosleep(s, ns); } /// Get the posix timestamp, UTC, in seconds +/// TODO audit this function. is it possible to return an error? pub fn timestamp() u64 { return @divFloor(milliTimestamp(), ms_per_s); } /// Get the posix timestamp, UTC, in milliseconds -pub const milliTimestamp = switch (builtin.os) { - Os.windows => milliTimestampWindows, - Os.linux, Os.freebsd, Os.netbsd => milliTimestampPosix, - Os.macosx, Os.ios => milliTimestampDarwin, - Os.wasi => milliTimestampWasi, - else => @compileError("Unsupported OS"), -}; - -fn milliTimestampWasi() u64 { - var ns: wasi.timestamp_t = undefined; - - // TODO: Verify that precision is ignored - const err = wasi.clock_time_get(wasi.CLOCK_REALTIME, 1, &ns); - debug.assert(err == wasi.ESUCCESS); - - const ns_per_ms = 1000; - return @divFloor(ns, ns_per_ms); -} - -fn milliTimestampWindows() u64 { - //FileTime has a granularity of 100 nanoseconds - // and uses the NTFS/Windows epoch - var ft: windows.FILETIME = undefined; - windows.GetSystemTimeAsFileTime(&ft); - const hns_per_ms = (ns_per_s / 100) / ms_per_s; - const epoch_adj = epoch.windows * ms_per_s; - - const ft64 = (u64(ft.dwHighDateTime) << 32) | ft.dwLowDateTime; - return @divFloor(ft64, hns_per_ms) - -epoch_adj; -} +/// TODO audit this function. is it possible to return an error? +pub fn milliTimestamp() u64 { + if (os.windows.is_the_target and !builtin.link_libc) { + //FileTime has a granularity of 100 nanoseconds + // and uses the NTFS/Windows epoch + var ft: os.windows.FILETIME = undefined; + os.windows.kernel32.GetSystemTimeAsFileTime(&ft); + const hns_per_ms = (ns_per_s / 100) / ms_per_s; + const epoch_adj = epoch.windows * ms_per_s; + + const ft64 = (u64(ft.dwHighDateTime) << 32) | ft.dwLowDateTime; + return @divFloor(ft64, hns_per_ms) - -epoch_adj; + } + if (os.wasi.is_the_target and !builtin.link_libc) { + var ns: os.wasi.timestamp_t = undefined; -fn milliTimestampDarwin() u64 { - var tv: darwin.timeval = undefined; - var err = darwin.gettimeofday(&tv, null); - debug.assert(err == 0); - const sec_ms = tv.tv_sec * ms_per_s; - const usec_ms = @divFloor(tv.tv_usec, us_per_s / ms_per_s); - return @intCast(u64, sec_ms + usec_ms); -} + // TODO: Verify that precision is ignored + const err = os.wasi.clock_time_get(os.wasi.CLOCK_REALTIME, 1, &ns); + assert(err == os.wasi.ESUCCESS); -fn milliTimestampPosix() u64 { + const ns_per_ms = 1000; + return @divFloor(ns, ns_per_ms); + } + if (os.darwin.is_the_target) { + var tv: os.darwin.timeval = undefined; + var err = os.darwin.gettimeofday(&tv, null); + assert(err == 0); + const sec_ms = tv.tv_sec * ms_per_s; + const usec_ms = @divFloor(tv.tv_usec, us_per_s / ms_per_s); + return @intCast(u64, sec_ms + usec_ms); + } + var ts: os.timespec = undefined; //From what I can tell there's no reason clock_gettime // should ever fail for us with CLOCK_REALTIME, // seccomp aside. - var ts: posix.timespec = undefined; - const err = posix.clock_gettime(posix.CLOCK_REALTIME, &ts); - debug.assert(err == 0); + os.clock_gettime(os.CLOCK_REALTIME, &ts) catch unreachable; const sec_ms = @intCast(u64, ts.tv_sec) * ms_per_s; const nsec_ms = @divFloor(@intCast(u64, ts.tv_nsec), ns_per_s / ms_per_s); return sec_ms + nsec_ms; @@ -145,27 +90,23 @@ pub const s_per_week = s_per_day * 7; /// depends on the OS. On Windows and Darwin it is a hardware counter /// value that requires calculation to convert to a meaninful unit. pub const Timer = struct { - - //if we used resolution's value when performing the - // performance counter calc on windows/darwin, it would - // be less precise + ///if we used resolution's value when performing the + /// performance counter calc on windows/darwin, it would + /// be less precise frequency: switch (builtin.os) { - Os.windows => u64, - Os.macosx, Os.ios => darwin.mach_timebase_info_data, + .windows => u64, + .macosx, .ios, .tvos, .watchos => darwin.mach_timebase_info_data, else => void, }, resolution: u64, start_time: u64, - //At some point we may change our minds on RAW, but for now we're - // sticking with posix standard MONOTONIC. For more information, see: - // https://github.com/ziglang/zig/pull/933 - // - //const monotonic_clock_id = switch(builtin.os) { - // Os.linux => linux.CLOCK_MONOTONIC_RAW, - // else => posix.CLOCK_MONOTONIC, - //}; - const monotonic_clock_id = posix.CLOCK_MONOTONIC; + const Error = error{TimerUnsupported}; + + ///At some point we may change our minds on RAW, but for now we're + /// sticking with posix standard MONOTONIC. For more information, see: + /// https://github.com/ziglang/zig/pull/933 + const monotonic_clock_id = os.CLOCK_MONOTONIC; /// Initialize the timer structure. //This gives us an opportunity to grab the counter frequency in windows. //On Windows: QueryPerformanceCounter will succeed on anything >= XP/2000. @@ -174,66 +115,51 @@ pub const Timer = struct { // impossible here barring cosmic rays or other such occurrences of // incredibly bad luck. //On Darwin: This cannot fail, as far as I am able to tell. - const TimerError = error{ - TimerUnsupported, - Unexpected, - }; - pub fn start() TimerError!Timer { + pub fn start() Error!Timer { var self: Timer = undefined; - switch (builtin.os) { - Os.windows => { - var freq: i64 = undefined; - var err = windows.QueryPerformanceFrequency(&freq); - if (err == windows.FALSE) return error.TimerUnsupported; - self.frequency = @intCast(u64, freq); - self.resolution = @divFloor(ns_per_s, self.frequency); - - var start_time: i64 = undefined; - err = windows.QueryPerformanceCounter(&start_time); - debug.assert(err != windows.FALSE); - self.start_time = @intCast(u64, start_time); - }, - Os.linux, Os.freebsd, Os.netbsd => { - //On Linux, seccomp can do arbitrary things to our ability to call - // syscalls, including return any errno value it wants and - // inconsistently throwing errors. Since we can't account for - // abuses of seccomp in a reasonable way, we'll assume that if - // seccomp is going to block us it will at least do so consistently - var ts: posix.timespec = undefined; - var result = posix.clock_getres(monotonic_clock_id, &ts); - var errno = posix.getErrno(result); - switch (errno) { - 0 => {}, - posix.EINVAL => return error.TimerUnsupported, - else => return std.os.unexpectedErrorPosix(errno), - } - self.resolution = @intCast(u64, ts.tv_sec) * u64(ns_per_s) + @intCast(u64, ts.tv_nsec); - - result = posix.clock_gettime(monotonic_clock_id, &ts); - errno = posix.getErrno(result); - if (errno != 0) return std.os.unexpectedErrorPosix(errno); - self.start_time = @intCast(u64, ts.tv_sec) * u64(ns_per_s) + @intCast(u64, ts.tv_nsec); - }, - Os.macosx, Os.ios => { - darwin.mach_timebase_info(&self.frequency); - self.resolution = @divFloor(self.frequency.numer, self.frequency.denom); - self.start_time = darwin.mach_absolute_time(); - }, - else => @compileError("Unsupported OS"), + if (os.windows.is_the_target) { + var freq: i64 = undefined; + var err = windows.QueryPerformanceFrequency(&freq); + if (err == windows.FALSE) return error.TimerUnsupported; + self.frequency = @intCast(u64, freq); + self.resolution = @divFloor(ns_per_s, self.frequency); + + var start_time: i64 = undefined; + err = windows.QueryPerformanceCounter(&start_time); + assert(err != windows.FALSE); + self.start_time = @intCast(u64, start_time); + } else if (os.darwin.is_the_target) { + darwin.mach_timebase_info(&self.frequency); + self.resolution = @divFloor(self.frequency.numer, self.frequency.denom); + self.start_time = darwin.mach_absolute_time(); + } else { + //On Linux, seccomp can do arbitrary things to our ability to call + // syscalls, including return any errno value it wants and + // inconsistently throwing errors. Since we can't account for + // abuses of seccomp in a reasonable way, we'll assume that if + // seccomp is going to block us it will at least do so consistently + var ts: os.timespec = undefined; + os.clock_getres(monotonic_clock_id, &ts) catch return error.TimerUnsupported; + self.resolution = @intCast(u64, ts.tv_sec) * u64(ns_per_s) + @intCast(u64, ts.tv_nsec); + + os.clock_gettime(monotonic_clock_id, &ts) catch return error.TimerUnsupported; + self.start_time = @intCast(u64, ts.tv_sec) * u64(ns_per_s) + @intCast(u64, ts.tv_nsec); } + return self; } /// Reads the timer value since start or the last reset in nanoseconds pub fn read(self: *Timer) u64 { var clock = clockNative() - self.start_time; - return switch (builtin.os) { - Os.windows => @divFloor(clock * ns_per_s, self.frequency), - Os.linux, Os.freebsd, Os.netbsd => clock, - Os.macosx, Os.ios => @divFloor(clock * self.frequency.numer, self.frequency.denom), - else => @compileError("Unsupported OS"), - }; + if (os.windows.is_the_target) { + return @divFloor(clock * ns_per_s, self.frequency); + } + if (os.darwin.is_the_target) { + return @divFloor(clock * self.frequency.numer, self.frequency.denom); + } + return clock; } /// Resets the timer value to 0/now. @@ -249,37 +175,27 @@ pub const Timer = struct { return lap_time; } - const clockNative = switch (builtin.os) { - Os.windows => clockWindows, - Os.linux, Os.freebsd, Os.netbsd => clockLinux, - Os.macosx, Os.ios => clockDarwin, - else => @compileError("Unsupported OS"), - }; - - fn clockWindows() u64 { - var result: i64 = undefined; - var err = windows.QueryPerformanceCounter(&result); - debug.assert(err != windows.FALSE); - return @intCast(u64, result); - } - - fn clockDarwin() u64 { - return darwin.mach_absolute_time(); - } - - fn clockLinux() u64 { - var ts: posix.timespec = undefined; - var result = posix.clock_gettime(monotonic_clock_id, &ts); - debug.assert(posix.getErrno(result) == 0); + fn clockNative() u64 { + if (os.windows.is_the_target) { + var result: i64 = undefined; + var err = windows.QueryPerformanceCounter(&result); + assert(err != windows.FALSE); + return @intCast(u64, result); + } + if (os.darwin.is_the_target) { + return darwin.mach_absolute_time(); + } + var ts: os.timespec = undefined; + os.clock_gettime(monotonic_clock_id, &ts) catch unreachable; return @intCast(u64, ts.tv_sec) * u64(ns_per_s) + @intCast(u64, ts.tv_nsec); } }; -test "os.time.sleep" { +test "sleep" { sleep(1); } -test "os.time.timestamp" { +test "timestamp" { const ns_per_ms = (ns_per_s / ms_per_s); const margin = 50; @@ -290,7 +206,7 @@ test "os.time.timestamp" { testing.expect(interval > 0 and interval < margin); } -test "os.time.Timer" { +test "Timer" { const ns_per_ms = (ns_per_s / ms_per_s); const margin = ns_per_ms * 150; diff --git a/std/zig/bench.zig b/std/zig/bench.zig index ed6ae9a128..b43c491c97 100644 --- a/std/zig/bench.zig +++ b/std/zig/bench.zig @@ -10,7 +10,7 @@ var fixed_buffer_mem: [10 * 1024 * 1024]u8 = undefined; pub fn main() !void { var i: usize = 0; - var timer = try std.os.time.Timer.start(); + var timer = try std.time.Timer.start(); const start = timer.lap(); const iterations = 100; var memory_used: usize = 0; @@ -19,7 +19,7 @@ pub fn main() !void { } const end = timer.read(); memory_used /= iterations; - const elapsed_s = @intToFloat(f64, end - start) / std.os.time.ns_per_s; + const elapsed_s = @intToFloat(f64, end - start) / std.time.ns_per_s; const bytes_per_sec = @intToFloat(f64, source.len * iterations) / elapsed_s; const mb_per_sec = bytes_per_sec / (1024 * 1024); |
