Skip to content

Commit

Permalink
more progress on posix API layer
Browse files Browse the repository at this point in the history
see #2380
  • Loading branch information
andrewrk committed May 20, 2019
1 parent 65b03db commit c306803
Show file tree
Hide file tree
Showing 36 changed files with 5,430 additions and 5,948 deletions.
9 changes: 9 additions & 0 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -474,6 +474,10 @@ set(ZIG_STD_FILES
"c/linux.zig"
"c/netbsd.zig"
"c/windows.zig"
"c/posix.zig"
"c/posix/darwin.zig"
"c/posix/freebsd.zig"
"c/posix/windows.zig"
"coff.zig"
"crypto.zig"
"crypto/blake2.zig"
Expand Down Expand Up @@ -612,15 +616,20 @@ set(ZIG_STD_FILES
"os/linux.zig"
"os/linux/arm64.zig"
"os/linux/errno.zig"
"os/linux/posix.zig"
"os/linux/posix/arm64.zig"
"os/linux/posix/x86_64.zig"
"os/linux/tls.zig"
"os/linux/vdso.zig"
"os/linux/x86_64.zig"
"os/netbsd.zig"
"os/netbsd/errno.zig"
"os/path.zig"
"os/posix.zig"
"os/time.zig"
"os/uefi.zig"
"os/wasi.zig"
"os/wasi/posix.zig"
"os/windows.zig"
"os/windows/advapi32.zig"
"os/windows/errno.zig"
Expand Down
1 change: 1 addition & 0 deletions doc/langref.html.in
Original file line number Diff line number Diff line change
Expand Up @@ -9891,6 +9891,7 @@ keyword <- KEYWORD_align / KEYWORD_and / KEYWORD_allowzero / KEYWORD_anyerror
<li>Avoid local maximums.</li>
<li>Reduce the amount one must remember.</li>
<li>Minimize energy spent on coding style.</li>
<li>Resource deallocation must succeed.</li>
<li>Together we serve end users.</li>
</ul>
{#header_close#}
Expand Down
70 changes: 47 additions & 23 deletions std/c.zig
Original file line number Diff line number Diff line change
@@ -1,9 +1,10 @@
const builtin = @import("builtin");

pub const is_the_target = builtin.link_libc;
pub const posix = @import("c/posix.zig");
pub use posix;

pub use switch (builtin.os) {
.linux => @import("c/linux.zig"),
.linux => @import("os/linux/posix.zig"),
.windows => @import("c/windows.zig"),
.macosx, .ios, .tvos, .watchos => @import("c/darwin.zig"),
.freebsd => @import("c/freebsd.zig"),
Expand All @@ -21,41 +22,43 @@ pub fn getErrno(rc: var) u12 {

// TODO https://github.com/ziglang/zig/issues/265 on this whole file

pub const FILE = @OpaqueType();
pub extern "c" fn fopen(filename: [*]const u8, modes: [*]const u8) ?*FILE;
pub extern "c" fn fclose(stream: *FILE) c_int;
pub extern "c" fn fwrite(ptr: [*]const u8, size_of_type: usize, item_count: usize, stream: *FILE) usize;
pub extern "c" fn fread(ptr: [*]u8, size_of_type: usize, item_count: usize, stream: *FILE) usize;

pub extern "c" fn abort() noreturn;
pub extern "c" fn exit(code: c_int) noreturn;
pub extern "c" fn isatty(fd: c_int) c_int;
pub extern "c" fn close(fd: c_int) c_int;
pub extern "c" fn fstat(fd: c_int, buf: *Stat) c_int;
pub extern "c" fn @"fstat$INODE64"(fd: c_int, buf: *Stat) c_int;
pub extern "c" fn lseek(fd: c_int, offset: isize, whence: c_int) isize;
pub extern "c" fn isatty(fd: fd_t) c_int;
pub extern "c" fn close(fd: fd_t) c_int;
pub extern "c" fn fstat(fd: fd_t, buf: *Stat) c_int;
pub extern "c" fn @"fstat$INODE64"(fd: fd_t, buf: *Stat) c_int;
pub extern "c" fn lseek(fd: fd_t, offset: isize, whence: c_int) isize;
pub extern "c" fn open(path: [*]const u8, oflag: c_int, ...) c_int;
pub extern "c" fn raise(sig: c_int) c_int;
pub extern "c" fn read(fd: c_int, buf: *c_void, nbyte: usize) isize;
pub extern "c" fn pread(fd: c_int, buf: *c_void, nbyte: usize, offset: u64) isize;
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 stat(noalias path: [*]const u8, noalias buf: *Stat) c_int;
pub extern "c" fn write(fd: c_int, buf: *const c_void, nbyte: usize) isize;
pub extern "c" fn pwrite(fd: c_int, buf: *const c_void, nbyte: usize, offset: u64) isize;
pub extern "c" fn mmap(addr: ?*c_void, len: usize, prot: c_int, flags: c_int, fd: c_int, offset: isize) ?*c_void;
pub extern "c" fn 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;
pub extern "c" fn mmap(addr: ?*c_void, len: usize, prot: c_int, flags: c_int, fd: fd_t, offset: isize) usize;
pub extern "c" fn munmap(addr: ?*c_void, len: usize) c_int;
pub extern "c" fn unlink(path: [*]const u8) c_int;
pub extern "c" fn getcwd(buf: [*]u8, size: usize) ?[*]u8;
pub extern "c" fn waitpid(pid: c_int, stat_loc: *c_int, options: c_int) c_int;
pub extern "c" fn fork() c_int;
pub extern "c" fn access(path: [*]const u8, mode: c_uint) c_int;
pub extern "c" fn pipe(fds: *[2]c_int) c_int;
pub extern "c" fn pipe(fds: *[2]fd_t) c_int;
pub extern "c" fn pipe2(fds: *[2]fd_t, flags: u32) c_int;
pub extern "c" fn mkdir(path: [*]const u8, mode: c_uint) c_int;
pub extern "c" fn symlink(existing: [*]const u8, new: [*]const u8) c_int;
pub extern "c" fn rename(old: [*]const u8, new: [*]const u8) c_int;
pub extern "c" fn chdir(path: [*]const u8) c_int;
pub extern "c" fn execve(path: [*]const u8, argv: [*]const ?[*]const u8, envp: [*]const ?[*]const u8) c_int;
pub extern "c" fn dup(fd: c_int) c_int;
pub extern "c" fn dup2(old_fd: c_int, new_fd: c_int) c_int;
pub extern "c" fn dup(fd: fd_t) c_int;
pub extern "c" fn dup2(old_fd: fd_t, new_fd: fd_t) c_int;
pub extern "c" fn readlink(noalias path: [*]const u8, noalias buf: [*]u8, bufsize: usize) isize;
pub extern "c" fn realpath(noalias file_name: [*]const u8, noalias resolved_name: [*]u8) ?[*]u8;
pub extern "c" fn sigprocmask(how: c_int, noalias set: *const sigset_t, noalias oset: ?*sigset_t) c_int;
Expand All @@ -66,18 +69,39 @@ pub extern "c" fn setreuid(ruid: c_uint, euid: c_uint) c_int;
pub extern "c" fn setregid(rgid: c_uint, egid: c_uint) c_int;
pub extern "c" fn rmdir(path: [*]const u8) c_int;
pub extern "c" fn getenv(name: [*]const u8) ?[*]u8;
pub extern "c" fn sysctl(name: [*]c_int, namelen: c_uint, oldp: ?*c_void, oldlenp: ?*usize, newp: ?*c_void, newlen: usize) c_int;
pub extern "c" fn sysctlbyname(name: [*]const u8, oldp: ?*c_void, oldlenp: ?*usize, newp: ?*c_void, newlen: usize) c_int;
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 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 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;
pub extern "c" fn clock_gettime(clk_id: c_int, tp: *timespec) c_int;
pub extern "c" fn clock_getres(clk_id: c_int, tp: *timespec) c_int;

pub extern "c" fn aligned_alloc(alignment: usize, size: usize) ?*c_void;
pub extern "c" fn malloc(usize) ?*c_void;
pub extern "c" fn realloc(?*c_void, usize) ?*c_void;
pub extern "c" fn free(*c_void) void;
pub extern "c" fn posix_memalign(memptr: **c_void, alignment: usize, size: usize) c_int;

pub extern "pthread" fn pthread_create(noalias newthread: *pthread_t, noalias attr: ?*const pthread_attr_t, start_routine: extern fn (?*c_void) ?*c_void, noalias arg: ?*c_void) c_int;
pub extern "pthread" fn pthread_attr_init(attr: *pthread_attr_t) c_int;
pub extern "pthread" fn pthread_attr_setstack(attr: *pthread_attr_t, stackaddr: *c_void, stacksize: usize) c_int;
pub extern "pthread" fn pthread_attr_destroy(attr: *pthread_attr_t) c_int;
pub extern "pthread" fn pthread_self() pthread_t;
pub extern "pthread" fn pthread_join(thread: pthread_t, arg_return: ?*?*c_void) c_int;
pub extern "c" fn pthread_create(noalias newthread: *pthread_t, noalias attr: ?*const pthread_attr_t, start_routine: extern fn (?*c_void) ?*c_void, noalias arg: ?*c_void) c_int;
pub extern "c" fn pthread_attr_init(attr: *pthread_attr_t) c_int;
pub extern "c" fn pthread_attr_setstack(attr: *pthread_attr_t, stackaddr: *c_void, stacksize: usize) c_int;
pub extern "c" fn pthread_attr_destroy(attr: *pthread_attr_t) c_int;
pub extern "c" fn pthread_self() pthread_t;
pub extern "c" fn pthread_join(thread: pthread_t, arg_return: ?*?*c_void) c_int;

pub const pthread_t = *@OpaqueType();
pub extern "c" fn kqueue() c_int;
pub extern "c" fn kevent(
kq: c_int,
changelist: [*]const Kevent,
nchanges: c_int,
eventlist: [*]Kevent,
nevents: c_int,
timeout: ?*const timespec,
) c_int;
193 changes: 16 additions & 177 deletions std/c/darwin.zig
Original file line number Diff line number Diff line change
@@ -1,24 +1,19 @@
const macho = @import("../macho.zig");
const std = @import("../std.zig");
const assert = std.debug.assert;
const builtin = @import("builtin");
const macho = std.macho;

use @import("posix/darwin.zig");

extern "c" fn __error() *c_int;
pub extern "c" fn _NSGetExecutablePath(buf: [*]u8, bufsize: *u32) c_int;
pub extern "c" fn _dyld_get_image_header(image_index: u32) ?*mach_header;

pub extern "c" fn __getdirentries64(fd: c_int, buf_ptr: [*]u8, buf_len: usize, basep: *i64) usize;
pub extern "c" fn __getdirentries64(fd: c_int, buf_ptr: [*]u8, buf_len: usize, basep: *i64) isize;

pub extern "c" fn mach_absolute_time() u64;
pub extern "c" fn mach_timebase_info(tinfo: ?*mach_timebase_info_data) void;

pub extern "c" fn kqueue() c_int;
pub extern "c" fn kevent(
kq: c_int,
changelist: [*]const Kevent,
nchanges: c_int,
eventlist: [*]Kevent,
nevents: c_int,
timeout: ?*const timespec,
) c_int;

pub extern "c" fn kevent64(
kq: c_int,
changelist: [*]const kevent64_s,
Expand All @@ -29,13 +24,6 @@ pub extern "c" fn kevent64(
timeout: ?*const timespec,
) c_int;

pub extern "c" fn sysctl(name: [*]c_int, namelen: c_uint, oldp: ?*c_void, oldlenp: ?*usize, newp: ?*c_void, newlen: usize) c_int;
pub extern "c" fn sysctlbyname(name: [*]const u8, oldp: ?*c_void, oldlenp: ?*usize, newp: ?*c_void, newlen: usize) c_int;
pub extern "c" fn sysctlnametomib(name: [*]const u8, mibp: ?*c_int, sizep: ?*usize) c_int;

pub extern "c" fn bind(socket: c_int, address: ?*const sockaddr, address_len: socklen_t) c_int;
pub extern "c" fn socket(domain: c_int, type: c_int, protocol: c_int) c_int;

const mach_hdr = if (@sizeOf(usize) == 8) mach_header_64 else mach_header;

/// The value of the link editor defined symbol _MH_EXECUTE_SYM is the address
Expand All @@ -48,170 +36,21 @@ const mach_hdr = if (@sizeOf(usize) == 8) mach_header_64 else mach_header;
/// export a weak symbol here, to be overridden by the real one.
pub extern "c" var _mh_execute_header: mach_hdr = undefined;
comptime {
@export("__mh_execute_header", _mh_execute_header, @import("builtin").GlobalLinkage.Weak);
if (std.os.darwin.is_the_target) {
@export("__mh_execute_header", _mh_execute_header, .Weak);
}
}

pub const mach_header_64 = macho.mach_header_64;
pub const mach_header = macho.mach_header;

pub use @import("../os/darwin/errno.zig");

pub const _errno = __error;

pub const in_port_t = u16;
pub const sa_family_t = u8;
pub const socklen_t = u32;
pub const sockaddr = extern union {
in: sockaddr_in,
in6: sockaddr_in6,
};
pub const sockaddr_in = extern struct {
len: u8,
family: sa_family_t,
port: in_port_t,
addr: u32,
zero: [8]u8,
};
pub const sockaddr_in6 = extern struct {
len: u8,
family: sa_family_t,
port: in_port_t,
flowinfo: u32,
addr: [16]u8,
scope_id: u32,
};

pub const timeval = extern struct {
tv_sec: c_long,
tv_usec: i32,
};

pub const timezone = extern struct {
tz_minuteswest: i32,
tz_dsttime: i32,
};

pub const mach_timebase_info_data = extern struct {
numer: u32,
denom: u32,
};

/// Renamed to Stat to not conflict with the stat function.
pub const Stat = extern struct {
dev: i32,
mode: u16,
nlink: u16,
ino: u64,
uid: u32,
gid: u32,
rdev: i32,
atime: usize,
atimensec: usize,
mtime: usize,
mtimensec: usize,
ctime: usize,
ctimensec: usize,
birthtime: usize,
birthtimensec: usize,
size: i64,
blocks: i64,
blksize: i32,
flags: u32,
gen: u32,
lspare: i32,
qspare: [2]i64,
};
pub extern "c" fn mach_host_self() mach_port_t;
pub extern "c" fn clock_get_time(clock_serv: clock_serv_t, cur_time: *mach_timespec_t) kern_return_t;
pub extern "c" fn host_get_clock_service(host: host_t, clock_id: clock_id_t, clock_serv: ?[*]clock_serv_t) kern_return_t;
pub extern "c" fn mach_port_deallocate(task: ipc_space_t, name: mach_port_name_t) kern_return_t;

pub const timespec = extern struct {
tv_sec: isize,
tv_nsec: isize,
};

pub const sigset_t = u32;

/// Renamed from `sigaction` to `Sigaction` to avoid conflict with function name.
pub const Sigaction = extern struct {
handler: extern fn (c_int) void,
sa_mask: sigset_t,
sa_flags: c_int,
};

pub const dirent = extern struct {
d_ino: usize,
d_seekoff: usize,
d_reclen: u16,
d_namlen: u16,
d_type: u8,
d_name: u8, // field address is address of first byte of name
};

pub const pthread_attr_t = extern struct {
__sig: c_long,
__opaque: [56]u8,
};

/// Renamed from `kevent` to `Kevent` to avoid conflict with function name.
pub const Kevent = extern struct {
ident: usize,
filter: i16,
flags: u16,
fflags: u32,
data: isize,
udata: usize,
};

// sys/types.h on macos uses #pragma pack(4) so these checks are
// to make sure the struct is laid out the same. These values were
// produced from C code using the offsetof macro.
const std = @import("../std.zig");
const assert = std.debug.assert;

comptime {
assert(@byteOffsetOf(Kevent, "ident") == 0);
assert(@byteOffsetOf(Kevent, "filter") == 8);
assert(@byteOffsetOf(Kevent, "flags") == 10);
assert(@byteOffsetOf(Kevent, "fflags") == 12);
assert(@byteOffsetOf(Kevent, "data") == 16);
assert(@byteOffsetOf(Kevent, "udata") == 24);
}

pub const kevent64_s = extern struct {
ident: u64,
filter: i16,
flags: u16,
fflags: u32,
data: i64,
udata: u64,
ext: [2]u64,
};

pub const mach_port_t = c_uint;
pub const clock_serv_t = mach_port_t;
pub const clock_res_t = c_int;
pub const mach_port_name_t = natural_t;
pub const natural_t = c_uint;
pub const mach_timespec_t = extern struct {
tv_sec: c_uint,
tv_nsec: clock_res_t,
};
pub const kern_return_t = c_int;
pub const host_t = mach_port_t;
pub const CALENDAR_CLOCK = 1;

pub extern fn mach_host_self() mach_port_t;
pub extern fn clock_get_time(clock_serv: clock_serv_t, cur_time: *mach_timespec_t) kern_return_t;
pub extern fn host_get_clock_service(host: host_t, clock_id: clock_id_t, clock_serv: ?[*]clock_serv_t) kern_return_t;
pub extern fn mach_port_deallocate(task: ipc_space_t, name: mach_port_name_t) kern_return_t;

// sys/types.h on macos uses #pragma pack() so these checks are
// to make sure the struct is laid out the same. These values were
// produced from C code using the offsetof macro.
comptime {
assert(@byteOffsetOf(kevent64_s, "ident") == 0);
assert(@byteOffsetOf(kevent64_s, "filter") == 8);
assert(@byteOffsetOf(kevent64_s, "flags") == 10);
assert(@byteOffsetOf(kevent64_s, "fflags") == 12);
assert(@byteOffsetOf(kevent64_s, "data") == 16);
assert(@byteOffsetOf(kevent64_s, "udata") == 24);
assert(@byteOffsetOf(kevent64_s, "ext") == 32);
pub fn sigaddset(set: *sigset_t, signo: u5) void {
set.* |= u32(1) << (signo - 1);
}
Loading

0 comments on commit c306803

Please sign in to comment.