|
@@ -14,6 +14,7 @@ Handle :: distinct i32
|
|
Pid :: distinct i32
|
|
Pid :: distinct i32
|
|
File_Time :: distinct u64
|
|
File_Time :: distinct u64
|
|
Errno :: distinct i32
|
|
Errno :: distinct i32
|
|
|
|
+Socket :: distinct int
|
|
|
|
|
|
INVALID_HANDLE :: ~Handle(0)
|
|
INVALID_HANDLE :: ~Handle(0)
|
|
|
|
|
|
@@ -171,6 +172,59 @@ SEEK_DATA :: 3
|
|
SEEK_HOLE :: 4
|
|
SEEK_HOLE :: 4
|
|
SEEK_MAX :: SEEK_HOLE
|
|
SEEK_MAX :: SEEK_HOLE
|
|
|
|
|
|
|
|
+
|
|
|
|
+AF_UNSPEC: int : 0
|
|
|
|
+AF_UNIX: int : 1
|
|
|
|
+AF_LOCAL: int : AF_UNIX
|
|
|
|
+AF_INET: int : 2
|
|
|
|
+AF_INET6: int : 10
|
|
|
|
+AF_PACKET: int : 17
|
|
|
|
+AF_BLUETOOTH: int : 31
|
|
|
|
+
|
|
|
|
+SOCK_STREAM: int : 1
|
|
|
|
+SOCK_DGRAM: int : 2
|
|
|
|
+SOCK_RAW: int : 3
|
|
|
|
+SOCK_RDM: int : 4
|
|
|
|
+SOCK_SEQPACKET: int : 5
|
|
|
|
+SOCK_PACKET: int : 10
|
|
|
|
+
|
|
|
|
+INADDR_ANY: c.ulong : 0
|
|
|
|
+INADDR_BROADCAST: c.ulong : 0xffffffff
|
|
|
|
+INADDR_NONE: c.ulong : 0xffffffff
|
|
|
|
+INADDR_DUMMY: c.ulong : 0xc0000008
|
|
|
|
+
|
|
|
|
+IPPROTO_IP: int : 0
|
|
|
|
+IPPROTO_ICMP: int : 1
|
|
|
|
+IPPROTO_TCP: int : 6
|
|
|
|
+IPPROTO_UDP: int : 17
|
|
|
|
+IPPROTO_IPV6: int : 41
|
|
|
|
+IPPROTO_ETHERNET: int : 143
|
|
|
|
+IPPROTO_RAW: int : 255
|
|
|
|
+
|
|
|
|
+SHUT_RD: int : 0
|
|
|
|
+SHUT_WR: int : 1
|
|
|
|
+SHUT_RDWR: int : 2
|
|
|
|
+
|
|
|
|
+
|
|
|
|
+SOL_SOCKET: int : 1
|
|
|
|
+SO_DEBUG: int : 1
|
|
|
|
+SO_REUSEADDR: int : 2
|
|
|
|
+SO_DONTROUTE: int : 5
|
|
|
|
+SO_BROADCAST: int : 6
|
|
|
|
+SO_SNDBUF: int : 7
|
|
|
|
+SO_RCVBUF: int : 8
|
|
|
|
+SO_KEEPALIVE: int : 9
|
|
|
|
+SO_OOBINLINE: int : 10
|
|
|
|
+SO_LINGER: int : 13
|
|
|
|
+SO_REUSEPORT: int : 15
|
|
|
|
+SO_RCVTIMEO_NEW: int : 66
|
|
|
|
+SO_SNDTIMEO_NEW: int : 67
|
|
|
|
+
|
|
|
|
+TCP_NODELAY: int : 1
|
|
|
|
+TCP_CORK: int : 3
|
|
|
|
+
|
|
|
|
+MSG_TRUNC : int : 0x20
|
|
|
|
+
|
|
// NOTE(zangent): These are OS specific!
|
|
// NOTE(zangent): These are OS specific!
|
|
// Do not mix these up!
|
|
// Do not mix these up!
|
|
RTLD_LAZY :: 0x001
|
|
RTLD_LAZY :: 0x001
|
|
@@ -178,6 +232,13 @@ RTLD_NOW :: 0x002
|
|
RTLD_BINDING_MASK :: 0x3
|
|
RTLD_BINDING_MASK :: 0x3
|
|
RTLD_GLOBAL :: 0x100
|
|
RTLD_GLOBAL :: 0x100
|
|
|
|
|
|
|
|
+socklen_t :: c.int
|
|
|
|
+
|
|
|
|
+Timeval :: struct {
|
|
|
|
+ seconds: i64,
|
|
|
|
+ nanoseconds: int,
|
|
|
|
+}
|
|
|
|
+
|
|
// "Argv" arguments converted to Odin strings
|
|
// "Argv" arguments converted to Odin strings
|
|
args := _alloc_command_line_arguments()
|
|
args := _alloc_command_line_arguments()
|
|
|
|
|
|
@@ -217,6 +278,102 @@ Dirent :: struct {
|
|
name: [256]byte,
|
|
name: [256]byte,
|
|
}
|
|
}
|
|
|
|
|
|
|
|
+ADDRESS_FAMILY :: u16
|
|
|
|
+SOCKADDR :: struct #packed {
|
|
|
|
+ sa_family: ADDRESS_FAMILY,
|
|
|
|
+ sa_data: [14]c.char,
|
|
|
|
+}
|
|
|
|
+
|
|
|
|
+SOCKADDR_STORAGE_LH :: struct #packed {
|
|
|
|
+ ss_family: ADDRESS_FAMILY,
|
|
|
|
+ __ss_pad1: [6]c.char,
|
|
|
|
+ __ss_align: i64,
|
|
|
|
+ __ss_pad2: [112]c.char,
|
|
|
|
+}
|
|
|
|
+
|
|
|
|
+sockaddr_in :: struct #packed {
|
|
|
|
+ sin_family: ADDRESS_FAMILY,
|
|
|
|
+ sin_port: u16be,
|
|
|
|
+ sin_addr: in_addr,
|
|
|
|
+ sin_zero: [8]c.char,
|
|
|
|
+}
|
|
|
|
+
|
|
|
|
+sockaddr_in6 :: struct #packed {
|
|
|
|
+ sin6_family: ADDRESS_FAMILY,
|
|
|
|
+ sin6_port: u16be,
|
|
|
|
+ sin6_flowinfo: c.ulong,
|
|
|
|
+ sin6_addr: in6_addr,
|
|
|
|
+ sin6_scope_id: c.ulong,
|
|
|
|
+}
|
|
|
|
+
|
|
|
|
+in_addr :: struct #packed {
|
|
|
|
+ s_addr: u32,
|
|
|
|
+}
|
|
|
|
+
|
|
|
|
+in6_addr :: struct #packed {
|
|
|
|
+ s6_addr: [16]u8,
|
|
|
|
+}
|
|
|
|
+
|
|
|
|
+rtnl_link_stats :: struct #packed {
|
|
|
|
+ rx_packets: u32,
|
|
|
|
+ tx_packets: u32,
|
|
|
|
+ rx_bytes: u32,
|
|
|
|
+ tx_bytes: u32,
|
|
|
|
+ rx_errors: u32,
|
|
|
|
+ tx_errors: u32,
|
|
|
|
+ rx_dropped: u32,
|
|
|
|
+ tx_dropped: u32,
|
|
|
|
+ multicast: u32,
|
|
|
|
+ collisions: u32,
|
|
|
|
+ rx_length_errors: u32,
|
|
|
|
+ rx_over_errors: u32,
|
|
|
|
+ rx_crc_errors: u32,
|
|
|
|
+ rx_frame_errors: u32,
|
|
|
|
+ rx_fifo_errors: u32,
|
|
|
|
+ rx_missed_errors: u32,
|
|
|
|
+ tx_aborted_errors: u32,
|
|
|
|
+ tx_carrier_errors: u32,
|
|
|
|
+ tx_fifo_errors: u32,
|
|
|
|
+ tx_heartbeat_errors: u32,
|
|
|
|
+ tx_window_errors: u32,
|
|
|
|
+ rx_compressed: u32,
|
|
|
|
+ tx_compressed: u32,
|
|
|
|
+ rx_nohandler: u32,
|
|
|
|
+}
|
|
|
|
+
|
|
|
|
+SIOCGIFFLAG :: enum c.int {
|
|
|
|
+ UP = 0, /* Interface is up. */
|
|
|
|
+ BROADCAST = 1, /* Broadcast address valid. */
|
|
|
|
+ DEBUG = 2, /* Turn on debugging. */
|
|
|
|
+ LOOPBACK = 3, /* Is a loopback net. */
|
|
|
|
+ POINT_TO_POINT = 4, /* Interface is point-to-point link. */
|
|
|
|
+ NO_TRAILERS = 5, /* Avoid use of trailers. */
|
|
|
|
+ RUNNING = 6, /* Resources allocated. */
|
|
|
|
+ NOARP = 7, /* No address resolution protocol. */
|
|
|
|
+ PROMISC = 8, /* Receive all packets. */
|
|
|
|
+ ALL_MULTI = 9, /* Receive all multicast packets. Unimplemented. */
|
|
|
|
+ MASTER = 10, /* Master of a load balancer. */
|
|
|
|
+ SLAVE = 11, /* Slave of a load balancer. */
|
|
|
|
+ MULTICAST = 12, /* Supports multicast. */
|
|
|
|
+ PORTSEL = 13, /* Can set media type. */
|
|
|
|
+ AUTOMEDIA = 14, /* Auto media select active. */
|
|
|
|
+ DYNAMIC = 15, /* Dialup device with changing addresses. */
|
|
|
|
+ LOWER_UP = 16,
|
|
|
|
+ DORMANT = 17,
|
|
|
|
+ ECHO = 18,
|
|
|
|
+}
|
|
|
|
+SIOCGIFFLAGS :: bit_set[SIOCGIFFLAG; c.int]
|
|
|
|
+
|
|
|
|
+ifaddrs :: struct {
|
|
|
|
+ next: ^ifaddrs,
|
|
|
|
+ name: cstring,
|
|
|
|
+ flags: SIOCGIFFLAGS,
|
|
|
|
+ address: ^SOCKADDR,
|
|
|
|
+ netmask: ^SOCKADDR,
|
|
|
|
+ broadcast_or_dest: ^SOCKADDR, // Broadcast or Point-to-Point address
|
|
|
|
+ data: rawptr, // Address-specific data.
|
|
|
|
+}
|
|
|
|
+
|
|
Dir :: distinct rawptr // DIR*
|
|
Dir :: distinct rawptr // DIR*
|
|
|
|
|
|
// File type
|
|
// File type
|
|
@@ -236,13 +393,13 @@ S_IRUSR :: 0o0400 // R for owner
|
|
S_IWUSR :: 0o0200 // W for owner
|
|
S_IWUSR :: 0o0200 // W for owner
|
|
S_IXUSR :: 0o0100 // X for owner
|
|
S_IXUSR :: 0o0100 // X for owner
|
|
|
|
|
|
- // Read, write, execute/search by group
|
|
|
|
|
|
+// Read, write, execute/search by group
|
|
S_IRWXG :: 0o0070 // RWX mask for group
|
|
S_IRWXG :: 0o0070 // RWX mask for group
|
|
S_IRGRP :: 0o0040 // R for group
|
|
S_IRGRP :: 0o0040 // R for group
|
|
S_IWGRP :: 0o0020 // W for group
|
|
S_IWGRP :: 0o0020 // W for group
|
|
S_IXGRP :: 0o0010 // X for group
|
|
S_IXGRP :: 0o0010 // X for group
|
|
|
|
|
|
- // Read, write, execute/search by others
|
|
|
|
|
|
+// Read, write, execute/search by others
|
|
S_IRWXO :: 0o0007 // RWX mask for other
|
|
S_IRWXO :: 0o0007 // RWX mask for other
|
|
S_IROTH :: 0o0004 // R for other
|
|
S_IROTH :: 0o0004 // R for other
|
|
S_IWOTH :: 0o0002 // W for other
|
|
S_IWOTH :: 0o0002 // W for other
|
|
@@ -270,136 +427,6 @@ AT_FDCWD :: ~uintptr(99) /* -100 */
|
|
AT_REMOVEDIR :: uintptr(0x200)
|
|
AT_REMOVEDIR :: uintptr(0x200)
|
|
AT_SYMLINK_NOFOLLOW :: uintptr(0x100)
|
|
AT_SYMLINK_NOFOLLOW :: uintptr(0x100)
|
|
|
|
|
|
-_unix_personality :: proc(persona: u64) -> int {
|
|
|
|
- return int(intrinsics.syscall(unix.SYS_personality, uintptr(persona)))
|
|
|
|
-}
|
|
|
|
-
|
|
|
|
-_unix_fork :: proc() -> Pid {
|
|
|
|
- when ODIN_ARCH != .arm64 {
|
|
|
|
- res := int(intrinsics.syscall(unix.SYS_fork))
|
|
|
|
- } else {
|
|
|
|
- res := int(intrinsics.syscall(unix.SYS_clone, unix.SIGCHLD))
|
|
|
|
- }
|
|
|
|
- return -1 if res < 0 else Pid(res)
|
|
|
|
-}
|
|
|
|
-
|
|
|
|
-_unix_open :: proc(path: cstring, flags: int, mode: int = 0o000) -> Handle {
|
|
|
|
- when ODIN_ARCH != .arm64 {
|
|
|
|
- res := int(intrinsics.syscall(unix.SYS_open, uintptr(rawptr(path)), uintptr(flags), uintptr(mode)))
|
|
|
|
- } else { // NOTE: arm64 does not have open
|
|
|
|
- res := int(intrinsics.syscall(unix.SYS_openat, AT_FDCWD, uintptr(rawptr(path)), uintptr(flags), uintptr(mode)))
|
|
|
|
- }
|
|
|
|
- return -1 if res < 0 else Handle(res)
|
|
|
|
-}
|
|
|
|
-
|
|
|
|
-_unix_close :: proc(fd: Handle) -> int {
|
|
|
|
- return int(intrinsics.syscall(unix.SYS_close, uintptr(fd)))
|
|
|
|
-}
|
|
|
|
-
|
|
|
|
-_unix_read :: proc(fd: Handle, buf: rawptr, size: uint) -> int {
|
|
|
|
- return int(intrinsics.syscall(unix.SYS_read, uintptr(fd), uintptr(buf), uintptr(size)))
|
|
|
|
-}
|
|
|
|
-
|
|
|
|
-_unix_write :: proc(fd: Handle, buf: rawptr, size: uint) -> int {
|
|
|
|
- return int(intrinsics.syscall(unix.SYS_write, uintptr(fd), uintptr(buf), uintptr(size)))
|
|
|
|
-}
|
|
|
|
-
|
|
|
|
-_unix_seek :: proc(fd: Handle, offset: i64, whence: int) -> i64 {
|
|
|
|
- when ODIN_ARCH == .amd64 || ODIN_ARCH == .arm64 {
|
|
|
|
- return i64(intrinsics.syscall(unix.SYS_lseek, uintptr(fd), uintptr(offset), uintptr(whence)))
|
|
|
|
- } else {
|
|
|
|
- low := uintptr(offset & 0xFFFFFFFF)
|
|
|
|
- high := uintptr(offset >> 32)
|
|
|
|
- result: i64
|
|
|
|
- res := i64(intrinsics.syscall(unix.SYS__llseek, uintptr(fd), high, low, uintptr(&result), uintptr(whence)))
|
|
|
|
- return -1 if res < 0 else result
|
|
|
|
- }
|
|
|
|
-}
|
|
|
|
-
|
|
|
|
-_unix_stat :: proc(path: cstring, stat: ^OS_Stat) -> int {
|
|
|
|
- when ODIN_ARCH == .amd64 {
|
|
|
|
- return int(intrinsics.syscall(unix.SYS_stat, uintptr(rawptr(path)), uintptr(stat)))
|
|
|
|
- } else when ODIN_ARCH != .arm64 {
|
|
|
|
- return int(intrinsics.syscall(unix.SYS_stat64, uintptr(rawptr(path)), uintptr(stat)))
|
|
|
|
- } else { // NOTE: arm64 does not have stat
|
|
|
|
- return int(intrinsics.syscall(unix.SYS_fstatat, AT_FDCWD, uintptr(rawptr(path)), uintptr(stat), 0))
|
|
|
|
- }
|
|
|
|
-}
|
|
|
|
-
|
|
|
|
-_unix_fstat :: proc(fd: Handle, stat: ^OS_Stat) -> int {
|
|
|
|
- when ODIN_ARCH == .amd64 || ODIN_ARCH == .arm64 {
|
|
|
|
- return int(intrinsics.syscall(unix.SYS_fstat, uintptr(fd), uintptr(stat)))
|
|
|
|
- } else {
|
|
|
|
- return int(intrinsics.syscall(unix.SYS_fstat64, uintptr(fd), uintptr(stat)))
|
|
|
|
- }
|
|
|
|
-}
|
|
|
|
-
|
|
|
|
-_unix_lstat :: proc(path: cstring, stat: ^OS_Stat) -> int {
|
|
|
|
- when ODIN_ARCH == .amd64 {
|
|
|
|
- return int(intrinsics.syscall(unix.SYS_lstat, uintptr(rawptr(path)), uintptr(stat)))
|
|
|
|
- } else when ODIN_ARCH != .arm64 {
|
|
|
|
- return int(intrinsics.syscall(unix.SYS_lstat64, uintptr(rawptr(path)), uintptr(stat)))
|
|
|
|
- } else { // NOTE: arm64 does not have any lstat
|
|
|
|
- return int(intrinsics.syscall(unix.SYS_fstatat, AT_FDCWD, uintptr(rawptr(path)), uintptr(stat), AT_SYMLINK_NOFOLLOW))
|
|
|
|
- }
|
|
|
|
-}
|
|
|
|
-
|
|
|
|
-_unix_readlink :: proc(path: cstring, buf: rawptr, bufsiz: uint) -> int {
|
|
|
|
- when ODIN_ARCH != .arm64 {
|
|
|
|
- return int(intrinsics.syscall(unix.SYS_readlink, uintptr(rawptr(path)), uintptr(buf), uintptr(bufsiz)))
|
|
|
|
- } else { // NOTE: arm64 does not have readlink
|
|
|
|
- return int(intrinsics.syscall(unix.SYS_readlinkat, AT_FDCWD, uintptr(rawptr(path)), uintptr(buf), uintptr(bufsiz)))
|
|
|
|
- }
|
|
|
|
-}
|
|
|
|
-
|
|
|
|
-_unix_access :: proc(path: cstring, mask: int) -> int {
|
|
|
|
- when ODIN_ARCH != .arm64 {
|
|
|
|
- return int(intrinsics.syscall(unix.SYS_access, uintptr(rawptr(path)), uintptr(mask)))
|
|
|
|
- } else { // NOTE: arm64 does not have access
|
|
|
|
- return int(intrinsics.syscall(unix.SYS_faccessat, AT_FDCWD, uintptr(rawptr(path)), uintptr(mask)))
|
|
|
|
- }
|
|
|
|
-}
|
|
|
|
-
|
|
|
|
-_unix_getcwd :: proc(buf: rawptr, size: uint) -> int {
|
|
|
|
- return int(intrinsics.syscall(unix.SYS_getcwd, uintptr(buf), uintptr(size)))
|
|
|
|
-}
|
|
|
|
-
|
|
|
|
-_unix_chdir :: proc(path: cstring) -> int {
|
|
|
|
- return int(intrinsics.syscall(unix.SYS_chdir, uintptr(rawptr(path))))
|
|
|
|
-}
|
|
|
|
-
|
|
|
|
-_unix_rename :: proc(old, new: cstring) -> int {
|
|
|
|
- when ODIN_ARCH != .arm64 {
|
|
|
|
- return int(intrinsics.syscall(unix.SYS_rename, uintptr(rawptr(old)), uintptr(rawptr(new))))
|
|
|
|
- } else { // NOTE: arm64 does not have rename
|
|
|
|
- return int(intrinsics.syscall(unix.SYS_renameat, AT_FDCWD, uintptr(rawptr(old)), uintptr(rawptr(new))))
|
|
|
|
- }
|
|
|
|
-}
|
|
|
|
-
|
|
|
|
-_unix_unlink :: proc(path: cstring) -> int {
|
|
|
|
- when ODIN_ARCH != .arm64 {
|
|
|
|
- return int(intrinsics.syscall(unix.SYS_unlink, uintptr(rawptr(path))))
|
|
|
|
- } else { // NOTE: arm64 does not have unlink
|
|
|
|
- return int(intrinsics.syscall(unix.SYS_unlinkat, AT_FDCWD, uintptr(rawptr(path)), 0))
|
|
|
|
- }
|
|
|
|
-}
|
|
|
|
-
|
|
|
|
-_unix_rmdir :: proc(path: cstring) -> int {
|
|
|
|
- when ODIN_ARCH != .arm64 {
|
|
|
|
- return int(intrinsics.syscall(unix.SYS_rmdir, uintptr(rawptr(path))))
|
|
|
|
- } else { // NOTE: arm64 does not have rmdir
|
|
|
|
- return int(intrinsics.syscall(unix.SYS_unlinkat, AT_FDCWD, uintptr(rawptr(path)), AT_REMOVEDIR))
|
|
|
|
- }
|
|
|
|
-}
|
|
|
|
-
|
|
|
|
-_unix_mkdir :: proc(path: cstring, mode: u32) -> int {
|
|
|
|
- when ODIN_ARCH != .arm64 {
|
|
|
|
- return int(intrinsics.syscall(unix.SYS_mkdir, uintptr(rawptr(path)), uintptr(mode)))
|
|
|
|
- } else { // NOTE: arm64 does not have mkdir
|
|
|
|
- return int(intrinsics.syscall(unix.SYS_mkdirat, AT_FDCWD, uintptr(rawptr(path)), uintptr(mode)))
|
|
|
|
- }
|
|
|
|
-}
|
|
|
|
-
|
|
|
|
foreign libc {
|
|
foreign libc {
|
|
@(link_name="__errno_location") __errno_location :: proc() -> ^int ---
|
|
@(link_name="__errno_location") __errno_location :: proc() -> ^int ---
|
|
|
|
|
|
@@ -415,6 +442,7 @@ foreign libc {
|
|
@(link_name="free") _unix_free :: proc(ptr: rawptr) ---
|
|
@(link_name="free") _unix_free :: proc(ptr: rawptr) ---
|
|
@(link_name="realloc") _unix_realloc :: proc(ptr: rawptr, size: c.size_t) -> rawptr ---
|
|
@(link_name="realloc") _unix_realloc :: proc(ptr: rawptr, size: c.size_t) -> rawptr ---
|
|
|
|
|
|
|
|
+ @(link_name="execvp") _unix_execvp :: proc(path: cstring, argv: [^]cstring) -> int ---
|
|
@(link_name="getenv") _unix_getenv :: proc(cstring) -> cstring ---
|
|
@(link_name="getenv") _unix_getenv :: proc(cstring) -> cstring ---
|
|
@(link_name="putenv") _unix_putenv :: proc(cstring) -> c.int ---
|
|
@(link_name="putenv") _unix_putenv :: proc(cstring) -> c.int ---
|
|
@(link_name="realpath") _unix_realpath :: proc(path: cstring, resolved_path: rawptr) -> rawptr ---
|
|
@(link_name="realpath") _unix_realpath :: proc(path: cstring, resolved_path: rawptr) -> rawptr ---
|
|
@@ -426,6 +454,9 @@ foreign dl {
|
|
@(link_name="dlsym") _unix_dlsym :: proc(handle: rawptr, symbol: cstring) -> rawptr ---
|
|
@(link_name="dlsym") _unix_dlsym :: proc(handle: rawptr, symbol: cstring) -> rawptr ---
|
|
@(link_name="dlclose") _unix_dlclose :: proc(handle: rawptr) -> c.int ---
|
|
@(link_name="dlclose") _unix_dlclose :: proc(handle: rawptr) -> c.int ---
|
|
@(link_name="dlerror") _unix_dlerror :: proc() -> cstring ---
|
|
@(link_name="dlerror") _unix_dlerror :: proc() -> cstring ---
|
|
|
|
+
|
|
|
|
+ @(link_name="getifaddrs") _getifaddrs :: proc(ifap: ^^ifaddrs) -> (c.int) ---
|
|
|
|
+ @(link_name="freeifaddrs") _freeifaddrs :: proc(ifa: ^ifaddrs) ---
|
|
}
|
|
}
|
|
|
|
|
|
is_path_separator :: proc(r: rune) -> bool {
|
|
is_path_separator :: proc(r: rune) -> bool {
|
|
@@ -447,7 +478,7 @@ get_last_error :: proc "contextless" () -> int {
|
|
}
|
|
}
|
|
|
|
|
|
personality :: proc(persona: u64) -> (Errno) {
|
|
personality :: proc(persona: u64) -> (Errno) {
|
|
- res := _unix_personality(persona)
|
|
|
|
|
|
+ res := unix.sys_personality(persona)
|
|
if res == -1 {
|
|
if res == -1 {
|
|
return _get_errno(res)
|
|
return _get_errno(res)
|
|
}
|
|
}
|
|
@@ -455,28 +486,48 @@ personality :: proc(persona: u64) -> (Errno) {
|
|
}
|
|
}
|
|
|
|
|
|
fork :: proc() -> (Pid, Errno) {
|
|
fork :: proc() -> (Pid, Errno) {
|
|
- pid := _unix_fork()
|
|
|
|
|
|
+ pid := unix.sys_fork()
|
|
if pid == -1 {
|
|
if pid == -1 {
|
|
- return -1, _get_errno(int(pid))
|
|
|
|
|
|
+ return -1, _get_errno(pid)
|
|
|
|
+ }
|
|
|
|
+ return Pid(pid), ERROR_NONE
|
|
|
|
+}
|
|
|
|
+
|
|
|
|
+execvp :: proc(path: string, args: []string) -> Errno {
|
|
|
|
+ runtime.DEFAULT_TEMP_ALLOCATOR_TEMP_GUARD()
|
|
|
|
+ path_cstr := strings.clone_to_cstring(path, context.temp_allocator)
|
|
|
|
+
|
|
|
|
+ args_cstrs := make([]cstring, len(args) + 2, context.temp_allocator)
|
|
|
|
+ args_cstrs[0] = strings.clone_to_cstring(path, context.temp_allocator)
|
|
|
|
+ for i := 0; i < len(args); i += 1 {
|
|
|
|
+ args_cstrs[i+1] = strings.clone_to_cstring(args[i], context.temp_allocator)
|
|
}
|
|
}
|
|
- return pid, ERROR_NONE
|
|
|
|
|
|
+
|
|
|
|
+ _unix_execvp(path_cstr, raw_data(args_cstrs))
|
|
|
|
+ return Errno(get_last_error())
|
|
}
|
|
}
|
|
|
|
|
|
-open :: proc(path: string, flags: int = O_RDONLY, mode: int = 0) -> (Handle, Errno) {
|
|
|
|
|
|
+
|
|
|
|
+open :: proc(path: string, flags: int = O_RDONLY, mode: int = 0o000) -> (Handle, Errno) {
|
|
|
|
+ runtime.DEFAULT_TEMP_ALLOCATOR_TEMP_GUARD()
|
|
cstr := strings.clone_to_cstring(path, context.temp_allocator)
|
|
cstr := strings.clone_to_cstring(path, context.temp_allocator)
|
|
- handle := _unix_open(cstr, flags, mode)
|
|
|
|
|
|
+ handle := unix.sys_open(cstr, flags, uint(mode))
|
|
if handle < 0 {
|
|
if handle < 0 {
|
|
- return INVALID_HANDLE, _get_errno(int(handle))
|
|
|
|
|
|
+ return INVALID_HANDLE, _get_errno(handle)
|
|
}
|
|
}
|
|
- return handle, ERROR_NONE
|
|
|
|
|
|
+ return Handle(handle), ERROR_NONE
|
|
}
|
|
}
|
|
|
|
|
|
close :: proc(fd: Handle) -> Errno {
|
|
close :: proc(fd: Handle) -> Errno {
|
|
- return _get_errno(_unix_close(fd))
|
|
|
|
|
|
+ return _get_errno(unix.sys_close(int(fd)))
|
|
}
|
|
}
|
|
|
|
|
|
read :: proc(fd: Handle, data: []byte) -> (int, Errno) {
|
|
read :: proc(fd: Handle, data: []byte) -> (int, Errno) {
|
|
- bytes_read := _unix_read(fd, &data[0], c.size_t(len(data)))
|
|
|
|
|
|
+ if len(data) == 0 {
|
|
|
|
+ return 0, ERROR_NONE
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ bytes_read := unix.sys_read(int(fd), raw_data(data), len(data))
|
|
if bytes_read < 0 {
|
|
if bytes_read < 0 {
|
|
return -1, _get_errno(bytes_read)
|
|
return -1, _get_errno(bytes_read)
|
|
}
|
|
}
|
|
@@ -487,50 +538,78 @@ write :: proc(fd: Handle, data: []byte) -> (int, Errno) {
|
|
if len(data) == 0 {
|
|
if len(data) == 0 {
|
|
return 0, ERROR_NONE
|
|
return 0, ERROR_NONE
|
|
}
|
|
}
|
|
- bytes_written := _unix_write(fd, &data[0], uint(len(data)))
|
|
|
|
|
|
+
|
|
|
|
+ bytes_written := unix.sys_write(int(fd), raw_data(data), len(data))
|
|
if bytes_written < 0 {
|
|
if bytes_written < 0 {
|
|
return -1, _get_errno(bytes_written)
|
|
return -1, _get_errno(bytes_written)
|
|
}
|
|
}
|
|
- return int(bytes_written), ERROR_NONE
|
|
|
|
|
|
+ return bytes_written, ERROR_NONE
|
|
|
|
+}
|
|
|
|
+read_at :: proc(fd: Handle, data: []byte, offset: i64) -> (int, Errno) {
|
|
|
|
+ if len(data) == 0 {
|
|
|
|
+ return 0, ERROR_NONE
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ bytes_read := unix.sys_pread(int(fd), raw_data(data), len(data), offset)
|
|
|
|
+ if bytes_read < 0 {
|
|
|
|
+ return -1, _get_errno(bytes_read)
|
|
|
|
+ }
|
|
|
|
+ return bytes_read, ERROR_NONE
|
|
|
|
+}
|
|
|
|
+
|
|
|
|
+write_at :: proc(fd: Handle, data: []byte, offset: i64) -> (int, Errno) {
|
|
|
|
+ if len(data) == 0 {
|
|
|
|
+ return 0, ERROR_NONE
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ bytes_written := unix.sys_pwrite(int(fd), raw_data(data), uint(len(data)), offset)
|
|
|
|
+ if bytes_written < 0 {
|
|
|
|
+ return -1, _get_errno(bytes_written)
|
|
|
|
+ }
|
|
|
|
+ return bytes_written, ERROR_NONE
|
|
}
|
|
}
|
|
|
|
|
|
seek :: proc(fd: Handle, offset: i64, whence: int) -> (i64, Errno) {
|
|
seek :: proc(fd: Handle, offset: i64, whence: int) -> (i64, Errno) {
|
|
- res := _unix_seek(fd, offset, whence)
|
|
|
|
|
|
+ res := unix.sys_lseek(int(fd), offset, whence)
|
|
if res < 0 {
|
|
if res < 0 {
|
|
return -1, _get_errno(int(res))
|
|
return -1, _get_errno(int(res))
|
|
}
|
|
}
|
|
- return res, ERROR_NONE
|
|
|
|
|
|
+ return i64(res), ERROR_NONE
|
|
}
|
|
}
|
|
|
|
|
|
file_size :: proc(fd: Handle) -> (i64, Errno) {
|
|
file_size :: proc(fd: Handle) -> (i64, Errno) {
|
|
- // deliberately uninitialized; the syscall fills this buffer for us
|
|
|
|
- s: OS_Stat = ---
|
|
|
|
- result := _unix_fstat(fd, &s)
|
|
|
|
- if result < 0 {
|
|
|
|
- return 0, _get_errno(result)
|
|
|
|
- }
|
|
|
|
- return max(s.size, 0), ERROR_NONE
|
|
|
|
|
|
+ // deliberately uninitialized; the syscall fills this buffer for us
|
|
|
|
+ s: OS_Stat = ---
|
|
|
|
+ result := unix.sys_fstat(int(fd), rawptr(&s))
|
|
|
|
+ if result < 0 {
|
|
|
|
+ return 0, _get_errno(result)
|
|
|
|
+ }
|
|
|
|
+ return max(s.size, 0), ERROR_NONE
|
|
}
|
|
}
|
|
|
|
|
|
rename :: proc(old_path, new_path: string) -> Errno {
|
|
rename :: proc(old_path, new_path: string) -> Errno {
|
|
|
|
+ runtime.DEFAULT_TEMP_ALLOCATOR_TEMP_GUARD()
|
|
old_path_cstr := strings.clone_to_cstring(old_path, context.temp_allocator)
|
|
old_path_cstr := strings.clone_to_cstring(old_path, context.temp_allocator)
|
|
new_path_cstr := strings.clone_to_cstring(new_path, context.temp_allocator)
|
|
new_path_cstr := strings.clone_to_cstring(new_path, context.temp_allocator)
|
|
- return _get_errno(_unix_rename(old_path_cstr, new_path_cstr))
|
|
|
|
|
|
+ return _get_errno(unix.sys_rename(old_path_cstr, new_path_cstr))
|
|
}
|
|
}
|
|
|
|
|
|
remove :: proc(path: string) -> Errno {
|
|
remove :: proc(path: string) -> Errno {
|
|
|
|
+ runtime.DEFAULT_TEMP_ALLOCATOR_TEMP_GUARD()
|
|
path_cstr := strings.clone_to_cstring(path, context.temp_allocator)
|
|
path_cstr := strings.clone_to_cstring(path, context.temp_allocator)
|
|
- return _get_errno(_unix_unlink(path_cstr))
|
|
|
|
|
|
+ return _get_errno(unix.sys_unlink(path_cstr))
|
|
}
|
|
}
|
|
|
|
|
|
make_directory :: proc(path: string, mode: u32 = 0o775) -> Errno {
|
|
make_directory :: proc(path: string, mode: u32 = 0o775) -> Errno {
|
|
|
|
+ runtime.DEFAULT_TEMP_ALLOCATOR_TEMP_GUARD()
|
|
path_cstr := strings.clone_to_cstring(path, context.temp_allocator)
|
|
path_cstr := strings.clone_to_cstring(path, context.temp_allocator)
|
|
- return _get_errno(_unix_mkdir(path_cstr, mode))
|
|
|
|
|
|
+ return _get_errno(unix.sys_mkdir(path_cstr, uint(mode)))
|
|
}
|
|
}
|
|
|
|
|
|
remove_directory :: proc(path: string) -> Errno {
|
|
remove_directory :: proc(path: string) -> Errno {
|
|
|
|
+ runtime.DEFAULT_TEMP_ALLOCATOR_TEMP_GUARD()
|
|
path_cstr := strings.clone_to_cstring(path, context.temp_allocator)
|
|
path_cstr := strings.clone_to_cstring(path, context.temp_allocator)
|
|
- return _get_errno(_unix_rmdir(path_cstr))
|
|
|
|
|
|
+ return _get_errno(unix.sys_rmdir(path_cstr))
|
|
}
|
|
}
|
|
|
|
|
|
is_file_handle :: proc(fd: Handle) -> bool {
|
|
is_file_handle :: proc(fd: Handle) -> bool {
|
|
@@ -582,8 +661,9 @@ is_file :: proc {is_file_path, is_file_handle}
|
|
is_dir :: proc {is_dir_path, is_dir_handle}
|
|
is_dir :: proc {is_dir_path, is_dir_handle}
|
|
|
|
|
|
exists :: proc(path: string) -> bool {
|
|
exists :: proc(path: string) -> bool {
|
|
|
|
+ runtime.DEFAULT_TEMP_ALLOCATOR_TEMP_GUARD()
|
|
cpath := strings.clone_to_cstring(path, context.temp_allocator)
|
|
cpath := strings.clone_to_cstring(path, context.temp_allocator)
|
|
- res := _unix_access(cpath, O_RDONLY)
|
|
|
|
|
|
+ res := unix.sys_access(cpath, O_RDONLY)
|
|
return res == 0
|
|
return res == 0
|
|
}
|
|
}
|
|
|
|
|
|
@@ -617,11 +697,12 @@ last_write_time_by_name :: proc(name: string) -> (File_Time, Errno) {
|
|
|
|
|
|
@private
|
|
@private
|
|
_stat :: proc(path: string) -> (OS_Stat, Errno) {
|
|
_stat :: proc(path: string) -> (OS_Stat, Errno) {
|
|
|
|
+ runtime.DEFAULT_TEMP_ALLOCATOR_TEMP_GUARD()
|
|
cstr := strings.clone_to_cstring(path, context.temp_allocator)
|
|
cstr := strings.clone_to_cstring(path, context.temp_allocator)
|
|
|
|
|
|
// deliberately uninitialized; the syscall fills this buffer for us
|
|
// deliberately uninitialized; the syscall fills this buffer for us
|
|
s: OS_Stat = ---
|
|
s: OS_Stat = ---
|
|
- result := _unix_stat(cstr, &s)
|
|
|
|
|
|
+ result := unix.sys_stat(cstr, &s)
|
|
if result < 0 {
|
|
if result < 0 {
|
|
return s, _get_errno(result)
|
|
return s, _get_errno(result)
|
|
}
|
|
}
|
|
@@ -630,11 +711,12 @@ _stat :: proc(path: string) -> (OS_Stat, Errno) {
|
|
|
|
|
|
@private
|
|
@private
|
|
_lstat :: proc(path: string) -> (OS_Stat, Errno) {
|
|
_lstat :: proc(path: string) -> (OS_Stat, Errno) {
|
|
|
|
+ runtime.DEFAULT_TEMP_ALLOCATOR_TEMP_GUARD()
|
|
cstr := strings.clone_to_cstring(path, context.temp_allocator)
|
|
cstr := strings.clone_to_cstring(path, context.temp_allocator)
|
|
|
|
|
|
// deliberately uninitialized; the syscall fills this buffer for us
|
|
// deliberately uninitialized; the syscall fills this buffer for us
|
|
s: OS_Stat = ---
|
|
s: OS_Stat = ---
|
|
- result := _unix_lstat(cstr, &s)
|
|
|
|
|
|
+ result := unix.sys_lstat(cstr, &s)
|
|
if result < 0 {
|
|
if result < 0 {
|
|
return s, _get_errno(result)
|
|
return s, _get_errno(result)
|
|
}
|
|
}
|
|
@@ -645,7 +727,7 @@ _lstat :: proc(path: string) -> (OS_Stat, Errno) {
|
|
_fstat :: proc(fd: Handle) -> (OS_Stat, Errno) {
|
|
_fstat :: proc(fd: Handle) -> (OS_Stat, Errno) {
|
|
// deliberately uninitialized; the syscall fills this buffer for us
|
|
// deliberately uninitialized; the syscall fills this buffer for us
|
|
s: OS_Stat = ---
|
|
s: OS_Stat = ---
|
|
- result := _unix_fstat(fd, &s)
|
|
|
|
|
|
+ result := unix.sys_fstat(int(fd), rawptr(&s))
|
|
if result < 0 {
|
|
if result < 0 {
|
|
return s, _get_errno(result)
|
|
return s, _get_errno(result)
|
|
}
|
|
}
|
|
@@ -697,12 +779,13 @@ _readdir :: proc(dirp: Dir) -> (entry: Dirent, err: Errno, end_of_stream: bool)
|
|
|
|
|
|
@private
|
|
@private
|
|
_readlink :: proc(path: string) -> (string, Errno) {
|
|
_readlink :: proc(path: string) -> (string, Errno) {
|
|
|
|
+ runtime.DEFAULT_TEMP_ALLOCATOR_TEMP_GUARD(ignore = context.temp_allocator == context.allocator)
|
|
path_cstr := strings.clone_to_cstring(path, context.temp_allocator)
|
|
path_cstr := strings.clone_to_cstring(path, context.temp_allocator)
|
|
|
|
|
|
bufsz : uint = 256
|
|
bufsz : uint = 256
|
|
buf := make([]byte, bufsz)
|
|
buf := make([]byte, bufsz)
|
|
for {
|
|
for {
|
|
- rc := _unix_readlink(path_cstr, &(buf[0]), bufsz)
|
|
|
|
|
|
+ rc := unix.sys_readlink(path_cstr, &(buf[0]), bufsz)
|
|
if rc < 0 {
|
|
if rc < 0 {
|
|
delete(buf)
|
|
delete(buf)
|
|
return "", _get_errno(rc)
|
|
return "", _get_errno(rc)
|
|
@@ -732,6 +815,7 @@ absolute_path_from_relative :: proc(rel: string) -> (path: string, err: Errno) {
|
|
if rel == "" {
|
|
if rel == "" {
|
|
rel = "."
|
|
rel = "."
|
|
}
|
|
}
|
|
|
|
+ runtime.DEFAULT_TEMP_ALLOCATOR_TEMP_GUARD(ignore = context.temp_allocator == context.allocator)
|
|
|
|
|
|
rel_cstr := strings.clone_to_cstring(rel, context.temp_allocator)
|
|
rel_cstr := strings.clone_to_cstring(rel, context.temp_allocator)
|
|
|
|
|
|
@@ -748,8 +832,9 @@ absolute_path_from_relative :: proc(rel: string) -> (path: string, err: Errno) {
|
|
}
|
|
}
|
|
|
|
|
|
access :: proc(path: string, mask: int) -> (bool, Errno) {
|
|
access :: proc(path: string, mask: int) -> (bool, Errno) {
|
|
|
|
+ runtime.DEFAULT_TEMP_ALLOCATOR_TEMP_GUARD()
|
|
cstr := strings.clone_to_cstring(path, context.temp_allocator)
|
|
cstr := strings.clone_to_cstring(path, context.temp_allocator)
|
|
- result := _unix_access(cstr, mask)
|
|
|
|
|
|
+ result := unix.sys_access(cstr, mask)
|
|
if result < 0 {
|
|
if result < 0 {
|
|
return false, _get_errno(result)
|
|
return false, _get_errno(result)
|
|
}
|
|
}
|
|
@@ -778,6 +863,7 @@ heap_free :: proc(ptr: rawptr) {
|
|
}
|
|
}
|
|
|
|
|
|
lookup_env :: proc(key: string, allocator := context.allocator) -> (value: string, found: bool) {
|
|
lookup_env :: proc(key: string, allocator := context.allocator) -> (value: string, found: bool) {
|
|
|
|
+ runtime.DEFAULT_TEMP_ALLOCATOR_TEMP_GUARD(ignore = context.temp_allocator == allocator)
|
|
path_str := strings.clone_to_cstring(key, context.temp_allocator)
|
|
path_str := strings.clone_to_cstring(key, context.temp_allocator)
|
|
// NOTE(tetra): Lifetime of 'cstr' is unclear, but _unix_free(cstr) segfaults.
|
|
// NOTE(tetra): Lifetime of 'cstr' is unclear, but _unix_free(cstr) segfaults.
|
|
cstr := _unix_getenv(path_str)
|
|
cstr := _unix_getenv(path_str)
|
|
@@ -793,6 +879,7 @@ get_env :: proc(key: string, allocator := context.allocator) -> (value: string)
|
|
}
|
|
}
|
|
|
|
|
|
set_env :: proc(key, value: string) -> Errno {
|
|
set_env :: proc(key, value: string) -> Errno {
|
|
|
|
+ runtime.DEFAULT_TEMP_ALLOCATOR_TEMP_GUARD()
|
|
s := strings.concatenate({key, "=", value, "\x00"}, context.temp_allocator)
|
|
s := strings.concatenate({key, "=", value, "\x00"}, context.temp_allocator)
|
|
res := _unix_putenv(strings.unsafe_string_to_cstring(s))
|
|
res := _unix_putenv(strings.unsafe_string_to_cstring(s))
|
|
if res < 0 {
|
|
if res < 0 {
|
|
@@ -802,6 +889,7 @@ set_env :: proc(key, value: string) -> Errno {
|
|
}
|
|
}
|
|
|
|
|
|
unset_env :: proc(key: string) -> Errno {
|
|
unset_env :: proc(key: string) -> Errno {
|
|
|
|
+ runtime.DEFAULT_TEMP_ALLOCATOR_TEMP_GUARD()
|
|
s := strings.clone_to_cstring(key, context.temp_allocator)
|
|
s := strings.clone_to_cstring(key, context.temp_allocator)
|
|
res := _unix_putenv(s)
|
|
res := _unix_putenv(s)
|
|
if res < 0 {
|
|
if res < 0 {
|
|
@@ -817,7 +905,7 @@ get_current_directory :: proc() -> string {
|
|
page_size := get_page_size()
|
|
page_size := get_page_size()
|
|
buf := make([dynamic]u8, page_size)
|
|
buf := make([dynamic]u8, page_size)
|
|
for {
|
|
for {
|
|
- #no_bounds_check res := _unix_getcwd(&buf[0], uint(len(buf)))
|
|
|
|
|
|
+ #no_bounds_check res := unix.sys_getcwd(&buf[0], uint(len(buf)))
|
|
|
|
|
|
if res >= 0 {
|
|
if res >= 0 {
|
|
return strings.string_from_nul_terminated_ptr(&buf[0], len(buf))
|
|
return strings.string_from_nul_terminated_ptr(&buf[0], len(buf))
|
|
@@ -832,8 +920,9 @@ get_current_directory :: proc() -> string {
|
|
}
|
|
}
|
|
|
|
|
|
set_current_directory :: proc(path: string) -> (err: Errno) {
|
|
set_current_directory :: proc(path: string) -> (err: Errno) {
|
|
|
|
+ runtime.DEFAULT_TEMP_ALLOCATOR_TEMP_GUARD()
|
|
cstr := strings.clone_to_cstring(path, context.temp_allocator)
|
|
cstr := strings.clone_to_cstring(path, context.temp_allocator)
|
|
- res := _unix_chdir(cstr)
|
|
|
|
|
|
+ res := unix.sys_chdir(cstr)
|
|
if res < 0 {
|
|
if res < 0 {
|
|
return _get_errno(res)
|
|
return _get_errno(res)
|
|
}
|
|
}
|
|
@@ -850,12 +939,14 @@ current_thread_id :: proc "contextless" () -> int {
|
|
}
|
|
}
|
|
|
|
|
|
dlopen :: proc(filename: string, flags: int) -> rawptr {
|
|
dlopen :: proc(filename: string, flags: int) -> rawptr {
|
|
|
|
+ runtime.DEFAULT_TEMP_ALLOCATOR_TEMP_GUARD()
|
|
cstr := strings.clone_to_cstring(filename, context.temp_allocator)
|
|
cstr := strings.clone_to_cstring(filename, context.temp_allocator)
|
|
handle := _unix_dlopen(cstr, c.int(flags))
|
|
handle := _unix_dlopen(cstr, c.int(flags))
|
|
return handle
|
|
return handle
|
|
}
|
|
}
|
|
dlsym :: proc(handle: rawptr, symbol: string) -> rawptr {
|
|
dlsym :: proc(handle: rawptr, symbol: string) -> rawptr {
|
|
assert(handle != nil)
|
|
assert(handle != nil)
|
|
|
|
+ runtime.DEFAULT_TEMP_ALLOCATOR_TEMP_GUARD()
|
|
cstr := strings.clone_to_cstring(symbol, context.temp_allocator)
|
|
cstr := strings.clone_to_cstring(symbol, context.temp_allocator)
|
|
proc_handle := _unix_dlsym(handle, cstr)
|
|
proc_handle := _unix_dlsym(handle, cstr)
|
|
return proc_handle
|
|
return proc_handle
|
|
@@ -892,3 +983,94 @@ _alloc_command_line_arguments :: proc() -> []string {
|
|
}
|
|
}
|
|
return res
|
|
return res
|
|
}
|
|
}
|
|
|
|
+
|
|
|
|
+socket :: proc(domain: int, type: int, protocol: int) -> (Socket, Errno) {
|
|
|
|
+ result := unix.sys_socket(domain, type, protocol)
|
|
|
|
+ if result < 0 {
|
|
|
|
+ return 0, _get_errno(result)
|
|
|
|
+ }
|
|
|
|
+ return Socket(result), ERROR_NONE
|
|
|
|
+}
|
|
|
|
+
|
|
|
|
+bind :: proc(sd: Socket, addr: ^SOCKADDR, len: socklen_t) -> (Errno) {
|
|
|
|
+ result := unix.sys_bind(int(sd), addr, len)
|
|
|
|
+ if result < 0 {
|
|
|
|
+ return _get_errno(result)
|
|
|
|
+ }
|
|
|
|
+ return ERROR_NONE
|
|
|
|
+}
|
|
|
|
+
|
|
|
|
+
|
|
|
|
+connect :: proc(sd: Socket, addr: ^SOCKADDR, len: socklen_t) -> (Errno) {
|
|
|
|
+ result := unix.sys_connect(int(sd), addr, len)
|
|
|
|
+ if result < 0 {
|
|
|
|
+ return _get_errno(result)
|
|
|
|
+ }
|
|
|
|
+ return ERROR_NONE
|
|
|
|
+}
|
|
|
|
+
|
|
|
|
+accept :: proc(sd: Socket, addr: ^SOCKADDR, len: rawptr) -> (Socket, Errno) {
|
|
|
|
+ result := unix.sys_accept(int(sd), rawptr(addr), len)
|
|
|
|
+ if result < 0 {
|
|
|
|
+ return 0, _get_errno(result)
|
|
|
|
+ }
|
|
|
|
+ return Socket(result), ERROR_NONE
|
|
|
|
+}
|
|
|
|
+
|
|
|
|
+listen :: proc(sd: Socket, backlog: int) -> (Errno) {
|
|
|
|
+ result := unix.sys_listen(int(sd), backlog)
|
|
|
|
+ if result < 0 {
|
|
|
|
+ return _get_errno(result)
|
|
|
|
+ }
|
|
|
|
+ return ERROR_NONE
|
|
|
|
+}
|
|
|
|
+
|
|
|
|
+setsockopt :: proc(sd: Socket, level: int, optname: int, optval: rawptr, optlen: socklen_t) -> (Errno) {
|
|
|
|
+ result := unix.sys_setsockopt(int(sd), level, optname, optval, optlen)
|
|
|
|
+ if result < 0 {
|
|
|
|
+ return _get_errno(result)
|
|
|
|
+ }
|
|
|
|
+ return ERROR_NONE
|
|
|
|
+}
|
|
|
|
+
|
|
|
|
+
|
|
|
|
+recvfrom :: proc(sd: Socket, data: []byte, flags: int, addr: ^SOCKADDR, addr_size: ^socklen_t) -> (u32, Errno) {
|
|
|
|
+ result := unix.sys_recvfrom(int(sd), raw_data(data), len(data), flags, addr, uintptr(addr_size))
|
|
|
|
+ if result < 0 {
|
|
|
|
+ return 0, _get_errno(int(result))
|
|
|
|
+ }
|
|
|
|
+ return u32(result), ERROR_NONE
|
|
|
|
+}
|
|
|
|
+
|
|
|
|
+recv :: proc(sd: Socket, data: []byte, flags: int) -> (u32, Errno) {
|
|
|
|
+ result := unix.sys_recvfrom(int(sd), raw_data(data), len(data), flags, nil, 0)
|
|
|
|
+ if result < 0 {
|
|
|
|
+ return 0, _get_errno(int(result))
|
|
|
|
+ }
|
|
|
|
+ return u32(result), ERROR_NONE
|
|
|
|
+}
|
|
|
|
+
|
|
|
|
+
|
|
|
|
+sendto :: proc(sd: Socket, data: []u8, flags: int, addr: ^SOCKADDR, addrlen: socklen_t) -> (u32, Errno) {
|
|
|
|
+ result := unix.sys_sendto(int(sd), raw_data(data), len(data), flags, addr, addrlen)
|
|
|
|
+ if result < 0 {
|
|
|
|
+ return 0, _get_errno(int(result))
|
|
|
|
+ }
|
|
|
|
+ return u32(result), ERROR_NONE
|
|
|
|
+}
|
|
|
|
+
|
|
|
|
+send :: proc(sd: Socket, data: []byte, flags: int) -> (u32, Errno) {
|
|
|
|
+ result := unix.sys_sendto(int(sd), raw_data(data), len(data), 0, nil, 0)
|
|
|
|
+ if result < 0 {
|
|
|
|
+ return 0, _get_errno(int(result))
|
|
|
|
+ }
|
|
|
|
+ return u32(result), ERROR_NONE
|
|
|
|
+}
|
|
|
|
+
|
|
|
|
+shutdown :: proc(sd: Socket, how: int) -> (Errno) {
|
|
|
|
+ result := unix.sys_shutdown(int(sd), how)
|
|
|
|
+ if result < 0 {
|
|
|
|
+ return _get_errno(result)
|
|
|
|
+ }
|
|
|
|
+ return ERROR_NONE
|
|
|
|
+}
|