tests passing on linux

This commit is contained in:
Andrew Kelley 2019-05-26 23:35:26 -04:00
parent 2b42e910bf
commit 0c6ab61b22
No known key found for this signature in database
GPG Key ID: 7C5F548F728501A9
38 changed files with 348 additions and 298 deletions

View File

@ -166,10 +166,8 @@ fn dependOnLib(b: *Builder, lib_exe_obj: var, dep: LibraryDep) void {
}
fn fileExists(filename: []const u8) !bool {
fs.File.exists(filename) catch |err| switch (err) {
error.PermissionDenied,
error.FileNotFound,
=> return false,
fs.File.access(filename) catch |err| switch (err) {
error.FileNotFound => return false,
else => return err,
};
return true;

View File

@ -796,8 +796,8 @@ const assert = std.debug.assert;
threadlocal var x: i32 = 1234;
test "thread local storage" {
const thread1 = try std.os.spawnThread({}, testTls);
const thread2 = try std.os.spawnThread({}, testTls);
const thread1 = try std.Thread.spawn({}, testTls);
const thread2 = try std.Thread.spawn({}, testTls);
testTls({});
thread1.wait();
thread2.wait();

View File

@ -1,12 +1,13 @@
const std = @import("std");
const io = std.io;
const process = std.process;
const File = std.fs.File;
const mem = std.mem;
const os = std.os;
const warn = std.debug.warn;
const allocator = std.debug.global_allocator;
pub fn main() !void {
var args_it = os.args();
var args_it = process.args();
const exe = try unwrapArg(args_it.next(allocator).?);
var catted_anything = false;
var stdout_file = try io.getStdOut();
@ -20,7 +21,7 @@ pub fn main() !void {
} else if (arg[0] == '-') {
return usage(exe);
} else {
var file = os.File.openRead(arg) catch |err| {
var file = File.openRead(arg) catch |err| {
warn("Unable to open file: {}\n", @errorName(err));
return err;
};
@ -41,7 +42,7 @@ fn usage(exe: []const u8) !void {
return error.Invalid;
}
fn cat_file(stdout: *os.File, file: *os.File) !void {
fn cat_file(stdout: *File, file: *File) !void {
var buf: [1024 * 4]u8 = undefined;
while (true) {

View File

@ -2,7 +2,6 @@ const builtin = @import("builtin");
const std = @import("std");
const io = std.io;
const fmt = std.fmt;
const os = std.os;
pub fn main() !void {
var stdout_file = try io.getStdOut();
@ -11,7 +10,7 @@ pub fn main() !void {
try stdout.print("Welcome to the Guess Number Game in Zig.\n");
var seed_bytes: [@sizeOf(u64)]u8 = undefined;
os.getRandomBytes(seed_bytes[0..]) catch |err| {
std.crypto.randomBytes(seed_bytes[0..]) catch |err| {
std.debug.warn("unable to seed random number generator: {}", err);
return err;
};

View File

@ -5,6 +5,6 @@ const c = @cImport({
});
export fn main(argc: c_int, argv: [*]?[*]u8) c_int {
c.fprintf(c.stderr, c"Hello, world!\n");
_ = c.fprintf(c.stderr, c"Hello, world!\n");
return 0;
}

View File

@ -301,6 +301,7 @@ pub const Compilation = struct {
InvalidUtf8,
BadPathName,
DeviceBusy,
CurrentWorkingDirectoryUnlinked,
};
pub const Event = union(enum) {

View File

@ -182,7 +182,7 @@ pub const LibCInstallation = struct {
}
async fn findNativeIncludeDirLinux(self: *LibCInstallation, loop: *event.Loop) !void {
const cc_exe = std.process.getEnvPosix("CC") orelse "cc";
const cc_exe = std.os.getenv("CC") orelse "cc";
const argv = []const []const u8{
cc_exe,
"-E",
@ -392,7 +392,7 @@ pub const LibCInstallation = struct {
/// caller owns returned memory
async fn ccPrintFileName(loop: *event.Loop, o_file: []const u8, want_dirname: bool) ![]u8 {
const cc_exe = std.process.getEnvPosix("CC") orelse "cc";
const cc_exe = std.os.getenv("CC") orelse "cc";
const arg1 = try std.fmt.allocPrint(loop.allocator, "-print-file-name={}", o_file);
defer loop.allocator.free(arg1);
const argv = []const []const u8{ cc_exe, arg1 };
@ -463,7 +463,7 @@ fn fileExists(path: []const u8) !bool {
if (fs.File.access(path)) |_| {
return true;
} else |err| switch (err) {
error.FileNotFound, error.PermissionDenied => return false,
error.FileNotFound => return false,
else => return error.FileSystem,
}
}

View File

@ -702,6 +702,7 @@ const FmtError = error{
ReadOnlyFileSystem,
LinkQuotaExceeded,
FileBusy,
CurrentWorkingDirectoryUnlinked,
} || fs.File.OpenError;
async fn asyncFmtMain(
@ -851,7 +852,7 @@ fn cmdTargets(allocator: *Allocator, args: []const []const u8) !void {
}
fn cmdVersion(allocator: *Allocator, args: []const []const u8) !void {
try stdout.print("{}\n", std.cstr.toSliceConst(c.ZIG_VERSION_STRING));
try stdout.print("{}\n", std.mem.toSliceConst(u8, c.ZIG_VERSION_STRING));
}
const args_test_spec = []Flag{Flag.Bool("--help")};
@ -924,14 +925,14 @@ fn cmdInternalBuildInfo(allocator: *Allocator, args: []const []const u8) !void {
\\ZIG_DIA_GUIDS_LIB {}
\\
,
std.cstr.toSliceConst(c.ZIG_CMAKE_BINARY_DIR),
std.cstr.toSliceConst(c.ZIG_CXX_COMPILER),
std.cstr.toSliceConst(c.ZIG_LLVM_CONFIG_EXE),
std.cstr.toSliceConst(c.ZIG_LLD_INCLUDE_PATH),
std.cstr.toSliceConst(c.ZIG_LLD_LIBRARIES),
std.cstr.toSliceConst(c.ZIG_STD_FILES),
std.cstr.toSliceConst(c.ZIG_C_HEADER_FILES),
std.cstr.toSliceConst(c.ZIG_DIA_GUIDS_LIB),
std.mem.toSliceConst(u8, c.ZIG_CMAKE_BINARY_DIR),
std.mem.toSliceConst(u8, c.ZIG_CXX_COMPILER),
std.mem.toSliceConst(u8, c.ZIG_LLVM_CONFIG_EXE),
std.mem.toSliceConst(u8, c.ZIG_LLD_INCLUDE_PATH),
std.mem.toSliceConst(u8, c.ZIG_LLD_LIBRARIES),
std.mem.toSliceConst(u8, c.ZIG_STD_FILES),
std.mem.toSliceConst(u8, c.ZIG_C_HEADER_FILES),
std.mem.toSliceConst(u8, c.ZIG_DIA_GUIDS_LIB),
);
}

View File

@ -39,8 +39,8 @@ pub extern "c" fn open(path: [*]const u8, oflag: c_uint, ...) c_int;
pub extern "c" fn raise(sig: c_int) c_int;
pub extern "c" fn read(fd: fd_t, buf: [*]u8, nbyte: usize) isize;
pub extern "c" fn pread(fd: fd_t, buf: [*]u8, nbyte: usize, offset: u64) isize;
pub extern "c" fn preadv(fd: c_int, iov: [*]const iovec, iovcnt: c_int, offset: usize) isize;
pub extern "c" fn pwritev(fd: c_int, iov: [*]const iovec, iovcnt: c_int, offset: usize) isize;
pub extern "c" fn preadv(fd: c_int, iov: [*]const iovec, iovcnt: c_uint, offset: usize) isize;
pub extern "c" fn pwritev(fd: c_int, iov: [*]const iovec_const, iovcnt: c_uint, offset: usize) isize;
pub extern "c" fn stat(noalias path: [*]const u8, noalias buf: *Stat) c_int;
pub extern "c" fn write(fd: fd_t, buf: [*]const u8, nbyte: usize) isize;
pub 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;
pub extern "c" fn mprotect(addr: *align(page_size) c_void, len: usize, prot: c_uint) c_int;
pub extern "c" fn unlink(path: [*]const u8) c_int;
pub extern "c" fn getcwd(buf: [*]u8, size: usize) ?[*]u8;
pub extern "c" fn waitpid(pid: c_int, stat_loc: *c_int, options: c_int) c_int;
pub extern "c" fn waitpid(pid: c_int, stat_loc: *c_uint, options: c_uint) c_int;
pub extern "c" fn fork() c_int;
pub extern "c" fn access(path: [*]const u8, mode: c_uint) c_int;
pub 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
pub extern "c" fn sysctlnametomib(name: [*]const u8, mibp: ?*c_int, sizep: ?*usize) c_int;
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 socket(domain: c_uint, sock_type: c_uint, protocol: c_uint) c_int;
pub extern "c" fn listen(sockfd: fd_t, backlog: c_uint) c_int;
pub extern "c" fn getsockname(sockfd: fd_t, noalias addr: *sockaddr, noalias addrlen: *socklen_t) c_int;
pub extern "c" fn connect(sockfd: fd_t, sock_addr: *const sockaddr, addrlen: socklen_t) c_int;
pub extern "c" fn accept4(sockfd: fd_t, addr: *sockaddr, addrlen: *socklen_t, flags: c_uint) c_int;
pub extern "c" fn getsockopt(sockfd: fd_t, level: c_int, optname: c_int, optval: *c_void, optlen: *socklen_t) 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) isize;
pub extern "c" fn openat(fd: c_int, path: [*]const u8, flags: c_int) c_int;

View File

@ -1,13 +1,27 @@
const std = @import("../std.zig");
use std.c;
pub extern "c" fn getrandom(buf_ptr: [*]u8, buf_len: usize, flags: c_uint) c_int;
pub extern "c" fn sched_getaffinity(pid: c_int, size: usize, set: *cpu_set_t) c_int;
extern "c" fn __errno_location() *c_int;
pub const _errno = __errno_location;
pub extern "c" fn getrandom(buf_ptr: [*]u8, buf_len: usize, flags: c_uint) c_int;
pub extern "c" fn sched_getaffinity(pid: c_int, size: usize, set: *cpu_set_t) c_int;
pub extern "c" fn eventfd(initval: c_uint, flags: c_uint) c_int;
pub extern "c" fn epoll_ctl(epfd: fd_t, op: c_uint, fd: fd_t, event: *epoll_event) c_int;
pub extern "c" fn epoll_create1(flags: c_uint) c_int;
pub extern "c" fn epoll_wait(epfd: fd_t, events: [*]epoll_event, maxevents: c_uint, timeout: c_int) c_int;
pub extern "c" fn epoll_pwait(
epfd: fd_t,
events: [*]epoll_event,
maxevents: c_int,
timeout: c_int,
sigmask: *const sigset_t,
) c_int;
pub extern "c" fn inotify_init1(flags: c_uint) c_int;
pub extern "c" fn inotify_add_watch(fd: fd_t, pathname: [*]const u8, mask: u32) c_int;
/// See std.elf for constants for this
pub extern fn getauxval(__type: c_ulong) c_ulong;
pub extern "c" fn getauxval(__type: c_ulong) c_ulong;
pub const dl_iterate_phdr_callback = extern fn (info: *dl_phdr_info, size: usize, data: ?*c_void) c_int;
pub extern fn dl_iterate_phdr(callback: dl_iterate_phdr_callback, data: ?*c_void) c_int;
pub extern "c" fn dl_iterate_phdr(callback: dl_iterate_phdr_callback, data: ?*c_void) c_int;

View File

@ -54,10 +54,10 @@ pub const ChildProcess = struct {
os.ChangeCurDirError || windows.CreateProcessError;
pub const Term = union(enum) {
Exited: i32,
Signal: i32,
Stopped: i32,
Unknown: i32,
Exited: u32,
Signal: u32,
Stopped: u32,
Unknown: u32,
};
pub const StdIo = enum {
@ -155,7 +155,7 @@ pub const ChildProcess = struct {
}
pub const ExecResult = struct {
term: os.ChildProcess.Term,
term: Term,
stdout: []u8,
stderr: []u8,
};
@ -224,7 +224,7 @@ pub const ChildProcess = struct {
if (windows.GetExitCodeProcess(self.handle, &exit_code) == 0) {
break :x Term{ .Unknown = 0 };
} else {
break :x Term{ .Exited = @bitCast(i32, exit_code) };
break :x Term{ .Exited = exit_code };
}
});
@ -240,7 +240,7 @@ pub const ChildProcess = struct {
self.handleWaitResult(status);
}
fn handleWaitResult(self: *ChildProcess, status: i32) void {
fn handleWaitResult(self: *ChildProcess, status: u32) void {
self.term = self.cleanupAfterWait(status);
}
@ -259,7 +259,7 @@ pub const ChildProcess = struct {
}
}
fn cleanupAfterWait(self: *ChildProcess, status: i32) !Term {
fn cleanupAfterWait(self: *ChildProcess, status: u32) !Term {
defer {
os.close(self.err_pipe[0]);
os.close(self.err_pipe[1]);
@ -281,7 +281,7 @@ pub const ChildProcess = struct {
return statusToTerm(status);
}
fn statusToTerm(status: i32) Term {
fn statusToTerm(status: u32) Term {
return if (os.WIFEXITED(status))
Term{ .Exited = os.WEXITSTATUS(status) }
else if (os.WIFSIGNALED(status))

View File

@ -28,7 +28,7 @@ test "cstr fns" {
fn testCStrFnsImpl() void {
testing.expect(cmp(c"aoeu", c"aoez") == -1);
testing.expect(len(c"123456789") == 9);
testing.expect(mem.len(u8, c"123456789") == 9);
}
/// Returns a mutable slice with 1 more byte of length which is a null byte.

View File

@ -6,8 +6,7 @@ const os = std.os;
const assert = std.debug.assert;
const testing = std.testing;
const elf = std.elf;
const windows = os.windows;
const win_util = @import("os/windows/util.zig");
const windows = std.os.windows;
const maxInt = std.math.maxInt;
pub const DynLib = switch (builtin.os) {
@ -102,17 +101,16 @@ pub fn linkmap_iterator(phdrs: []elf.Phdr) !LinkMap.Iterator {
pub const LinuxDynLib = struct {
elf_lib: ElfLib,
fd: i32,
map_addr: usize,
map_size: usize,
memory: []align(mem.page_size) u8,
/// Trusts the file
pub fn open(allocator: *mem.Allocator, path: []const u8) !DynLib {
const fd = try os.open(path, 0, os.O_RDONLY | os.O_CLOEXEC);
errdefer std.os.close(fd);
errdefer os.close(fd);
const size = @intCast(usize, (try std.os.posixFStat(fd)).size);
const size = @intCast(usize, (try os.fstat(fd)).size);
const addr = os.mmap(
const bytes = try os.mmap(
null,
size,
os.PROT_READ | os.PROT_EXEC,
@ -120,21 +118,18 @@ pub const LinuxDynLib = struct {
fd,
0,
);
errdefer os.munmap(addr, size);
const bytes = @intToPtr([*]align(mem.page_size) u8, addr)[0..size];
errdefer os.munmap(bytes);
return DynLib{
.elf_lib = try ElfLib.init(bytes),
.fd = fd,
.map_addr = addr,
.map_size = size,
.memory = bytes,
};
}
pub fn close(self: *DynLib) void {
os.munmap(self.map_addr, self.map_size);
std.os.close(self.fd);
os.munmap(self.memory);
os.close(self.fd);
self.* = undefined;
}
@ -253,28 +248,21 @@ pub const WindowsDynLib = struct {
dll: windows.HMODULE,
pub fn open(allocator: *mem.Allocator, path: []const u8) !WindowsDynLib {
const wpath = try win_util.sliceToPrefixedFileW(path);
const wpath = try windows.sliceToPrefixedFileW(path);
return WindowsDynLib{
.allocator = allocator,
.dll = windows.LoadLibraryW(&wpath) orelse {
switch (windows.GetLastError()) {
windows.ERROR.FILE_NOT_FOUND => return error.FileNotFound,
windows.ERROR.PATH_NOT_FOUND => return error.FileNotFound,
windows.ERROR.MOD_NOT_FOUND => return error.FileNotFound,
else => |err| return windows.unexpectedError(err),
}
},
.dll = try windows.LoadLibraryW(&wpath),
};
}
pub fn close(self: *WindowsDynLib) void {
assert(windows.FreeLibrary(self.dll) != 0);
windows.FreeLibrary(self.dll);
self.* = undefined;
}
pub fn lookup(self: *WindowsDynLib, name: []const u8) ?usize {
return @ptrToInt(windows.GetProcAddress(self.dll, name.ptr));
return @ptrToInt(windows.kernel32.GetProcAddress(self.dll, name.ptr));
}
};

View File

@ -36,7 +36,7 @@ pub const Request = struct {
offset: usize,
result: Error!void,
pub const Error = os.PosixWriteError;
pub const Error = os.WriteError;
};
pub const PReadV = struct {
@ -45,7 +45,7 @@ pub const Request = struct {
offset: usize,
result: Error!usize,
pub const Error = os.PosixReadError;
pub const Error = os.ReadError;
};
pub const Open = struct {
@ -172,7 +172,7 @@ pub async fn pwritevPosix(
fd: fd_t,
iovecs: []const os.iovec_const,
offset: usize,
) os.PosixWriteError!void {
) os.WriteError!void {
// workaround for https://github.com/ziglang/zig/issues/1194
suspend {
resume @handle();
@ -320,7 +320,7 @@ pub async fn preadvPosix(
fd: fd_t,
iovecs: []const os.iovec,
offset: usize,
) os.PosixReadError!usize {
) os.ReadError!usize {
// workaround for https://github.com/ziglang/zig/issues/1194
suspend {
resume @handle();
@ -786,7 +786,7 @@ pub fn Watch(comptime V: type) type {
switch (builtin.os) {
builtin.Os.linux => {
const inotify_fd = try os.linuxINotifyInit1(os.linux.IN_NONBLOCK | os.linux.IN_CLOEXEC);
const inotify_fd = try os.inotify_init1(os.linux.IN_NONBLOCK | os.linux.IN_CLOEXEC);
errdefer os.close(inotify_fd);
var result: *Self = undefined;
@ -977,7 +977,7 @@ pub fn Watch(comptime V: type) type {
var basename_with_null_consumed = false;
defer if (!basename_with_null_consumed) self.channel.loop.allocator.free(basename_with_null);
const wd = try os.linuxINotifyAddWatchC(
const wd = try os.inotify_add_watchC(
self.os_data.inotify_fd,
dirname_with_null.ptr,
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 {
ev = @ptrCast(*os.linux.inotify_event, ptr);
if (ev.mask & os.linux.IN_CLOSE_WRITE == os.linux.IN_CLOSE_WRITE) {
const basename_ptr = ptr + @sizeOf(os.linux.inotify_event);
const basename_with_null = basename_ptr[0 .. std.cstr.len(basename_ptr) + 1];
const basename_with_null = basename_ptr[0 .. std.mem.len(u8, basename_ptr) + 1];
const user_value = blk: {
const held = await (async watch.os_data.table_lock.acquire() catch unreachable);
defer held.release();

View File

@ -99,7 +99,7 @@ pub const Loop = struct {
/// have the correct pointer value.
pub fn initMultiThreaded(self: *Loop, allocator: *mem.Allocator) !void {
if (builtin.single_threaded) @compileError("initMultiThreaded unavailable when building in single-threaded mode");
const core_count = try os.cpuCount(allocator);
const core_count = try Thread.cpuCount();
return self.initInternal(allocator, core_count);
}
@ -139,9 +139,9 @@ pub const Loop = struct {
self.allocator.free(self.extra_threads);
}
const InitOsDataError = os.LinuxEpollCreateError || mem.Allocator.Error || os.LinuxEventFdError ||
os.SpawnThreadError || os.LinuxEpollCtlError || os.BsdKEventError ||
os.WindowsCreateIoCompletionPortError;
const InitOsDataError = os.EpollCreateError || mem.Allocator.Error || os.EventFdError ||
Thread.SpawnError || os.EpollCtlError || os.KEventError ||
windows.CreateIoCompletionPortError;
const wakeup_bytes = []u8{0x1} ** 8;
@ -172,7 +172,7 @@ pub const Loop = struct {
.handle = undefined,
.overlapped = ResumeNode.overlapped_init,
},
.eventfd = try os.linuxEventFd(1, os.EFD_CLOEXEC | os.EFD_NONBLOCK),
.eventfd = try os.eventfd(1, os.EFD_CLOEXEC | os.EFD_NONBLOCK),
.epoll_op = os.EPOLL_CTL_ADD,
},
.next = undefined,
@ -180,17 +180,17 @@ pub const Loop = struct {
self.available_eventfd_resume_nodes.push(eventfd_node);
}
self.os_data.epollfd = try os.linuxEpollCreate(os.EPOLL_CLOEXEC);
self.os_data.epollfd = try os.epoll_create1(os.EPOLL_CLOEXEC);
errdefer os.close(self.os_data.epollfd);
self.os_data.final_eventfd = try os.linuxEventFd(0, os.EFD_CLOEXEC | os.EFD_NONBLOCK);
self.os_data.final_eventfd = try os.eventfd(0, os.EFD_CLOEXEC | os.EFD_NONBLOCK);
errdefer os.close(self.os_data.final_eventfd);
self.os_data.final_eventfd_event = os.epoll_event{
.events = os.EPOLLIN,
.data = os.epoll_data{ .ptr = @ptrToInt(&self.final_resume_node) },
};
try os.linuxEpollCtl(
try os.epoll_ctl(
self.os_data.epollfd,
os.EPOLL_CTL_ADD,
self.os_data.final_eventfd,
@ -211,7 +211,7 @@ pub const Loop = struct {
var extra_thread_index: usize = 0;
errdefer {
// writing 8 bytes to an eventfd cannot fail
os.posixWrite(self.os_data.final_eventfd, wakeup_bytes) catch unreachable;
os.write(self.os_data.final_eventfd, wakeup_bytes) catch unreachable;
while (extra_thread_index != 0) {
extra_thread_index -= 1;
self.extra_threads[extra_thread_index].wait();
@ -417,11 +417,11 @@ pub const Loop = struct {
.events = flags,
.data = os.linux.epoll_data{ .ptr = @ptrToInt(resume_node) },
};
try os.linuxEpollCtl(self.os_data.epollfd, op, fd, &ev);
try os.epoll_ctl(self.os_data.epollfd, op, fd, &ev);
}
pub fn linuxRemoveFd(self: *Loop, fd: i32) void {
os.linuxEpollCtl(self.os_data.epollfd, os.linux.EPOLL_CTL_DEL, fd, undefined) catch {};
os.epoll_ctl(self.os_data.epollfd, os.linux.EPOLL_CTL_DEL, fd, undefined) catch {};
self.finishOneEvent();
}
@ -626,7 +626,7 @@ pub const Loop = struct {
builtin.Os.linux => {
self.posixFsRequest(&self.os_data.fs_end_request);
// writing 8 bytes to an eventfd cannot fail
os.posixWrite(self.os_data.final_eventfd, wakeup_bytes) catch unreachable;
os.write(self.os_data.final_eventfd, wakeup_bytes) catch unreachable;
return;
},
builtin.Os.macosx, builtin.Os.freebsd, builtin.Os.netbsd => {
@ -666,7 +666,7 @@ pub const Loop = struct {
builtin.Os.linux => {
// only process 1 event so we don't steal from other threads
var events: [1]os.linux.epoll_event = undefined;
const count = os.linuxEpollWait(self.os_data.epollfd, events[0..], -1);
const count = os.epoll_wait(self.os_data.epollfd, events[0..], -1);
for (events[0..count]) |ev| {
const resume_node = @intToPtr(*ResumeNode, ev.data.ptr);
const handle = resume_node.handle;
@ -783,10 +783,10 @@ pub const Loop = struct {
switch (node.data.msg) {
@TagType(fs.Request.Msg).End => return,
@TagType(fs.Request.Msg).PWriteV => |*msg| {
msg.result = os.posix_pwritev(msg.fd, msg.iov.ptr, msg.iov.len, msg.offset);
msg.result = os.pwritev(msg.fd, msg.iov, msg.offset);
},
@TagType(fs.Request.Msg).PReadV => |*msg| {
msg.result = os.posix_preadv(msg.fd, msg.iov.ptr, msg.iov.len, msg.offset);
msg.result = os.preadv(msg.fd, msg.iov, msg.offset);
},
@TagType(fs.Request.Msg).Open => |*msg| {
msg.result = os.openC(msg.path.ptr, msg.flags, msg.mode);
@ -800,7 +800,7 @@ pub const Loop = struct {
break :blk;
};
defer os.close(fd);
msg.result = os.posixWrite(fd, msg.contents);
msg.result = os.write(fd, msg.contents);
},
}
switch (node.data.finish) {

View File

@ -45,13 +45,13 @@ pub const Server = struct {
) !void {
self.handleRequestFn = handleRequestFn;
const sockfd = try os.posixSocket(os.AF_INET, os.SOCK_STREAM | os.SOCK_CLOEXEC | os.SOCK_NONBLOCK, os.PROTO_tcp);
const sockfd = try os.socket(os.AF_INET, os.SOCK_STREAM | os.SOCK_CLOEXEC | os.SOCK_NONBLOCK, os.PROTO_tcp);
errdefer os.close(sockfd);
self.sockfd = sockfd;
try os.posixBind(sockfd, &address.os_addr);
try os.posixListen(sockfd, os.SOMAXCONN);
self.listen_address = std.net.Address.initPosix(try os.posixGetSockName(sockfd));
try os.bind(sockfd, &address.os_addr);
try os.listen(sockfd, os.SOMAXCONN);
self.listen_address = std.net.Address.initPosix(try os.getsockname(sockfd));
self.accept_coro = try async<self.loop.allocator> Server.handler(self);
errdefer cancel self.accept_coro.?;
@ -64,7 +64,10 @@ pub const Server = struct {
/// Stop listening
pub fn close(self: *Server) void {
self.loop.linuxRemoveFd(self.sockfd.?);
os.close(self.sockfd.?);
if (self.sockfd) |fd| {
os.close(fd);
self.sockfd = null;
}
}
pub fn deinit(self: *Server) void {
@ -76,7 +79,7 @@ pub const Server = struct {
while (true) {
var accepted_addr: std.net.Address = undefined;
// TODO just inline the following function here and don't expose it as posixAsyncAccept
if (os.posixAsyncAccept(self.sockfd.?, &accepted_addr.os_addr, os.SOCK_NONBLOCK | os.SOCK_CLOEXEC)) |accepted_fd| {
if (os.accept4_async(self.sockfd.?, &accepted_addr.os_addr, os.SOCK_NONBLOCK | os.SOCK_CLOEXEC)) |accepted_fd| {
if (accepted_fd == -1) {
// would block
suspend; // we will get resumed by epoll_wait in the event loop
@ -105,7 +108,7 @@ pub const Server = struct {
};
pub async fn connectUnixSocket(loop: *Loop, path: []const u8) !i32 {
const sockfd = try os.posixSocket(
const sockfd = try os.socket(
os.AF_UNIX,
os.SOCK_STREAM | os.SOCK_CLOEXEC | os.SOCK_NONBLOCK,
0,
@ -120,9 +123,9 @@ pub async fn connectUnixSocket(loop: *Loop, path: []const u8) !i32 {
if (path.len > @typeOf(sock_addr.path).len) return error.NameTooLong;
mem.copy(u8, sock_addr.path[0..], path);
const size = @intCast(u32, @sizeOf(os.sa_family_t) + path.len);
try os.posixConnectAsync(sockfd, &sock_addr, size);
try os.connect_async(sockfd, &sock_addr, size);
try await try async loop.linuxWaitFd(sockfd, os.EPOLLIN | os.EPOLLOUT | os.EPOLLET);
try os.posixGetSockOptConnectError(sockfd);
try os.getsockoptError(sockfd);
return sockfd;
}
@ -249,12 +252,12 @@ pub async fn readv(loop: *Loop, fd: fd_t, data: []const []u8) !usize {
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(os.AF_INET, os.SOCK_STREAM | os.SOCK_CLOEXEC | os.SOCK_NONBLOCK, os.PROTO_tcp);
const sockfd = try os.socket(os.AF_INET, os.SOCK_STREAM | os.SOCK_CLOEXEC | os.SOCK_NONBLOCK, os.PROTO_tcp);
errdefer os.close(sockfd);
try os.posixConnectAsync(sockfd, &address.os_addr, @sizeOf(os.sockaddr_in));
try os.connect_async(sockfd, &address.os_addr, @sizeOf(os.sockaddr_in));
try await try async loop.linuxWaitFd(sockfd, os.EPOLLIN | os.EPOLLOUT | os.EPOLLET);
try os.posixGetSockOptConnectError(sockfd);
try os.getsockoptError(sockfd);
return File.openHandle(sockfd);
}

View File

@ -38,24 +38,6 @@ pub const MAX_PATH_BYTES = switch (builtin.os) {
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 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 os.getcwd(&buf));
}
test "getCwdAlloc" {
// at least call it so it gets compiled
var buf: [1000]u8 = undefined;
const allocator = &std.heap.FixedBufferAllocator.init(&buf).allocator;
_ = getCwdAlloc(allocator) catch {};
}
// here we replace the standard +/ with -_ so that it can be used in a file name
const b64_fs_encoder = base64.Base64Encoder.init("ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789-_", base64.standard_pad_char);
@ -260,17 +242,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 {
pub fn deleteDir(dir_path: []const u8) !void {
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 {
pub fn deleteDirC(dir_path: [*]const u8) !void {
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 {
pub fn deleteDirW(dir_path: [*]const u16) !void {
return os.rmdirW(dir_path);
}
@ -362,7 +344,7 @@ pub fn deleteTree(allocator: *Allocator, full_path: []const u8) DeleteTreeError!
};
defer dir.close();
var full_entry_buf = ArrayList(u8).init(allocator);
var full_entry_buf = std.ArrayList(u8).init(allocator);
defer full_entry_buf.deinit();
while (try dir.next()) |entry| {

View File

@ -137,24 +137,27 @@ pub const File = struct {
/// Test for the existence of `path`.
/// `path` is UTF8-encoded.
pub fn exists(path: []const u8) !void {
/// In general it is recommended to avoid this function. For example,
/// instead of testing if a file exists and then opening it, just
/// open it and handle the error for file not found.
pub fn access(path: []const u8) !void {
return os.access(path, os.F_OK);
}
/// Same as `exists` except the parameter is null-terminated.
pub fn existsC(path: [*]const u8) !void {
/// Same as `access` except the parameter is null-terminated.
pub fn accessC(path: [*]const u8) !void {
return os.accessC(path, os.F_OK);
}
/// Same as `exists` except the parameter is null-terminated UTF16LE-encoded.
pub fn existsW(path: [*]const u16) !void {
/// Same as `access` except the parameter is null-terminated UTF16LE-encoded.
pub fn accessW(path: [*]const u16) !void {
return os.accessW(path, os.F_OK);
}
/// Upon success, the stream is in an uninitialized state. To continue using it,
/// you must use the open() function.
pub fn close(self: File) void {
os.close(self.handle);
return os.close(self.handle);
}
/// Test whether the file refers to a terminal.

View File

@ -9,6 +9,7 @@ const Allocator = mem.Allocator;
const math = std.math;
const windows = std.os.windows;
const fs = std.fs;
const process = std.process;
pub const sep_windows = '\\';
pub const sep_posix = '/';
@ -390,7 +391,7 @@ pub fn resolve(allocator: *Allocator, paths: []const []const u8) ![]u8 {
pub fn resolveWindows(allocator: *Allocator, paths: []const []const u8) ![]u8 {
if (paths.len == 0) {
assert(windows.is_the_target); // resolveWindows called on non windows can't use getCwd
return fs.getCwdAlloc(allocator);
return process.getCwdAlloc(allocator);
}
// determine which disk designator we will result with, if any
@ -485,7 +486,7 @@ pub fn resolveWindows(allocator: *Allocator, paths: []const []const u8) ![]u8 {
},
WindowsPath.Kind.None => {
assert(windows.is_the_target); // resolveWindows called on non windows can't use getCwd
const cwd = try fs.getCwdAlloc(allocator);
const cwd = try process.getCwdAlloc(allocator);
defer allocator.free(cwd);
const parsed_cwd = windowsParsePath(cwd);
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 {
} else {
assert(windows.is_the_target); // resolveWindows called on non windows can't use getCwd
// TODO call get cwd for the result_disk_designator instead of the global one
const cwd = try fs.getCwdAlloc(allocator);
const cwd = try process.getCwdAlloc(allocator);
defer allocator.free(cwd);
result = try allocator.alloc(u8, max_size + cwd.len + 1);
@ -571,7 +572,7 @@ pub fn resolveWindows(allocator: *Allocator, paths: []const []const u8) ![]u8 {
pub fn resolvePosix(allocator: *Allocator, paths: []const []const u8) ![]u8 {
if (paths.len == 0) {
assert(!windows.is_the_target); // resolvePosix called on windows can't use getCwd
return fs.getCwdAlloc(allocator);
return process.getCwdAlloc(allocator);
}
var first_index: usize = 0;
@ -593,7 +594,7 @@ pub fn resolvePosix(allocator: *Allocator, paths: []const []const u8) ![]u8 {
result = try allocator.alloc(u8, max_size);
} else {
assert(!windows.is_the_target); // resolvePosix called on windows can't use getCwd
const cwd = try fs.getCwdAlloc(allocator);
const cwd = try process.getCwdAlloc(allocator);
defer allocator.free(cwd);
result = try allocator.alloc(u8, max_size + cwd.len + 1);
mem.copy(u8, result, cwd);
@ -632,7 +633,7 @@ pub fn resolvePosix(allocator: *Allocator, paths: []const []const u8) ![]u8 {
}
test "resolve" {
const cwd = try fs.getCwdAlloc(debug.global_allocator);
const cwd = try process.getCwdAlloc(debug.global_allocator);
if (windows.is_the_target) {
if (windowsParsePath(cwd).kind == WindowsPath.Kind.Drive) {
cwd[0] = asciiUpper(cwd[0]);
@ -646,7 +647,7 @@ test "resolve" {
test "resolveWindows" {
if (windows.is_the_target) {
const cwd = try fs.getCwdAlloc(debug.global_allocator);
const cwd = try process.getCwdAlloc(debug.global_allocator);
const parsed_cwd = windowsParsePath(cwd);
{
const result = testResolveWindows([][]const u8{ "/usr/local", "lib\\zig\\std\\array_list.zig" });

View File

@ -112,7 +112,7 @@ pub const DirectAllocator = struct {
-1,
0,
) catch return error.OutOfMemory;
if (alloc_size == n) return slice;
if (alloc_size == n) return slice[0..n];
const aligned_addr = mem.alignForward(@ptrToInt(slice.ptr), alignment);

View File

@ -7,7 +7,7 @@ const DefaultPrng = std.rand.DefaultPrng;
const expect = std.testing.expect;
const expectError = std.testing.expectError;
const mem = std.mem;
const os = std.os;
const fs = std.fs;
const File = std.fs.File;
test "write a file, read it, then delete it" {
@ -58,7 +58,7 @@ test "write a file, read it, then delete it" {
expect(mem.eql(u8, contents["begin".len .. contents.len - "end".len], data));
expect(mem.eql(u8, contents[contents.len - "end".len ..], "end"));
}
try os.deleteFile(tmp_file_name);
try fs.deleteFile(tmp_file_name);
}
test "BufferOutStream" {
@ -316,7 +316,7 @@ test "BitStreams with File Stream" {
expectError(error.EndOfStream, bit_stream.readBitsNoEof(u1, 1));
}
try os.deleteFile(tmp_file_name);
try fs.deleteFile(tmp_file_name);
}
fn testIntSerializerDeserializer(comptime endian: builtin.Endian, comptime packing: io.Packing) !void {
@ -596,7 +596,7 @@ test "c out stream" {
const filename = c"tmp_io_test_file.txt";
const out_file = std.c.fopen(filename, c"w") orelse return error.UnableToOpenTestFile;
defer std.os.deleteFileC(filename) catch {};
defer fs.deleteFileC(filename) catch {};
const out_stream = &io.COutStream.init(out_file).stream;
try out_stream.print("hi: {}\n", i32(123));

View File

@ -284,7 +284,7 @@ pub fn read(fd: fd_t, buf: []u8) ReadError!usize {
/// Number of bytes read is returned. Upon reading end-of-file, zero is returned.
/// This function is for blocking file descriptors only. For non-blocking, see
/// `preadvAsync`.
pub fn preadv(fd: fd_t, iov: [*]const iovec, count: usize, offset: u64) ReadError!usize {
pub fn preadv(fd: fd_t, iov: []const iovec, offset: u64) ReadError!usize {
if (darwin.is_the_target) {
// Darwin does not have preadv but it does have pread.
var off: usize = 0;
@ -301,7 +301,7 @@ pub fn preadv(fd: fd_t, iov: [*]const iovec, count: usize, offset: u64) ReadErro
if (inner_off == v.iov_len) {
iov_i += 1;
inner_off = 0;
if (iov_i == count) {
if (iov_i == iov.len) {
return off;
}
}
@ -323,9 +323,10 @@ pub fn preadv(fd: fd_t, iov: [*]const iovec, count: usize, offset: u64) ReadErro
}
}
while (true) {
const rc = system.preadv(fd, iov, count, offset);
// TODO handle the case when iov_len is too large and get rid of this @intCast
const rc = system.preadv(fd, iov.ptr, @intCast(u32, iov.len), offset);
switch (errno(rc)) {
0 => return rc,
0 => return @bitCast(usize, rc),
EINTR => continue,
EINVAL => unreachable,
EFAULT => unreachable,
@ -407,7 +408,7 @@ pub fn write(fd: fd_t, bytes: []const u8) WriteError!void {
/// Write multiple buffers to a file descriptor. Keeps trying if it gets interrupted.
/// This function is for blocking file descriptors only. For non-blocking, see
/// `pwritevAsync`.
pub fn pwritev(fd: fd_t, iov: [*]const iovec_const, count: usize, offset: u64) WriteError!void {
pub fn pwritev(fd: fd_t, iov: []const iovec_const, offset: u64) WriteError!void {
if (darwin.is_the_target) {
// Darwin does not have pwritev but it does have pwrite.
var off: usize = 0;
@ -424,7 +425,7 @@ pub fn pwritev(fd: fd_t, iov: [*]const iovec_const, count: usize, offset: u64) W
if (inner_off == v.iov_len) {
iov_i += 1;
inner_off = 0;
if (iov_i == count) {
if (iov_i == iov.len) {
return;
}
}
@ -449,7 +450,8 @@ pub fn pwritev(fd: fd_t, iov: [*]const iovec_const, count: usize, offset: u64) W
}
while (true) {
const rc = system.pwritev(fd, iov, count, offset);
// TODO handle the case when iov_len is too large and get rid of this @intCast
const rc = system.pwritev(fd, iov.ptr, @intCast(u32, iov.len), offset);
switch (errno(rc)) {
0 => return,
EINTR => continue,
@ -724,7 +726,7 @@ pub fn getcwd(out_buffer: []u8) GetCwdError![]u8 {
EINVAL => unreachable,
ENOENT => return error.CurrentWorkingDirectoryUnlinked,
ERANGE => return error.NameTooLong,
else => return unexpectedErrno(err),
else => return unexpectedErrno(@intCast(usize, err)),
}
}
@ -1121,7 +1123,7 @@ pub fn readlinkC(file_path: [*]const u8, out_buffer: []u8) ReadLinkError![]u8 {
}
const rc = system.readlink(file_path, out_buffer.ptr, out_buffer.len);
switch (errno(rc)) {
0 => return out_buffer[0..rc],
0 => return out_buffer[0..@bitCast(usize, rc)],
EACCES => return error.AccessDenied,
EFAULT => unreachable,
EINVAL => unreachable,
@ -1307,7 +1309,7 @@ pub const BindError = error{
/// addr is `*const T` where T is one of the sockaddr
pub fn bind(fd: i32, addr: *const sockaddr) BindError!void {
const rc = system.bind(fd, system, @sizeOf(sockaddr));
const rc = system.bind(fd, addr, @sizeOf(sockaddr));
switch (errno(rc)) {
0 => return,
EACCES => return error.AccessDenied,
@ -1521,7 +1523,7 @@ pub fn epoll_wait(epfd: i32, events: []epoll_event, timeout: i32) usize {
// TODO get rid of the @intCast
const rc = system.epoll_wait(epfd, events.ptr, @intCast(u32, events.len), timeout);
switch (errno(rc)) {
0 => return rc,
0 => return @intCast(usize, rc),
EINTR => continue,
EBADF => unreachable,
EFAULT => unreachable,
@ -1613,12 +1615,10 @@ pub const ConnectError = error{
/// Initiate a connection on a socket.
/// This is for blocking file descriptors only.
/// For non-blocking, see `connect_async`.
pub fn connect(sockfd: i32, sockaddr: *const sockaddr) ConnectError!void {
pub fn connect(sockfd: i32, sock_addr: *sockaddr, len: socklen_t) ConnectError!void {
while (true) {
switch (errno(system.connect(sockfd, sockaddr, @sizeOf(sockaddr)))) {
switch (errno(system.connect(sockfd, sock_addr, @sizeOf(sockaddr)))) {
0 => return,
else => |err| return unexpectedErrno(err),
EACCES => return error.PermissionDenied,
EPERM => return error.PermissionDenied,
EADDRINUSE => return error.AddressInUse,
@ -1636,19 +1636,18 @@ pub fn connect(sockfd: i32, sockaddr: *const sockaddr) ConnectError!void {
ENOTSOCK => unreachable, // The file descriptor sockfd does not refer to a socket.
EPROTOTYPE => unreachable, // The socket type does not support the requested communications protocol.
ETIMEDOUT => return error.ConnectionTimedOut,
else => |err| return unexpectedErrno(err),
}
}
}
/// Same as `connect` except it is for blocking socket file descriptors.
/// It expects to receive EINPROGRESS`.
pub fn connect_async(sockfd: i32, sockaddr: *const c_void, len: u32) ConnectError!void {
pub fn connect_async(sockfd: i32, sock_addr: *sockaddr, len: socklen_t) ConnectError!void {
while (true) {
switch (errno(system.connect(sockfd, sockaddr, len))) {
0, EINPROGRESS => return,
switch (errno(system.connect(sockfd, sock_addr, @sizeOf(sockaddr)))) {
EINTR => continue,
else => |err| return unexpectedErrno(err),
0, EINPROGRESS => return,
EACCES => return error.PermissionDenied,
EPERM => return error.PermissionDenied,
EADDRINUSE => return error.AddressInUse,
@ -1664,13 +1663,14 @@ pub fn connect_async(sockfd: i32, sockaddr: *const c_void, len: u32) ConnectErro
ENOTSOCK => unreachable, // The file descriptor sockfd does not refer to a socket.
EPROTOTYPE => unreachable, // The socket type does not support the requested communications protocol.
ETIMEDOUT => return error.ConnectionTimedOut,
else => |err| return unexpectedErrno(err),
}
}
}
pub fn getsockoptError(sockfd: i32) ConnectError!void {
var err_code: i32 = undefined;
var size: u32 = @sizeOf(i32);
var err_code: u32 = undefined;
var size: u32 = @sizeOf(u32);
const rc = system.getsockopt(sockfd, SOL_SOCKET, SO_ERROR, @ptrCast([*]u8, &err_code), &size);
assert(size == 4);
switch (errno(rc)) {
@ -1702,11 +1702,13 @@ pub fn getsockoptError(sockfd: i32) ConnectError!void {
}
}
pub fn waitpid(pid: i32, flags: u32) i32 {
var status: i32 = undefined;
pub fn waitpid(pid: i32, flags: u32) u32 {
// TODO allow implicit pointer cast from *u32 to *c_uint ?
const Status = if (builtin.link_libc) c_uint else u32;
var status: Status = undefined;
while (true) {
switch (errno(system.waitpid(pid, &status, flags))) {
0 => return status,
0 => return @bitCast(u32, status),
EINTR => continue,
ECHILD => unreachable, // The process specified does not exist. It would be a race condition to handle this error.
EINVAL => unreachable, // The options argument was invalid
@ -1892,11 +1894,19 @@ pub fn fork() ForkError!pid_t {
}
pub const MMapError = error{
/// The underlying filesystem of the specified file does not support memory mapping.
MemoryMappingNotSupported,
/// A file descriptor refers to a non-regular file. Or a file mapping was requested,
/// but the file descriptor is not open for reading. Or `MAP_SHARED` was requested
/// and `PROT_WRITE` is set, but the file descriptor is not open in `O_RDWR` mode.
/// Or `PROT_WRITE` is set, but the file is append-only.
AccessDenied,
/// The `prot` argument asks for `PROT_EXEC` but the mapped area belongs to a file on
/// a filesystem that was mounted no-exec.
PermissionDenied,
LockedMemoryLimitExceeded,
SystemFdQuotaExceeded,
MemoryMappingNotSupported,
OutOfMemory,
Unexpected,
};
@ -1932,7 +1942,6 @@ pub fn mmap(
EAGAIN => return error.LockedMemoryLimitExceeded,
EBADF => unreachable, // Always a race condition.
EOVERFLOW => unreachable, // The number of pages used for length + offset would overflow.
ENFILE => return error.SystemFdQuotaExceeded,
ENODEV => return error.MemoryMappingNotSupported,
EINVAL => unreachable, // Invalid parameters to mmap()
ENOMEM => return error.OutOfMemory,
@ -2265,7 +2274,7 @@ pub fn realpathC(pathname: [*]const u8, out_buffer: *[MAX_PATH_BYTES]u8) RealPat
ENAMETOOLONG => return error.NameTooLong,
ELOOP => return error.SymLinkLoop,
EIO => return error.InputOutput,
else => |err| return unexpectedErrno(err),
else => |err| return unexpectedErrno(@intCast(usize, err)),
};
return mem.toSlice(u8, result_path);
}
@ -2349,7 +2358,7 @@ pub fn clock_gettime(clk_id: i32, tp: *timespec) ClockGetTimeError!void {
}
pub fn clock_getres(clk_id: i32, res: *timespec) ClockGetTimeError!void {
switch (errno(system.clock_getres(clk_id, tp))) {
switch (errno(system.clock_getres(clk_id, res))) {
0 => return,
EFAULT => unreachable,
EINVAL => return error.UnsupportedClock,
@ -2364,7 +2373,7 @@ pub const SchedGetAffinityError = error{
pub fn sched_getaffinity(pid: pid_t) SchedGetAffinityError!cpu_set_t {
var set: cpu_set_t = undefined;
switch (errno(system.sched_getaffinity(pid, &set))) {
switch (errno(system.sched_getaffinity(pid, @sizeOf(cpu_set_t), &set))) {
0 => return set,
EFAULT => unreachable,
EINVAL => unreachable,

View File

@ -219,7 +219,7 @@ pub const MAP_NOCACHE = 0x0400;
/// don't reserve needed swap area
pub const MAP_NORESERVE = 0x0040;
pub const MAP_FAILED = maxInt(usize);
pub const MAP_FAILED = @intToPtr(*c_void, maxInt(usize));
/// [XSI] no hang in wait/no child to reap
pub const WNOHANG = 0x00000001;
@ -749,26 +749,26 @@ pub const IPPROTO_UDP = 17;
pub const IPPROTO_IP = 0;
pub const IPPROTO_IPV6 = 41;
fn wstatus(x: i32) i32 {
fn wstatus(x: u32) u32 {
return x & 0o177;
}
const wstopped = 0o177;
pub fn WEXITSTATUS(x: i32) i32 {
pub fn WEXITSTATUS(x: u32) u32 {
return x >> 8;
}
pub fn WTERMSIG(x: i32) i32 {
pub fn WTERMSIG(x: u32) u32 {
return wstatus(x);
}
pub fn WSTOPSIG(x: i32) i32 {
pub fn WSTOPSIG(x: u32) u32 {
return x >> 8;
}
pub fn WIFEXITED(x: i32) bool {
pub fn WIFEXITED(x: u32) bool {
return wstatus(x) == 0;
}
pub fn WIFSTOPPED(x: i32) bool {
pub fn WIFSTOPPED(x: u32) bool {
return wstatus(x) == wstopped and WSTOPSIG(x) != 0x13;
}
pub fn WIFSIGNALED(x: i32) bool {
pub fn WIFSIGNALED(x: u32) bool {
return wstatus(x) != wstopped and wstatus(x) != 0;
}

View File

@ -161,7 +161,7 @@ pub const CLOCK_SECOND = 13;
pub const CLOCK_THREAD_CPUTIME_ID = 14;
pub const CLOCK_PROCESS_CPUTIME_ID = 15;
pub const MAP_FAILED = maxInt(usize);
pub const MAP_FAILED = @intToPtr(*c_void, maxInt(usize));
pub const MAP_SHARED = 0x0001;
pub const MAP_PRIVATE = 0x0002;
pub const MAP_FIXED = 0x0010;
@ -644,29 +644,23 @@ pub const TIOCGPKT = 0x80045438;
pub const TIOCGPTLCK = 0x80045439;
pub const TIOCGEXCL = 0x80045440;
fn unsigned(s: i32) u32 {
return @bitCast(u32, s);
pub fn WEXITSTATUS(s: u32) u32 {
return (s & 0xff00) >> 8;
}
fn signed(s: u32) i32 {
return @bitCast(i32, s);
pub fn WTERMSIG(s: u32) u32 {
return s & 0x7f;
}
pub fn WEXITSTATUS(s: i32) i32 {
return signed((unsigned(s) & 0xff00) >> 8);
}
pub fn WTERMSIG(s: i32) i32 {
return signed(unsigned(s) & 0x7f);
}
pub fn WSTOPSIG(s: i32) i32 {
pub fn WSTOPSIG(s: u32) u32 {
return WEXITSTATUS(s);
}
pub fn WIFEXITED(s: i32) bool {
pub fn WIFEXITED(s: u32) bool {
return WTERMSIG(s) == 0;
}
pub fn WIFSTOPPED(s: i32) bool {
return @intCast(u16, (((unsigned(s) & 0xffff) *% 0x10001) >> 8)) > 0x7f00;
pub fn WIFSTOPPED(s: u32) bool {
return @intCast(u16, (((s & 0xffff) *% 0x10001) >> 8)) > 0x7f00;
}
pub fn WIFSIGNALED(s: i32) bool {
return (unsigned(s) & 0xffff) -% 1 < 0xff;
pub fn WIFSIGNALED(s: u32) bool {
return (s & 0xffff) -% 1 < 0xff;
}
pub const winsize = extern struct {

View File

@ -1,5 +1,7 @@
const builtin = @import("builtin");
const std = @import("../../std.zig");
const maxInt = std.math.maxInt;
use @import("../bits.zig");
pub use @import("linux/errno.zig");
pub use switch (builtin.arch) {
@ -661,29 +663,23 @@ pub const TFD_CLOEXEC = O_CLOEXEC;
pub const TFD_TIMER_ABSTIME = 1;
pub const TFD_TIMER_CANCEL_ON_SET = (1 << 1);
fn unsigned(s: i32) u32 {
return @bitCast(u32, s);
pub fn WEXITSTATUS(s: u32) u32 {
return (s & 0xff00) >> 8;
}
fn signed(s: u32) i32 {
return @bitCast(i32, s);
pub fn WTERMSIG(s: u32) u32 {
return s & 0x7f;
}
pub fn WEXITSTATUS(s: i32) i32 {
return signed((unsigned(s) & 0xff00) >> 8);
}
pub fn WTERMSIG(s: i32) i32 {
return signed(unsigned(s) & 0x7f);
}
pub fn WSTOPSIG(s: i32) i32 {
pub fn WSTOPSIG(s: u32) u32 {
return WEXITSTATUS(s);
}
pub fn WIFEXITED(s: i32) bool {
pub fn WIFEXITED(s: u32) bool {
return WTERMSIG(s) == 0;
}
pub fn WIFSTOPPED(s: i32) bool {
return @intCast(u16, ((unsigned(s) & 0xffff) *% 0x10001) >> 8) > 0x7f00;
pub fn WIFSTOPPED(s: u32) bool {
return @intCast(u16, ((s & 0xffff) *% 0x10001) >> 8) > 0x7f00;
}
pub fn WIFSIGNALED(s: i32) bool {
return (unsigned(s) & 0xffff) -% 1 < 0xff;
pub fn WIFSIGNALED(s: u32) bool {
return (s & 0xffff) -% 1 < 0xff;
}
pub const winsize = extern struct {
@ -902,7 +898,7 @@ pub const dirent64 = extern struct {
pub const dl_phdr_info = extern struct {
dlpi_addr: usize,
dlpi_name: ?[*]const u8,
dlpi_phdr: [*]elf.Phdr,
dlpi_phdr: [*]std.elf.Phdr,
dlpi_phnum: u16,
};

View File

@ -152,7 +152,7 @@ pub const CLOCK_MONOTONIC = 3;
pub const CLOCK_THREAD_CPUTIME_ID = 0x20000000;
pub const CLOCK_PROCESS_CPUTIME_ID = 0x40000000;
pub const MAP_FAILED = maxInt(usize);
pub const MAP_FAILED = @intToPtr(*c_void, maxInt(usize));
pub const MAP_SHARED = 0x0001;
pub const MAP_PRIVATE = 0x0002;
pub const MAP_REMAPDUP = 0x0004;
@ -516,34 +516,28 @@ pub const TIOCSWINSZ = 0x80087467;
pub const TIOCUCNTL = 0x80047466;
pub const TIOCXMTFRAME = 0x80087444;
fn unsigned(s: i32) u32 {
return @bitCast(u32, s);
pub fn WEXITSTATUS(s: u32) u32 {
return (s >> 8) & 0xff;
}
fn signed(s: u32) i32 {
return @bitCast(i32, s);
pub fn WTERMSIG(s: u32) u32 {
return s & 0x7f;
}
pub fn WEXITSTATUS(s: i32) i32 {
return signed((unsigned(s) >> 8) & 0xff);
}
pub fn WTERMSIG(s: i32) i32 {
return signed(unsigned(s) & 0x7f);
}
pub fn WSTOPSIG(s: i32) i32 {
pub fn WSTOPSIG(s: u32) u32 {
return WEXITSTATUS(s);
}
pub fn WIFEXITED(s: i32) bool {
pub fn WIFEXITED(s: u32) bool {
return WTERMSIG(s) == 0;
}
pub fn WIFCONTINUED(s: i32) bool {
pub fn WIFCONTINUED(s: u32) bool {
return ((s & 0x7f) == 0xffff);
}
pub fn WIFSTOPPED(s: i32) bool {
pub fn WIFSTOPPED(s: u32) bool {
return ((s & 0x7f != 0x7f) and !WIFCONTINUED(s));
}
pub fn WIFSIGNALED(s: i32) bool {
pub fn WIFSIGNALED(s: u32) bool {
return !WIFSTOPPED(s) and !WIFCONTINUED(s) and !WIFEXITED(s);
}

View File

@ -382,7 +382,7 @@ pub fn unlinkat(dirfd: i32, path: [*]const u8, flags: u32) usize {
return syscall3(SYS_unlinkat, @bitCast(usize, isize(dirfd)), @ptrToInt(path), flags);
}
pub fn waitpid(pid: i32, status: *i32, flags: u32) usize {
pub fn waitpid(pid: i32, status: *u32, flags: u32) usize {
return syscall4(SYS_wait4, @bitCast(usize, isize(pid)), @ptrToInt(status), flags, 0);
}

View File

@ -11,7 +11,7 @@ test "getpid" {
test "timer" {
const epoll_fd = linux.epoll_create();
var err = linux.getErrno(epoll_fd);
var err: usize = linux.getErrno(epoll_fd);
expect(err == 0);
const timer_fd = linux.timerfd_create(linux.CLOCK_MONOTONIC, 0);

View File

@ -5,7 +5,7 @@ const mem = std.mem;
const maxInt = std.math.maxInt;
pub fn lookup(vername: []const u8, name: []const u8) usize {
const vdso_addr = std.os.linuxGetAuxVal(std.elf.AT_SYSINFO_EHDR);
const vdso_addr = std.os.system.getauxval(std.elf.AT_SYSINFO_EHDR);
if (vdso_addr == 0) return 0;
const eh = @intToPtr(*elf.Ehdr, vdso_addr);

View File

@ -15,11 +15,11 @@ const AtomicRmwOp = builtin.AtomicRmwOp;
const AtomicOrder = builtin.AtomicOrder;
test "makePath, put some files in it, deleteTree" {
try os.makePath(a, "os_test_tmp" ++ fs.path.sep_str ++ "b" ++ fs.path.sep_str ++ "c");
try fs.makePath(a, "os_test_tmp" ++ fs.path.sep_str ++ "b" ++ fs.path.sep_str ++ "c");
try io.writeFile("os_test_tmp" ++ fs.path.sep_str ++ "b" ++ fs.path.sep_str ++ "c" ++ fs.path.sep_str ++ "file.txt", "nonsense");
try io.writeFile("os_test_tmp" ++ fs.path.sep_str ++ "b" ++ fs.path.sep_str ++ "file2.txt", "blah");
try os.deleteTree(a, "os_test_tmp");
if (os.Dir.open(a, "os_test_tmp")) |dir| {
try fs.deleteTree(a, "os_test_tmp");
if (fs.Dir.open(a, "os_test_tmp")) |dir| {
@panic("expected error");
} else |err| {
expect(err == error.FileNotFound);
@ -27,7 +27,7 @@ test "makePath, put some files in it, deleteTree" {
}
test "access file" {
try os.makePath(a, "os_test_tmp");
try fs.makePath(a, "os_test_tmp");
if (File.access("os_test_tmp" ++ fs.path.sep_str ++ "file.txt")) |ok| {
@panic("expected error");
} else |err| {
@ -35,8 +35,8 @@ test "access file" {
}
try io.writeFile("os_test_tmp" ++ fs.path.sep_str ++ "file.txt", "");
try File.access("os_test_tmp" ++ fs.path.sep_str ++ "file.txt");
try os.deleteTree(a, "os_test_tmp");
try os.access("os_test_tmp" ++ fs.path.sep_str ++ "file.txt", os.F_OK);
try fs.deleteTree(a, "os_test_tmp");
}
fn testThreadIdFn(thread_id: *Thread.Id) void {
@ -52,15 +52,12 @@ test "std.Thread.getCurrentId" {
thread.wait();
if (Thread.use_pthreads) {
expect(thread_current_id == thread_id);
} else if (os.windows.is_the_target) {
expect(Thread.getCurrentId() != thread_current_id);
} else {
switch (builtin.os) {
builtin.Os.windows => expect(Thread.getCurrentId() != thread_current_id),
else => {
// If the thread completes very quickly, then thread_id can be 0. See the
// documentation comments for `std.Thread.handle`.
expect(thread_id == 0 or thread_current_id == thread_id);
},
}
// If the thread completes very quickly, then thread_id can be 0. See the
// documentation comments for `std.Thread.handle`.
expect(thread_id == 0 or thread_current_id == thread_id);
}
}
@ -92,7 +89,7 @@ fn start2(ctx: *i32) u8 {
}
test "cpu count" {
const cpu_count = try std.os.cpuCount(a);
const cpu_count = try Thread.cpuCount();
expect(cpu_count >= 1);
}
@ -105,7 +102,7 @@ test "AtomicFile" {
\\ this is a test file
;
{
var af = try os.AtomicFile.init(test_out_file, File.default_mode);
var af = try fs.AtomicFile.init(test_out_file, File.default_mode);
defer af.deinit();
try af.file.write(test_content);
try af.finish();
@ -113,7 +110,7 @@ test "AtomicFile" {
const content = try io.readFileAlloc(allocator, test_out_file);
expect(mem.eql(u8, content, test_content));
try os.deleteFile(test_out_file);
try fs.deleteFile(test_out_file);
}
test "thread local storage" {
@ -145,10 +142,10 @@ test "getrandom" {
test "getcwd" {
// at least call it so it gets compiled
var buf: [std.fs.MAX_PATH_BYTES]u8 = undefined;
_ = os.getcwd(&buf) catch {};
_ = os.getcwd(&buf) catch undefined;
}
test "realpath" {
var buf: [std.fs.MAX_PATH_BYTES]u8 = undefined;
testing.expectError(error.FileNotFound, os.realpath("definitely_bogus_does_not_exist1234", &buf));
testing.expectError(error.FileNotFound, fs.realpath("definitely_bogus_does_not_exist1234", &buf));
}

View File

@ -1180,6 +1180,44 @@ pub fn CreateProcessW(
}
}
pub const LoadLibraryError = error{
FileNotFound,
Unexpected,
};
pub fn LoadLibraryW(lpLibFileName: [*]const u16) LoadLibraryError!HMODULE {
return kernel32.LoadLibraryW(lpLibFileName) orelse {
switch (kernel32.GetLastError()) {
ERROR.FILE_NOT_FOUND => return error.FileNotFound,
ERROR.PATH_NOT_FOUND => return error.FileNotFound,
ERROR.MOD_NOT_FOUND => return error.FileNotFound,
else => |err| return unexpectedError(err),
}
};
}
pub fn FreeLibrary(hModule: HMODULE) void {
assert(kernel32.FreeLibrary(hModule) != 0);
}
pub fn QueryPerformanceFrequency() u64 {
// "On systems that run Windows XP or later, the function will always succeed"
// https://docs.microsoft.com/en-us/windows/desktop/api/profileapi/nf-profileapi-queryperformancefrequency
var result: LARGE_INTEGER = undefined;
assert(kernel32.QueryPerformanceFrequency(&result) != 0);
// The kernel treats this integer as unsigned.
return @bitCast(u64, result);
}
pub fn QueryPerformanceCounter() u64 {
// "On systems that run Windows XP or later, the function will always succeed"
// https://docs.microsoft.com/en-us/windows/desktop/api/profileapi/nf-profileapi-queryperformancecounter
var result: LARGE_INTEGER = undefined;
assert(kernel32.QueryPerformanceCounter(&result) != 0);
// The kernel treats this integer as unsigned.
return @bitCast(u64, result);
}
pub fn cStrToPrefixedFileW(s: [*]const u8) ![PATH_MAX_WIDE + 1]u16 {
return sliceToPrefixedFileW(mem.toSliceConst(u8, s));
}

View File

@ -80,7 +80,7 @@ pub const STDOUT_FILENO = 1;
pub const STDERR_FILENO = 2;
// FIXME: let's borrow Linux's error numbers for now.
use @import("../bits/linux/errno.zig");
use @import("bits/linux/errno.zig");
// Get the errno from a syscall return value, or 0 for no error.
pub fn getErrno(r: usize) usize {
const signed_r = @bitCast(isize, r);

View File

@ -1,7 +1,9 @@
const builtin = @import("builtin");
const std = @import("std.zig");
const os = std.os;
const fs = std.fs;
const BufMap = std.BufMap;
const Buffer = std.Buffer;
const mem = std.mem;
const math = std.math;
const Allocator = mem.Allocator;
@ -13,6 +15,24 @@ pub const exit = os.exit;
pub const changeCurDir = os.chdir;
pub const changeCurDirC = os.chdirC;
/// The result is a slice of `out_buffer`, from index `0`.
pub fn getCwd(out_buffer: *[fs.MAX_PATH_BYTES]u8) ![]u8 {
return os.getcwd(out_buffer);
}
/// Caller must free the returned memory.
pub fn getCwdAlloc(allocator: *Allocator) ![]u8 {
var buf: [fs.MAX_PATH_BYTES]u8 = undefined;
return mem.dupe(allocator, u8, try os.getcwd(&buf));
}
test "getCwdAlloc" {
// at least call it so it gets compiled
var buf: [1000]u8 = undefined;
const allocator = &std.heap.FixedBufferAllocator.init(&buf).allocator;
_ = getCwdAlloc(allocator) catch undefined;
}
/// Caller must free result when done.
/// TODO make this go through libc when we have it
pub fn getEnvMap(allocator: *Allocator) !BufMap {
@ -402,7 +422,7 @@ pub fn argsAlloc(allocator: *mem.Allocator) ![]const []u8 {
var contents = try Buffer.initSize(allocator, 0);
defer contents.deinit();
var slice_list = ArrayList(usize).init(allocator);
var slice_list = std.ArrayList(usize).init(allocator);
defer slice_list.deinit();
while (it.next(allocator)) |arg_or_err| {

View File

@ -1,8 +1,10 @@
const builtin = @import("builtin");
const std = @import("std.zig");
const os = std.os;
const mem = std.mem;
const windows = std.os.windows;
const c = std.c;
const assert = std.debug.assert;
pub const Thread = struct {
data: Data,
@ -31,14 +33,12 @@ pub const Thread = struct {
pub const Data = if (use_pthreads)
struct {
handle: Thread.Handle,
mmap_addr: usize,
mmap_len: usize,
memory: []align(mem.page_size) u8,
}
else switch (builtin.os) {
.linux => struct {
handle: Thread.Handle,
mmap_addr: usize,
mmap_len: usize,
memory: []align(mem.page_size) u8,
},
.windows => struct {
handle: Thread.Handle,
@ -56,7 +56,7 @@ pub const Thread = struct {
return c.pthread_self();
} else
return switch (builtin.os) {
.linux => linux.gettid(),
.linux => os.linux.gettid(),
.windows => windows.GetCurrentThreadId(),
else => @compileError("Unsupported OS"),
};
@ -82,21 +82,21 @@ pub const Thread = struct {
os.EDEADLK => unreachable,
else => unreachable,
}
os.munmap(self.data.mmap_addr, self.data.mmap_len);
os.munmap(self.data.memory);
} else switch (builtin.os) {
.linux => {
while (true) {
const pid_value = @atomicLoad(i32, &self.data.handle, .SeqCst);
if (pid_value == 0) break;
const rc = linux.futex_wait(&self.data.handle, linux.FUTEX_WAIT, pid_value, null);
switch (linux.getErrno(rc)) {
const rc = os.linux.futex_wait(&self.data.handle, os.linux.FUTEX_WAIT, pid_value, null);
switch (os.linux.getErrno(rc)) {
0 => continue,
os.EINTR => continue,
os.EAGAIN => continue,
else => unreachable,
}
}
os.munmap(self.data.mmap_addr, self.data.mmap_len);
os.munmap(self.data.memory);
},
.windows => {
assert(windows.WaitForSingleObject(self.data.handle, windows.INFINITE) == windows.WAIT_OBJECT_0);
@ -130,6 +130,10 @@ pub const Thread = struct {
/// Not enough userland memory to spawn the thread.
OutOfMemory,
/// `mlockall` is enabled, and the memory needed to spawn the thread
/// would exceed the limit.
LockedMemoryLimitExceeded,
Unexpected,
};
@ -219,7 +223,7 @@ pub const Thread = struct {
}
};
const MAP_GROWSDOWN = if (builtin.os == .linux) linux.MAP_GROWSDOWN else 0;
const MAP_GROWSDOWN = if (os.linux.is_the_target) os.linux.MAP_GROWSDOWN else 0;
var stack_end_offset: usize = undefined;
var thread_start_offset: usize = undefined;
@ -241,7 +245,7 @@ pub const Thread = struct {
}
// Finally, the Thread Local Storage, if any.
if (!Thread.use_pthreads) {
if (linux.tls.tls_image) |tls_img| {
if (os.linux.tls.tls_image) |tls_img| {
l = mem.alignForward(l, @alignOf(usize));
tls_start_offset = l;
l += tls_img.alloc_size;
@ -249,12 +253,24 @@ pub const Thread = struct {
}
break :blk l;
};
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);
errdefer os.munmap(mmap_addr, mmap_len);
const mmap_slice = os.mmap(
null,
mem.alignForward(mmap_len, mem.page_size),
os.PROT_READ | os.PROT_WRITE,
os.MAP_PRIVATE | os.MAP_ANONYMOUS | MAP_GROWSDOWN,
-1,
0,
) catch |err| switch (err) {
error.MemoryMappingNotSupported => unreachable, // no file descriptor
error.AccessDenied => unreachable, // no file descriptor
error.PermissionDenied => unreachable, // no file descriptor
else => |e| return e,
};
errdefer os.munmap(mmap_slice);
const mmap_addr = @ptrToInt(mmap_slice.ptr);
const thread_ptr = @alignCast(@alignOf(Thread), @intToPtr(*Thread, mmap_addr + thread_start_offset));
thread_ptr.data.mmap_addr = mmap_addr;
thread_ptr.data.mmap_len = mmap_len;
thread_ptr.data.memory = mmap_slice;
var arg: usize = undefined;
if (@sizeOf(Context) != 0) {
@ -269,7 +285,7 @@ pub const Thread = struct {
if (c.pthread_attr_init(&attr) != 0) return error.SystemResources;
defer assert(c.pthread_attr_destroy(&attr) == 0);
assert(c.pthread_attr_setstack(&attr, @intToPtr(*c_void, mmap_addr), stack_end_offset) == 0);
assert(c.pthread_attr_setstack(&attr, mmap_slice.ptr, stack_end_offset) == 0);
const err = c.pthread_create(&thread_ptr.data.handle, &attr, MainFuncs.posixThreadMain, @intToPtr(*c_void, arg));
switch (err) {
@ -279,13 +295,13 @@ pub const Thread = struct {
os.EINVAL => unreachable,
else => return os.unexpectedErrno(@intCast(usize, err)),
}
} else if (builtin.os == .linux) {
} else if (os.linux.is_the_target) {
var flags: u32 = os.CLONE_VM | os.CLONE_FS | os.CLONE_FILES | os.CLONE_SIGHAND |
os.CLONE_THREAD | os.CLONE_SYSVSEM | os.CLONE_PARENT_SETTID | os.CLONE_CHILD_CLEARTID |
os.CLONE_DETACHED;
var newtls: usize = undefined;
if (linux.tls.tls_image) |tls_img| {
newtls = linux.tls.copyTLS(mmap_addr + tls_start_offset);
if (os.linux.tls.tls_image) |tls_img| {
newtls = os.linux.tls.copyTLS(mmap_addr + tls_start_offset);
flags |= os.CLONE_SETTLS;
}
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 {
pub fn cpuCount() CpuCountError!usize {
if (os.linux.is_the_target) {
const cpu_set = try os.sched_getaffinity(0);
return os.CPU_COUNT(cpu_set);
return usize(os.CPU_COUNT(cpu_set)); // TODO should not need this usize cast
}
if (os.windows.is_the_target) {
var system_info: windows.SYSTEM_INFO = undefined;

View File

@ -95,7 +95,7 @@ pub const Timer = struct {
/// be less precise
frequency: switch (builtin.os) {
.windows => u64,
.macosx, .ios, .tvos, .watchos => darwin.mach_timebase_info_data,
.macosx, .ios, .tvos, .watchos => os.darwin.mach_timebase_info_data,
else => void,
},
resolution: u64,
@ -119,20 +119,13 @@ pub const Timer = struct {
var self: Timer = undefined;
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.frequency = os.windows.QueryPerformanceFrequency();
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);
self.start_time = os.windows.QueryPerformanceCounter();
} else if (os.darwin.is_the_target) {
darwin.mach_timebase_info(&self.frequency);
os.darwin.mach_timebase_info(&self.frequency);
self.resolution = @divFloor(self.frequency.numer, self.frequency.denom);
self.start_time = darwin.mach_absolute_time();
self.start_time = os.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
@ -177,13 +170,10 @@ pub const Timer = struct {
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);
return os.windows.QueryPerformanceCounter();
}
if (os.darwin.is_the_target) {
return darwin.mach_absolute_time();
return os.darwin.mach_absolute_time();
}
var ts: os.timespec = undefined;
os.clock_gettime(monotonic_clock_id, &ts) catch unreachable;

View File

@ -377,7 +377,7 @@ pub fn addCases(cases: *tests.CompareOutputContext) void {
\\ stdout.print("before\n") catch unreachable;
\\ defer stdout.print("defer1\n") catch unreachable;
\\ defer stdout.print("defer2\n") catch unreachable;
\\ var args_it = @import("std").os.args();
\\ var args_it = @import("std").process.args();
\\ if (args_it.skip() and !args_it.skip()) return;
\\ defer stdout.print("defer3\n") catch unreachable;
\\ stdout.print("after\n") catch unreachable;
@ -444,7 +444,7 @@ pub fn addCases(cases: *tests.CompareOutputContext) void {
\\const allocator = std.debug.global_allocator;
\\
\\pub fn main() !void {
\\ var args_it = os.args();
\\ var args_it = std.process.args();
\\ var stdout_file = try io.getStdOut();
\\ var stdout_adapter = stdout_file.outStream();
\\ const stdout = &stdout_adapter.stream;
@ -485,7 +485,7 @@ pub fn addCases(cases: *tests.CompareOutputContext) void {
\\const allocator = std.debug.global_allocator;
\\
\\pub fn main() !void {
\\ var args_it = os.args();
\\ var args_it = std.process.args();
\\ var stdout_file = try io.getStdOut();
\\ var stdout_adapter = stdout_file.outStream();
\\ const stdout = &stdout_adapter.stream;

View File

@ -1,6 +1,6 @@
const std = @import("std");
pub fn main() void {
const env_map = std.os.getEnvMap(std.debug.global_allocator) catch @panic("unable to get env map");
const env_map = std.process.getEnvMap(std.debug.global_allocator) catch @panic("unable to get env map");
std.testing.expect(env_map.count() == 0);
}

View File

@ -393,7 +393,7 @@ pub const CompareOutputContext = struct {
debug.panic("Unable to spawn {}: {}\n", full_exe_path, @errorName(err));
};
const expected_exit_code: i32 = 126;
const expected_exit_code: u32 = 126;
switch (term) {
.Exited => |code| {
if (code != expected_exit_code) {