Add @(require_results)

This commit is contained in:
gingerBill
2024-08-04 15:24:26 +01:00
parent bf948ab8ae
commit c078b2dd1b
14 changed files with 297 additions and 133 deletions
+1
View File
@@ -6,6 +6,7 @@ import "base:runtime"
@(require_results) @(require_results)
read_dir :: proc(fd: Handle, n: int, allocator := context.allocator) -> (fi: []File_Info, err: Error) { read_dir :: proc(fd: Handle, n: int, allocator := context.allocator) -> (fi: []File_Info, err: Error) {
@(require_results)
find_data_to_file_info :: proc(base_path: string, d: ^win32.WIN32_FIND_DATAW) -> (fi: File_Info) { find_data_to_file_info :: proc(base_path: string, d: ^win32.WIN32_FIND_DATAW) -> (fi: File_Info) {
// Ignore "." and ".." // Ignore "." and ".."
if d.cFileName[0] == '.' && d.cFileName[1] == 0 { if d.cFileName[0] == '.' && d.cFileName[1] == 0 {
+6
View File
@@ -139,6 +139,12 @@ _error_string :: proc "contextless" (e: Platform_Error) -> string where intrinsi
return "" return ""
} }
when ODIN_OS == .Darwin {
if s := string(_darwin_string_error(i32(e))); s != "" {
return s
}
}
when ODIN_OS != .Linux { when ODIN_OS != .Linux {
@(require_results) @(require_results)
binary_search :: proc "contextless" (array: $A/[]$T, key: T) -> (index: int, found: bool) #no_bounds_check { binary_search :: proc "contextless" (array: $A/[]$T, key: T) -> (index: int, found: bool) #no_bounds_check {
+11 -3
View File
@@ -5,10 +5,12 @@ import "base:intrinsics"
import "base:runtime" import "base:runtime"
import "core:unicode/utf16" import "core:unicode/utf16"
@(require_results)
is_path_separator :: proc(c: byte) -> bool { is_path_separator :: proc(c: byte) -> bool {
return c == '/' || c == '\\' return c == '/' || c == '\\'
} }
@(require_results)
open :: proc(path: string, mode: int = O_RDONLY, perm: int = 0) -> (Handle, Error) { open :: proc(path: string, mode: int = O_RDONLY, perm: int = 0) -> (Handle, Error) {
if len(path) == 0 { if len(path) == 0 {
return INVALID_HANDLE, General_Error.Not_Exist return INVALID_HANDLE, General_Error.Not_Exist
@@ -96,7 +98,7 @@ write :: proc(fd: Handle, data: []byte) -> (int, Error) {
return int(total_write), nil return int(total_write), nil
} }
@(private="file") @(private="file", require_results)
read_console :: proc(handle: win32.HANDLE, b: []byte) -> (n: int, err: Error) { read_console :: proc(handle: win32.HANDLE, b: []byte) -> (n: int, err: Error) {
if len(b) == 0 { if len(b) == 0 {
return 0, nil return 0, nil
@@ -206,6 +208,7 @@ seek :: proc(fd: Handle, offset: i64, whence: int) -> (i64, Error) {
return i64(hi)<<32 + i64(dw_ptr), nil return i64(hi)<<32 + i64(dw_ptr), nil
} }
@(require_results)
file_size :: proc(fd: Handle) -> (i64, Error) { file_size :: proc(fd: Handle) -> (i64, Error) {
length: win32.LARGE_INTEGER length: win32.LARGE_INTEGER
err: Error err: Error
@@ -331,6 +334,7 @@ stdout := get_std_handle(uint(win32.STD_OUTPUT_HANDLE))
stderr := get_std_handle(uint(win32.STD_ERROR_HANDLE)) stderr := get_std_handle(uint(win32.STD_ERROR_HANDLE))
@(require_results)
get_std_handle :: proc "contextless" (h: uint) -> Handle { get_std_handle :: proc "contextless" (h: uint) -> Handle {
fd := win32.GetStdHandle(win32.DWORD(h)) fd := win32.GetStdHandle(win32.DWORD(h))
return Handle(fd) return Handle(fd)
@@ -345,6 +349,7 @@ exists :: proc(path: string) -> bool {
return attribs != win32.INVALID_FILE_ATTRIBUTES return attribs != win32.INVALID_FILE_ATTRIBUTES
} }
@(require_results)
is_file :: proc(path: string) -> bool { is_file :: proc(path: string) -> bool {
runtime.DEFAULT_TEMP_ALLOCATOR_TEMP_GUARD() runtime.DEFAULT_TEMP_ALLOCATOR_TEMP_GUARD()
wpath := win32.utf8_to_wstring(path, context.temp_allocator) wpath := win32.utf8_to_wstring(path, context.temp_allocator)
@@ -356,6 +361,7 @@ is_file :: proc(path: string) -> bool {
return false return false
} }
@(require_results)
is_dir :: proc(path: string) -> bool { is_dir :: proc(path: string) -> bool {
runtime.DEFAULT_TEMP_ALLOCATOR_TEMP_GUARD() runtime.DEFAULT_TEMP_ALLOCATOR_TEMP_GUARD()
wpath := win32.utf8_to_wstring(path, context.temp_allocator) wpath := win32.utf8_to_wstring(path, context.temp_allocator)
@@ -370,6 +376,7 @@ is_dir :: proc(path: string) -> bool {
// NOTE(tetra): GetCurrentDirectory is not thread safe with SetCurrentDirectory and GetFullPathName // NOTE(tetra): GetCurrentDirectory is not thread safe with SetCurrentDirectory and GetFullPathName
@private cwd_lock := win32.SRWLOCK{} // zero is initialized @private cwd_lock := win32.SRWLOCK{} // zero is initialized
@(require_results)
get_current_directory :: proc(allocator := context.allocator) -> string { get_current_directory :: proc(allocator := context.allocator) -> string {
win32.AcquireSRWLockExclusive(&cwd_lock) win32.AcquireSRWLockExclusive(&cwd_lock)
@@ -426,7 +433,7 @@ remove_directory :: proc(path: string) -> (err: Error) {
@(private) @(private, require_results)
is_abs :: proc(path: string) -> bool { is_abs :: proc(path: string) -> bool {
if len(path) > 0 && path[0] == '/' { if len(path) > 0 && path[0] == '/' {
return true return true
@@ -442,7 +449,7 @@ is_abs :: proc(path: string) -> bool {
return false return false
} }
@(private) @(private, require_results)
fix_long_path :: proc(path: string) -> string { fix_long_path :: proc(path: string) -> string {
if len(path) < 248 { if len(path) < 248 {
return path return path
@@ -574,6 +581,7 @@ remove :: proc(name: string) -> Error {
} }
@(require_results)
pipe :: proc() -> (r, w: Handle, err: Error) { pipe :: proc() -> (r, w: Handle, err: Error) {
sa: win32.SECURITY_ATTRIBUTES sa: win32.SECURITY_ATTRIBUTES
sa.nLength = size_of(win32.SECURITY_ATTRIBUTES) sa.nLength = size_of(win32.SECURITY_ATTRIBUTES)
+44 -21
View File
@@ -562,13 +562,13 @@ S_ISUID :: 0o4000 // Set user id on execution
S_ISGID :: 0o2000 // Set group id on execution S_ISGID :: 0o2000 // Set group id on execution
S_ISVTX :: 0o1000 // Directory restrcted delete S_ISVTX :: 0o1000 // Directory restrcted delete
S_ISLNK :: #force_inline proc(m: u16) -> bool { return (m & S_IFMT) == S_IFLNK } @(require_results) S_ISLNK :: #force_inline proc(m: u16) -> bool { return (m & S_IFMT) == S_IFLNK }
S_ISREG :: #force_inline proc(m: u16) -> bool { return (m & S_IFMT) == S_IFREG } @(require_results) S_ISREG :: #force_inline proc(m: u16) -> bool { return (m & S_IFMT) == S_IFREG }
S_ISDIR :: #force_inline proc(m: u16) -> bool { return (m & S_IFMT) == S_IFDIR } @(require_results) S_ISDIR :: #force_inline proc(m: u16) -> bool { return (m & S_IFMT) == S_IFDIR }
S_ISCHR :: #force_inline proc(m: u16) -> bool { return (m & S_IFMT) == S_IFCHR } @(require_results) S_ISCHR :: #force_inline proc(m: u16) -> bool { return (m & S_IFMT) == S_IFCHR }
S_ISBLK :: #force_inline proc(m: u16) -> bool { return (m & S_IFMT) == S_IFBLK } @(require_results) S_ISBLK :: #force_inline proc(m: u16) -> bool { return (m & S_IFMT) == S_IFBLK }
S_ISFIFO :: #force_inline proc(m: u16) -> bool { return (m & S_IFMT) == S_IFIFO } @(require_results) S_ISFIFO :: #force_inline proc(m: u16) -> bool { return (m & S_IFMT) == S_IFIFO }
S_ISSOCK :: #force_inline proc(m: u16) -> bool { return (m & S_IFMT) == S_IFSOCK } @(require_results) S_ISSOCK :: #force_inline proc(m: u16) -> bool { return (m & S_IFMT) == S_IFSOCK }
R_OK :: 4 // Test for read permission R_OK :: 4 // Test for read permission
W_OK :: 2 // Test for write permission W_OK :: 2 // Test for write permission
@@ -667,11 +667,13 @@ get_last_error :: proc "contextless" () -> Error {
return Platform_Error(__error()^) return Platform_Error(__error()^)
} }
@(require_results)
get_last_error_string :: proc() -> string { get_last_error_string :: proc() -> string {
return string(_darwin_string_error(__error()^)) return string(_darwin_string_error(__error()^))
} }
@(require_results)
open :: proc(path: string, flags: int = O_RDWR, mode: int = 0) -> (handle: Handle, err: Error) { open :: proc(path: string, flags: int = O_RDWR, mode: int = 0) -> (handle: Handle, err: Error) {
isDir := is_dir_path(path) isDir := is_dir_path(path)
flags := flags flags := flags
@@ -790,6 +792,7 @@ seek :: proc(fd: Handle, offset: i64, whence: int) -> (i64, Error) {
return final_offset, nil return final_offset, nil
} }
@(require_results)
file_size :: proc(fd: Handle) -> (i64, Error) { file_size :: proc(fd: Handle) -> (i64, Error) {
prev, _ := seek(fd, 0, SEEK_CUR) prev, _ := seek(fd, 0, SEEK_CUR)
size, err := seek(fd, 0, SEEK_END) size, err := seek(fd, 0, SEEK_END)
@@ -804,12 +807,14 @@ stdin: Handle = 0 // get_std_handle(win32.STD_INPUT_HANDLE);
stdout: Handle = 1 // get_std_handle(win32.STD_OUTPUT_HANDLE); stdout: Handle = 1 // get_std_handle(win32.STD_OUTPUT_HANDLE);
stderr: Handle = 2 // get_std_handle(win32.STD_ERROR_HANDLE); stderr: Handle = 2 // get_std_handle(win32.STD_ERROR_HANDLE);
@(require_results)
last_write_time :: proc(fd: Handle) -> (time: File_Time, err: Error) { last_write_time :: proc(fd: Handle) -> (time: File_Time, err: Error) {
s := _fstat(fd) or_return s := _fstat(fd) or_return
modified := s.modified.seconds * 1_000_000_000 + s.modified.nanoseconds modified := s.modified.seconds * 1_000_000_000 + s.modified.nanoseconds
return File_Time(modified), nil return File_Time(modified), nil
} }
@(require_results)
last_write_time_by_name :: proc(name: string) -> (time: File_Time, err: Error) { last_write_time_by_name :: proc(name: string) -> (time: File_Time, err: Error) {
s := _stat(name) or_return s := _stat(name) or_return
modified := s.modified.seconds * 1_000_000_000 + s.modified.nanoseconds modified := s.modified.seconds * 1_000_000_000 + s.modified.nanoseconds
@@ -817,10 +822,12 @@ last_write_time_by_name :: proc(name: string) -> (time: File_Time, err: Error) {
} }
@(require_results)
is_path_separator :: proc(r: rune) -> bool { is_path_separator :: proc(r: rune) -> bool {
return r == '/' return r == '/'
} }
@(require_results)
is_file_handle :: proc(fd: Handle) -> bool { is_file_handle :: proc(fd: Handle) -> bool {
s, err := _fstat(fd) s, err := _fstat(fd)
if err != nil { if err != nil {
@@ -829,6 +836,7 @@ is_file_handle :: proc(fd: Handle) -> bool {
return S_ISREG(s.mode) return S_ISREG(s.mode)
} }
@(require_results)
is_file_path :: proc(path: string, follow_links: bool = true) -> bool { is_file_path :: proc(path: string, follow_links: bool = true) -> bool {
s: OS_Stat s: OS_Stat
err: Error err: Error
@@ -844,6 +852,7 @@ is_file_path :: proc(path: string, follow_links: bool = true) -> bool {
} }
@(require_results)
is_dir_handle :: proc(fd: Handle) -> bool { is_dir_handle :: proc(fd: Handle) -> bool {
s, err := _fstat(fd) s, err := _fstat(fd)
if err != nil { if err != nil {
@@ -852,6 +861,7 @@ is_dir_handle :: proc(fd: Handle) -> bool {
return S_ISDIR(s.mode) return S_ISDIR(s.mode)
} }
@(require_results)
is_dir_path :: proc(path: string, follow_links: bool = true) -> bool { is_dir_path :: proc(path: string, follow_links: bool = true) -> bool {
s: OS_Stat s: OS_Stat
err: Error err: Error
@@ -869,6 +879,7 @@ is_dir_path :: proc(path: string, follow_links: bool = true) -> bool {
is_file :: proc {is_file_path, is_file_handle} 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}
@(require_results)
exists :: proc(path: string) -> bool { exists :: proc(path: string) -> bool {
runtime.DEFAULT_TEMP_ALLOCATOR_TEMP_GUARD() runtime.DEFAULT_TEMP_ALLOCATOR_TEMP_GUARD()
cpath := strings.clone_to_cstring(path, context.temp_allocator) cpath := strings.clone_to_cstring(path, context.temp_allocator)
@@ -893,7 +904,7 @@ remove :: proc(path: string) -> Error {
return nil return nil
} }
@private @(private, require_results)
_stat :: proc(path: string) -> (OS_Stat, Error) { _stat :: proc(path: string) -> (OS_Stat, Error) {
runtime.DEFAULT_TEMP_ALLOCATOR_TEMP_GUARD() runtime.DEFAULT_TEMP_ALLOCATOR_TEMP_GUARD()
cstr := strings.clone_to_cstring(path, context.temp_allocator) cstr := strings.clone_to_cstring(path, context.temp_allocator)
@@ -906,7 +917,7 @@ _stat :: proc(path: string) -> (OS_Stat, Error) {
return s, nil return s, nil
} }
@private @(private, require_results)
_lstat :: proc(path: string) -> (OS_Stat, Error) { _lstat :: proc(path: string) -> (OS_Stat, Error) {
runtime.DEFAULT_TEMP_ALLOCATOR_TEMP_GUARD() runtime.DEFAULT_TEMP_ALLOCATOR_TEMP_GUARD()
cstr := strings.clone_to_cstring(path, context.temp_allocator) cstr := strings.clone_to_cstring(path, context.temp_allocator)
@@ -919,7 +930,7 @@ _lstat :: proc(path: string) -> (OS_Stat, Error) {
return s, nil return s, nil
} }
@private @(private, require_results)
_fstat :: proc(fd: Handle) -> (OS_Stat, Error) { _fstat :: proc(fd: Handle) -> (OS_Stat, Error) {
s: OS_Stat s: OS_Stat
result := _unix_fstat(fd, &s) result := _unix_fstat(fd, &s)
@@ -929,7 +940,7 @@ _fstat :: proc(fd: Handle) -> (OS_Stat, Error) {
return s, nil return s, nil
} }
@private @(private, require_results)
_fdopendir :: proc(fd: Handle) -> (Dir, Error) { _fdopendir :: proc(fd: Handle) -> (Dir, Error) {
dirp := _unix_fdopendir(fd) dirp := _unix_fdopendir(fd)
if dirp == cast(Dir)nil { if dirp == cast(Dir)nil {
@@ -938,7 +949,7 @@ _fdopendir :: proc(fd: Handle) -> (Dir, Error) {
return dirp, nil return dirp, nil
} }
@private @(private)
_closedir :: proc(dirp: Dir) -> Error { _closedir :: proc(dirp: Dir) -> Error {
rc := _unix_closedir(dirp) rc := _unix_closedir(dirp)
if rc != 0 { if rc != 0 {
@@ -947,12 +958,12 @@ _closedir :: proc(dirp: Dir) -> Error {
return nil return nil
} }
@private @(private)
_rewinddir :: proc(dirp: Dir) { _rewinddir :: proc(dirp: Dir) {
_unix_rewinddir(dirp) _unix_rewinddir(dirp)
} }
@private @(private, require_results)
_readdir :: proc(dirp: Dir) -> (entry: Dirent, err: Error, end_of_stream: bool) { _readdir :: proc(dirp: Dir) -> (entry: Dirent, err: Error, end_of_stream: bool) {
result: ^Dirent result: ^Dirent
rc := _unix_readdir_r(dirp, &entry, &result) rc := _unix_readdir_r(dirp, &entry, &result)
@@ -971,7 +982,7 @@ _readdir :: proc(dirp: Dir) -> (entry: Dirent, err: Error, end_of_stream: bool)
return return
} }
@private @(private, require_results)
_readlink :: proc(path: string) -> (string, Error) { _readlink :: proc(path: string) -> (string, Error) {
runtime.DEFAULT_TEMP_ALLOCATOR_TEMP_GUARD(ignore = context.temp_allocator == context.allocator) 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)
@@ -994,12 +1005,14 @@ _readlink :: proc(path: string) -> (string, Error) {
} }
} }
@(require_results)
absolute_path_from_handle :: proc(fd: Handle) -> (path: string, err: Error) { absolute_path_from_handle :: proc(fd: Handle) -> (path: string, err: Error) {
buf: [DARWIN_MAXPATHLEN]byte buf: [DARWIN_MAXPATHLEN]byte
_ = fcntl(int(fd), F_GETPATH, int(uintptr(&buf[0]))) or_return _ = fcntl(int(fd), F_GETPATH, int(uintptr(&buf[0]))) or_return
return strings.clone_from_cstring(cstring(&buf[0])) return strings.clone_from_cstring(cstring(&buf[0]))
} }
@(require_results)
absolute_path_from_relative :: proc(rel: string) -> (path: string, err: Error) { absolute_path_from_relative :: proc(rel: string) -> (path: string, err: Error) {
rel := rel rel := rel
if rel == "" { if rel == "" {
@@ -1031,6 +1044,7 @@ flush :: proc(fd: Handle) -> Error {
return cast(Platform_Error)_unix_fsync(fd) return cast(Platform_Error)_unix_fsync(fd)
} }
@(require_results)
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) 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)
@@ -1041,6 +1055,7 @@ lookup_env :: proc(key: string, allocator := context.allocator) -> (value: strin
return strings.clone(string(cstr), allocator), true return strings.clone(string(cstr), allocator), true
} }
@(require_results)
get_env :: proc(key: string, allocator := context.allocator) -> (value: string) { get_env :: proc(key: string, allocator := context.allocator) -> (value: string) {
value, _ = lookup_env(key, allocator) value, _ = lookup_env(key, allocator)
return return
@@ -1067,6 +1082,7 @@ unset_env :: proc(key: string) -> Error {
return nil return nil
} }
@(require_results)
get_current_directory :: proc() -> string { get_current_directory :: proc() -> string {
page_size := get_page_size() // NOTE(tetra): See note in os_linux.odin/get_current_directory. page_size := get_page_size() // NOTE(tetra): See note in os_linux.odin/get_current_directory.
buf := make([dynamic]u8, page_size) buf := make([dynamic]u8, page_size)
@@ -1109,6 +1125,7 @@ exit :: proc "contextless" (code: int) -> ! {
_unix_exit(i32(code)) _unix_exit(i32(code))
} }
@(require_results)
current_thread_id :: proc "contextless" () -> int { current_thread_id :: proc "contextless" () -> int {
tid: u64 tid: u64
// NOTE(Oskar): available from OSX 10.6 and iOS 3.2. // NOTE(Oskar): available from OSX 10.6 and iOS 3.2.
@@ -1119,12 +1136,14 @@ current_thread_id :: proc "contextless" () -> int {
return int(tid) return int(tid)
} }
@(require_results)
dlopen :: proc(filename: string, flags: int) -> rawptr { dlopen :: proc(filename: string, flags: int) -> rawptr {
runtime.DEFAULT_TEMP_ALLOCATOR_TEMP_GUARD() 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, flags) handle := _unix_dlopen(cstr, flags)
return handle return handle
} }
@(require_results)
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() runtime.DEFAULT_TEMP_ALLOCATOR_TEMP_GUARD()
@@ -1140,6 +1159,7 @@ dlerror :: proc() -> string {
return string(_unix_dlerror()) return string(_unix_dlerror())
} }
@(require_results)
get_page_size :: proc() -> int { get_page_size :: proc() -> int {
// NOTE(tetra): The page size never changes, so why do anything complicated // NOTE(tetra): The page size never changes, so why do anything complicated
// if we don't have to. // if we don't have to.
@@ -1152,7 +1172,7 @@ get_page_size :: proc() -> int {
return page_size return page_size
} }
@(private) @(private, require_results)
_processor_core_count :: proc() -> int { _processor_core_count :: proc() -> int {
count : int = 0 count : int = 0
count_size := size_of(count) count_size := size_of(count)
@@ -1165,6 +1185,7 @@ _processor_core_count :: proc() -> int {
return 1 return 1
} }
@(require_results)
_alloc_command_line_arguments :: proc() -> []string { _alloc_command_line_arguments :: proc() -> []string {
res := make([]string, len(runtime.args__)) res := make([]string, len(runtime.args__))
for _, i in res { for _, i in res {
@@ -1173,6 +1194,7 @@ _alloc_command_line_arguments :: proc() -> []string {
return res return res
} }
@(require_results)
socket :: proc(domain: int, type: int, protocol: int) -> (Socket, Error) { socket :: proc(domain: int, type: int, protocol: int) -> (Socket, Error) {
result := _unix_socket(domain, type, protocol) result := _unix_socket(domain, type, protocol)
if result < 0 { if result < 0 {
@@ -1181,7 +1203,8 @@ socket :: proc(domain: int, type: int, protocol: int) -> (Socket, Error) {
return Socket(result), nil return Socket(result), nil
} }
connect :: proc(sd: Socket, addr: ^SOCKADDR, len: socklen_t) -> (Error) { @(require_results)
connect :: proc(sd: Socket, addr: ^SOCKADDR, len: socklen_t) -> Error {
result := _unix_connect(int(sd), addr, len) result := _unix_connect(int(sd), addr, len)
if result < 0 { if result < 0 {
return get_last_error() return get_last_error()
@@ -1189,7 +1212,7 @@ connect :: proc(sd: Socket, addr: ^SOCKADDR, len: socklen_t) -> (Error) {
return nil return nil
} }
bind :: proc(sd: Socket, addr: ^SOCKADDR, len: socklen_t) -> (Error) { bind :: proc(sd: Socket, addr: ^SOCKADDR, len: socklen_t) -> Error {
result := _unix_bind(int(sd), addr, len) result := _unix_bind(int(sd), addr, len)
if result < 0 { if result < 0 {
return get_last_error() return get_last_error()
@@ -1205,7 +1228,7 @@ accept :: proc(sd: Socket, addr: ^SOCKADDR, len: rawptr) -> (Socket, Error) {
return Socket(result), nil return Socket(result), nil
} }
listen :: proc(sd: Socket, backlog: int) -> (Error) { listen :: proc(sd: Socket, backlog: int) -> Error {
result := _unix_listen(int(sd), backlog) result := _unix_listen(int(sd), backlog)
if result < 0 { if result < 0 {
return get_last_error() return get_last_error()
@@ -1213,7 +1236,7 @@ listen :: proc(sd: Socket, backlog: int) -> (Error) {
return nil return nil
} }
setsockopt :: proc(sd: Socket, level: int, optname: int, optval: rawptr, optlen: socklen_t) -> (Error) { setsockopt :: proc(sd: Socket, level: int, optname: int, optval: rawptr, optlen: socklen_t) -> Error {
result := _unix_setsockopt(int(sd), level, optname, optval, optlen) result := _unix_setsockopt(int(sd), level, optname, optval, optlen)
if result < 0 { if result < 0 {
return get_last_error() return get_last_error()
@@ -1261,7 +1284,7 @@ send :: proc(sd: Socket, data: []byte, flags: int) -> (u32, Error) {
return u32(result), nil return u32(result), nil
} }
shutdown :: proc(sd: Socket, how: int) -> (Error) { shutdown :: proc(sd: Socket, how: int) -> Error {
result := _unix_shutdown(int(sd), how) result := _unix_shutdown(int(sd), how)
if result < 0 { if result < 0 {
return get_last_error() return get_last_error()
+35 -16
View File
@@ -353,13 +353,13 @@ S_ISGID :: 0o2000 // Set group id on execution
S_ISVTX :: 0o1000 // Directory restrcted delete S_ISVTX :: 0o1000 // Directory restrcted delete
S_ISLNK :: #force_inline proc(m: mode_t) -> bool { return (m & S_IFMT) == S_IFLNK } @(require_results) S_ISLNK :: #force_inline proc(m: mode_t) -> bool { return (m & S_IFMT) == S_IFLNK }
S_ISREG :: #force_inline proc(m: mode_t) -> bool { return (m & S_IFMT) == S_IFREG } @(require_results) S_ISREG :: #force_inline proc(m: mode_t) -> bool { return (m & S_IFMT) == S_IFREG }
S_ISDIR :: #force_inline proc(m: mode_t) -> bool { return (m & S_IFMT) == S_IFDIR } @(require_results) S_ISDIR :: #force_inline proc(m: mode_t) -> bool { return (m & S_IFMT) == S_IFDIR }
S_ISCHR :: #force_inline proc(m: mode_t) -> bool { return (m & S_IFMT) == S_IFCHR } @(require_results) S_ISCHR :: #force_inline proc(m: mode_t) -> bool { return (m & S_IFMT) == S_IFCHR }
S_ISBLK :: #force_inline proc(m: mode_t) -> bool { return (m & S_IFMT) == S_IFBLK } @(require_results) S_ISBLK :: #force_inline proc(m: mode_t) -> bool { return (m & S_IFMT) == S_IFBLK }
S_ISFIFO :: #force_inline proc(m: mode_t) -> bool { return (m & S_IFMT) == S_IFIFO } @(require_results) S_ISFIFO :: #force_inline proc(m: mode_t) -> bool { return (m & S_IFMT) == S_IFIFO }
S_ISSOCK :: #force_inline proc(m: mode_t) -> bool { return (m & S_IFMT) == S_IFSOCK } @(require_results) S_ISSOCK :: #force_inline proc(m: mode_t) -> bool { return (m & S_IFMT) == S_IFSOCK }
F_OK :: 0 // Test for file existance F_OK :: 0 // Test for file existance
X_OK :: 1 // Test for execute permission X_OK :: 1 // Test for execute permission
@@ -415,6 +415,7 @@ foreign dl {
@(link_name="pthread_getthreadid_np") pthread_getthreadid_np :: proc() -> c.int --- @(link_name="pthread_getthreadid_np") pthread_getthreadid_np :: proc() -> c.int ---
} }
@(require_results)
is_path_separator :: proc(r: rune) -> bool { is_path_separator :: proc(r: rune) -> bool {
return r == '/' return r == '/'
} }
@@ -424,6 +425,7 @@ get_last_error :: proc "contextless" () -> Error {
return Platform_Error(__Error_location()^) return Platform_Error(__Error_location()^)
} }
@(require_results)
open :: proc(path: string, flags: int = O_RDONLY, mode: int = 0) -> (Handle, Error) { open :: proc(path: string, flags: int = O_RDONLY, mode: int = 0) -> (Handle, Error) {
runtime.DEFAULT_TEMP_ALLOCATOR_TEMP_GUARD() runtime.DEFAULT_TEMP_ALLOCATOR_TEMP_GUARD()
cstr := strings.clone_to_cstring(path, context.temp_allocator) cstr := strings.clone_to_cstring(path, context.temp_allocator)
@@ -505,6 +507,7 @@ seek :: proc(fd: Handle, offset: i64, whence: int) -> (i64, Error) {
return res, nil return res, nil
} }
@(require_results)
file_size :: proc(fd: Handle) -> (size: i64, err: Error) { file_size :: proc(fd: Handle) -> (size: i64, err: Error) {
size = -1 size = -1
s := _fstat(fd) or_return s := _fstat(fd) or_return
@@ -553,6 +556,7 @@ remove_directory :: proc(path: string) -> Error {
return nil return nil
} }
@(require_results)
is_file_handle :: proc(fd: Handle) -> bool { is_file_handle :: proc(fd: Handle) -> bool {
s, err := _fstat(fd) s, err := _fstat(fd)
if err != nil { if err != nil {
@@ -561,6 +565,7 @@ is_file_handle :: proc(fd: Handle) -> bool {
return S_ISREG(s.mode) return S_ISREG(s.mode)
} }
@(require_results)
is_file_path :: proc(path: string, follow_links: bool = true) -> bool { is_file_path :: proc(path: string, follow_links: bool = true) -> bool {
s: OS_Stat s: OS_Stat
err: Error err: Error
@@ -575,6 +580,7 @@ is_file_path :: proc(path: string, follow_links: bool = true) -> bool {
return S_ISREG(s.mode) return S_ISREG(s.mode)
} }
@(require_results)
is_dir_handle :: proc(fd: Handle) -> bool { is_dir_handle :: proc(fd: Handle) -> bool {
s, err := _fstat(fd) s, err := _fstat(fd)
if err != nil { if err != nil {
@@ -583,6 +589,7 @@ is_dir_handle :: proc(fd: Handle) -> bool {
return S_ISDIR(s.mode) return S_ISDIR(s.mode)
} }
@(require_results)
is_dir_path :: proc(path: string, follow_links: bool = true) -> bool { is_dir_path :: proc(path: string, follow_links: bool = true) -> bool {
s: OS_Stat s: OS_Stat
err: Error err: Error
@@ -610,6 +617,7 @@ stderr: Handle = 2
last_write_time :: proc(fd: Handle) -> File_Time {} last_write_time :: proc(fd: Handle) -> File_Time {}
last_write_time_by_name :: proc(name: string) -> File_Time {} last_write_time_by_name :: proc(name: string) -> File_Time {}
*/ */
@(require_results)
last_write_time :: proc(fd: Handle) -> (File_Time, Error) { last_write_time :: proc(fd: Handle) -> (File_Time, Error) {
s, err := _fstat(fd) s, err := _fstat(fd)
if err != nil { if err != nil {
@@ -619,6 +627,7 @@ last_write_time :: proc(fd: Handle) -> (File_Time, Error) {
return File_Time(modified), nil return File_Time(modified), nil
} }
@(require_results)
last_write_time_by_name :: proc(name: string) -> (File_Time, Error) { last_write_time_by_name :: proc(name: string) -> (File_Time, Error) {
s, err := _stat(name) s, err := _stat(name)
if err != nil { if err != nil {
@@ -628,7 +637,7 @@ last_write_time_by_name :: proc(name: string) -> (File_Time, Error) {
return File_Time(modified), nil return File_Time(modified), nil
} }
@private @(private, require_results)
_stat :: proc(path: string) -> (OS_Stat, Error) { _stat :: proc(path: string) -> (OS_Stat, Error) {
runtime.DEFAULT_TEMP_ALLOCATOR_TEMP_GUARD() runtime.DEFAULT_TEMP_ALLOCATOR_TEMP_GUARD()
cstr := strings.clone_to_cstring(path, context.temp_allocator) cstr := strings.clone_to_cstring(path, context.temp_allocator)
@@ -640,7 +649,7 @@ _stat :: proc(path: string) -> (OS_Stat, Error) {
return s, nil return s, nil
} }
@private @(private, require_results)
_lstat :: proc(path: string) -> (OS_Stat, Error) { _lstat :: proc(path: string) -> (OS_Stat, Error) {
runtime.DEFAULT_TEMP_ALLOCATOR_TEMP_GUARD() runtime.DEFAULT_TEMP_ALLOCATOR_TEMP_GUARD()
cstr := strings.clone_to_cstring(path, context.temp_allocator) cstr := strings.clone_to_cstring(path, context.temp_allocator)
@@ -654,7 +663,7 @@ _lstat :: proc(path: string) -> (OS_Stat, Error) {
return s, nil return s, nil
} }
@private @(private, require_results)
_fstat :: proc(fd: Handle) -> (OS_Stat, Error) { _fstat :: proc(fd: Handle) -> (OS_Stat, Error) {
s: OS_Stat = --- s: OS_Stat = ---
result := _unix_fstat(fd, &s) result := _unix_fstat(fd, &s)
@@ -664,7 +673,7 @@ _fstat :: proc(fd: Handle) -> (OS_Stat, Error) {
return s, nil return s, nil
} }
@private @(private, require_results)
_fdopendir :: proc(fd: Handle) -> (Dir, Error) { _fdopendir :: proc(fd: Handle) -> (Dir, Error) {
dirp := _unix_fdopendir(fd) dirp := _unix_fdopendir(fd)
if dirp == cast(Dir)nil { if dirp == cast(Dir)nil {
@@ -673,7 +682,7 @@ _fdopendir :: proc(fd: Handle) -> (Dir, Error) {
return dirp, nil return dirp, nil
} }
@private @(private)
_closedir :: proc(dirp: Dir) -> Error { _closedir :: proc(dirp: Dir) -> Error {
rc := _unix_closedir(dirp) rc := _unix_closedir(dirp)
if rc != 0 { if rc != 0 {
@@ -682,12 +691,12 @@ _closedir :: proc(dirp: Dir) -> Error {
return nil return nil
} }
@private @(private)
_rewinddir :: proc(dirp: Dir) { _rewinddir :: proc(dirp: Dir) {
_unix_rewinddir(dirp) _unix_rewinddir(dirp)
} }
@private @(private, require_results)
_readdir :: proc(dirp: Dir) -> (entry: Dirent, err: Error, end_of_stream: bool) { _readdir :: proc(dirp: Dir) -> (entry: Dirent, err: Error, end_of_stream: bool) {
result: ^Dirent result: ^Dirent
rc := _unix_readdir_r(dirp, &entry, &result) rc := _unix_readdir_r(dirp, &entry, &result)
@@ -705,7 +714,7 @@ _readdir :: proc(dirp: Dir) -> (entry: Dirent, err: Error, end_of_stream: bool)
return return
} }
@private @(private, require_results)
_readlink :: proc(path: string) -> (string, Error) { _readlink :: proc(path: string) -> (string, Error) {
runtime.DEFAULT_TEMP_ALLOCATOR_TEMP_GUARD(ignore = context.temp_allocator == context.allocator) runtime.DEFAULT_TEMP_ALLOCATOR_TEMP_GUARD(ignore = context.temp_allocator == context.allocator)
@@ -730,6 +739,7 @@ _readlink :: proc(path: string) -> (string, Error) {
return "", Error{} return "", Error{}
} }
@(require_results)
absolute_path_from_handle :: proc(fd: Handle) -> (string, Error) { absolute_path_from_handle :: proc(fd: Handle) -> (string, Error) {
// NOTE(Feoramund): The situation isn't ideal, but this was the best way I // NOTE(Feoramund): The situation isn't ideal, but this was the best way I
// could find to implement this. There are a couple outstanding bug reports // could find to implement this. There are a couple outstanding bug reports
@@ -752,6 +762,7 @@ absolute_path_from_handle :: proc(fd: Handle) -> (string, Error) {
return path, nil return path, nil
} }
@(require_results)
absolute_path_from_relative :: proc(rel: string) -> (path: string, err: Error) { absolute_path_from_relative :: proc(rel: string) -> (path: string, err: Error) {
rel := rel rel := rel
if rel == "" { if rel == "" {
@@ -784,6 +795,7 @@ access :: proc(path: string, mask: int) -> (bool, Error) {
return true, nil return true, nil
} }
@(require_results)
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) runtime.DEFAULT_TEMP_ALLOCATOR_TEMP_GUARD(ignore = context.temp_allocator == allocator)
@@ -795,11 +807,13 @@ lookup_env :: proc(key: string, allocator := context.allocator) -> (value: strin
return strings.clone(string(cstr), allocator), true return strings.clone(string(cstr), allocator), true
} }
@(require_results)
get_env :: proc(key: string, allocator := context.allocator) -> (value: string) { get_env :: proc(key: string, allocator := context.allocator) -> (value: string) {
value, _ = lookup_env(key, allocator) value, _ = lookup_env(key, allocator)
return return
} }
@(require_results)
get_current_directory :: proc() -> string { get_current_directory :: proc() -> string {
// NOTE(tetra): I would use PATH_MAX here, but I was not able to find // NOTE(tetra): I would use PATH_MAX here, but I was not able to find
// an authoritative value for it across all systems. // an authoritative value for it across all systems.
@@ -835,16 +849,19 @@ exit :: proc "contextless" (code: int) -> ! {
_unix_exit(c.int(code)) _unix_exit(c.int(code))
} }
@(require_results)
current_thread_id :: proc "contextless" () -> int { current_thread_id :: proc "contextless" () -> int {
return cast(int) pthread_getthreadid_np() return cast(int) pthread_getthreadid_np()
} }
@(require_results)
dlopen :: proc(filename: string, flags: int) -> rawptr { dlopen :: proc(filename: string, flags: int) -> rawptr {
runtime.DEFAULT_TEMP_ALLOCATOR_TEMP_GUARD() 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
} }
@(require_results)
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() runtime.DEFAULT_TEMP_ALLOCATOR_TEMP_GUARD()
@@ -860,6 +877,7 @@ dlerror :: proc() -> string {
return string(_unix_dlerror()) return string(_unix_dlerror())
} }
@(require_results)
get_page_size :: proc() -> int { get_page_size :: proc() -> int {
// NOTE(tetra): The page size never changes, so why do anything complicated // NOTE(tetra): The page size never changes, so why do anything complicated
// if we don't have to. // if we don't have to.
@@ -872,7 +890,7 @@ get_page_size :: proc() -> int {
return page_size return page_size
} }
@(private) @(private, require_results)
_processor_core_count :: proc() -> int { _processor_core_count :: proc() -> int {
count : int = 0 count : int = 0
count_size := size_of(count) count_size := size_of(count)
@@ -886,6 +904,7 @@ _processor_core_count :: proc() -> int {
} }
@(require_results)
_alloc_command_line_arguments :: proc() -> []string { _alloc_command_line_arguments :: proc() -> []string {
res := make([]string, len(runtime.args__)) res := make([]string, len(runtime.args__))
for arg, i in runtime.args__ { for arg, i in runtime.args__ {
+18 -9
View File
@@ -177,6 +177,7 @@ Dirent :: struct {
Dir :: distinct rawptr // DIR* Dir :: distinct rawptr // DIR*
@(require_results)
is_path_separator :: proc(r: rune) -> bool { is_path_separator :: proc(r: rune) -> bool {
return r == '/' return r == '/'
} }
@@ -186,6 +187,7 @@ get_last_error :: proc "contextless" () -> Error {
return Platform_Error(__error()^) return Platform_Error(__error()^)
} }
@(require_results)
fork :: proc() -> (Pid, Error) { fork :: proc() -> (Pid, Error) {
pid := _unix_fork() pid := _unix_fork()
if pid == -1 { if pid == -1 {
@@ -194,6 +196,7 @@ fork :: proc() -> (Pid, Error) {
return Pid(pid), nil return Pid(pid), nil
} }
@(require_results)
open :: proc(path: string, flags: int = O_RDONLY, mode: int = 0) -> (Handle, Error) { open :: proc(path: string, flags: int = O_RDONLY, mode: int = 0) -> (Handle, Error) {
runtime.DEFAULT_TEMP_ALLOCATOR_TEMP_GUARD() runtime.DEFAULT_TEMP_ALLOCATOR_TEMP_GUARD()
cstr := strings.clone_to_cstring(path, context.temp_allocator) cstr := strings.clone_to_cstring(path, context.temp_allocator)
@@ -274,6 +277,7 @@ seek :: proc(fd: Handle, offset: i64, whence: int) -> (i64, Error) {
return res, nil return res, nil
} }
@(require_results)
file_size :: proc(fd: Handle) -> (i64, Error) { file_size :: proc(fd: Handle) -> (i64, Error) {
s, err := _fstat(fd) s, err := _fstat(fd)
if err != nil { if err != nil {
@@ -285,6 +289,7 @@ file_size :: proc(fd: Handle) -> (i64, Error) {
// "Argv" arguments converted to Odin strings // "Argv" arguments converted to Odin strings
args := _alloc_command_line_arguments() args := _alloc_command_line_arguments()
@(require_results)
_alloc_command_line_arguments :: proc() -> []string { _alloc_command_line_arguments :: proc() -> []string {
res := make([]string, len(runtime.args__)) res := make([]string, len(runtime.args__))
for arg, i in runtime.args__ { for arg, i in runtime.args__ {
@@ -293,7 +298,7 @@ _alloc_command_line_arguments :: proc() -> []string {
return res return res
} }
@private @(private, require_results)
_stat :: proc(path: string) -> (OS_Stat, Error) { _stat :: proc(path: string) -> (OS_Stat, Error) {
runtime.DEFAULT_TEMP_ALLOCATOR_TEMP_GUARD() runtime.DEFAULT_TEMP_ALLOCATOR_TEMP_GUARD()
cstr := strings.clone_to_cstring(path, context.temp_allocator) cstr := strings.clone_to_cstring(path, context.temp_allocator)
@@ -307,7 +312,7 @@ _stat :: proc(path: string) -> (OS_Stat, Error) {
return s, nil return s, nil
} }
@private @(private, require_results)
_lstat :: proc(path: string) -> (OS_Stat, Error) { _lstat :: proc(path: string) -> (OS_Stat, Error) {
runtime.DEFAULT_TEMP_ALLOCATOR_TEMP_GUARD() runtime.DEFAULT_TEMP_ALLOCATOR_TEMP_GUARD()
cstr := strings.clone_to_cstring(path, context.temp_allocator) cstr := strings.clone_to_cstring(path, context.temp_allocator)
@@ -321,7 +326,7 @@ _lstat :: proc(path: string) -> (OS_Stat, Error) {
return s, nil return s, nil
} }
@private @(private, require_results)
_fstat :: proc(fd: Handle) -> (OS_Stat, Error) { _fstat :: proc(fd: Handle) -> (OS_Stat, Error) {
// deliberately uninitialized // deliberately uninitialized
s: OS_Stat = --- s: OS_Stat = ---
@@ -332,7 +337,7 @@ _fstat :: proc(fd: Handle) -> (OS_Stat, Error) {
return s, nil return s, nil
} }
@private @(private)
_fdopendir :: proc(fd: Handle) -> (Dir, Error) { _fdopendir :: proc(fd: Handle) -> (Dir, Error) {
dirp := _unix_fdopendir(fd) dirp := _unix_fdopendir(fd)
if dirp == cast(Dir)nil { if dirp == cast(Dir)nil {
@@ -341,7 +346,7 @@ _fdopendir :: proc(fd: Handle) -> (Dir, Error) {
return dirp, nil return dirp, nil
} }
@private @(private)
_closedir :: proc(dirp: Dir) -> Error { _closedir :: proc(dirp: Dir) -> Error {
rc := _unix_closedir(dirp) rc := _unix_closedir(dirp)
if rc != 0 { if rc != 0 {
@@ -350,12 +355,12 @@ _closedir :: proc(dirp: Dir) -> Error {
return nil return nil
} }
@private @(private)
_rewinddir :: proc(dirp: Dir) { _rewinddir :: proc(dirp: Dir) {
_unix_rewinddir(dirp) _unix_rewinddir(dirp)
} }
@private @(private, require_results)
_readdir :: proc(dirp: Dir) -> (entry: Dirent, err: Error, end_of_stream: bool) { _readdir :: proc(dirp: Dir) -> (entry: Dirent, err: Error, end_of_stream: bool) {
result: ^Dirent result: ^Dirent
rc := _unix_readdir_r(dirp, &entry, &result) rc := _unix_readdir_r(dirp, &entry, &result)
@@ -373,7 +378,7 @@ _readdir :: proc(dirp: Dir) -> (entry: Dirent, err: Error, end_of_stream: bool)
return return
} }
@private @(private, require_results)
_readlink :: proc(path: string) -> (string, Error) { _readlink :: proc(path: string) -> (string, Error) {
runtime.DEFAULT_TEMP_ALLOCATOR_TEMP_GUARD(ignore = context.temp_allocator == context.allocator) 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)
@@ -395,10 +400,12 @@ _readlink :: proc(path: string) -> (string, Error) {
} }
} }
@(require_results)
absolute_path_from_handle :: proc(fd: Handle) -> (string, Error) { absolute_path_from_handle :: proc(fd: Handle) -> (string, Error) {
return "", Error(ENOSYS) return "", Error(ENOSYS)
} }
@(require_results)
absolute_path_from_relative :: proc(rel: string) -> (path: string, err: Error) { absolute_path_from_relative :: proc(rel: string) -> (path: string, err: Error) {
rel := rel rel := rel
if rel == "" { if rel == "" {
@@ -430,6 +437,7 @@ access :: proc(path: string, mask: int) -> (bool, Error) {
return true, nil return true, nil
} }
@(require_results)
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) 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)
@@ -440,12 +448,13 @@ lookup_env :: proc(key: string, allocator := context.allocator) -> (value: strin
return strings.clone(string(cstr), allocator), true return strings.clone(string(cstr), allocator), true
} }
@(require_results)
get_env :: proc(key: string, allocator := context.allocator) -> (value: string) { get_env :: proc(key: string, allocator := context.allocator) -> (value: string) {
value, _ = lookup_env(key, allocator) value, _ = lookup_env(key, allocator)
return return
} }
@(private) @(private, require_results)
_processor_core_count :: proc() -> int { _processor_core_count :: proc() -> int {
info: haiku.system_info info: haiku.system_info
haiku.get_system_info(&info) haiku.get_system_info(&info)
+18 -3
View File
@@ -3,10 +3,12 @@ package os
import "base:runtime" import "base:runtime"
@(require_results)
is_path_separator :: proc(c: byte) -> bool { is_path_separator :: proc(c: byte) -> bool {
return c == '/' || c == '\\' return c == '/' || c == '\\'
} }
@(require_results)
open :: proc(path: string, mode: int = O_RDONLY, perm: int = 0) -> (Handle, Error) { open :: proc(path: string, mode: int = O_RDONLY, perm: int = 0) -> (Handle, Error) {
unimplemented("core:os procedure not supported on JS target") unimplemented("core:os procedure not supported on JS target")
} }
@@ -38,6 +40,7 @@ seek :: proc(fd: Handle, offset: i64, whence: int) -> (i64, Error) {
unimplemented("core:os procedure not supported on JS target") unimplemented("core:os procedure not supported on JS target")
} }
@(require_results)
file_size :: proc(fd: Handle) -> (i64, Error) { file_size :: proc(fd: Handle) -> (i64, Error) {
unimplemented("core:os procedure not supported on JS target") unimplemented("core:os procedure not supported on JS target")
} }
@@ -65,20 +68,24 @@ write_at :: proc(fd: Handle, data: []byte, offset: i64) -> (n: int, err: Error)
stdout: Handle = 1 stdout: Handle = 1
stderr: Handle = 2 stderr: Handle = 2
@(require_results)
get_std_handle :: proc "contextless" (h: uint) -> Handle { get_std_handle :: proc "contextless" (h: uint) -> Handle {
context = runtime.default_context() context = runtime.default_context()
unimplemented("core:os procedure not supported on JS target") unimplemented("core:os procedure not supported on JS target")
} }
@(require_results)
exists :: proc(path: string) -> bool { exists :: proc(path: string) -> bool {
unimplemented("core:os procedure not supported on JS target") unimplemented("core:os procedure not supported on JS target")
} }
@(require_results)
is_file :: proc(path: string) -> bool { is_file :: proc(path: string) -> bool {
unimplemented("core:os procedure not supported on JS target") unimplemented("core:os procedure not supported on JS target")
} }
@(require_results)
is_dir :: proc(path: string) -> bool { is_dir :: proc(path: string) -> bool {
unimplemented("core:os procedure not supported on JS target") unimplemented("core:os procedure not supported on JS target")
} }
@@ -86,6 +93,7 @@ is_dir :: proc(path: string) -> bool {
// NOTE(tetra): GetCurrentDirectory is not thread safe with SetCurrentDirectory and GetFullPathName // NOTE(tetra): GetCurrentDirectory is not thread safe with SetCurrentDirectory and GetFullPathName
//@private cwd_lock := win32.SRWLOCK{} // zero is initialized //@private cwd_lock := win32.SRWLOCK{} // zero is initialized
@(require_results)
get_current_directory :: proc(allocator := context.allocator) -> string { get_current_directory :: proc(allocator := context.allocator) -> string {
unimplemented("core:os procedure not supported on JS target") unimplemented("core:os procedure not supported on JS target")
} }
@@ -111,12 +119,12 @@ remove_directory :: proc(path: string) -> (err: Error) {
@(private) @(private, require_results)
is_abs :: proc(path: string) -> bool { is_abs :: proc(path: string) -> bool {
unimplemented("core:os procedure not supported on JS target") unimplemented("core:os procedure not supported on JS target")
} }
@(private) @(private, require_results)
fix_long_path :: proc(path: string) -> string { fix_long_path :: proc(path: string) -> string {
unimplemented("core:os procedure not supported on JS target") unimplemented("core:os procedure not supported on JS target")
} }
@@ -151,10 +159,12 @@ remove :: proc(name: string) -> Error {
} }
@(require_results)
pipe :: proc() -> (r, w: Handle, err: Error) { pipe :: proc() -> (r, w: Handle, err: Error) {
unimplemented("core:os procedure not supported on JS target") unimplemented("core:os procedure not supported on JS target")
} }
@(require_results)
read_dir :: proc(fd: Handle, n: int, allocator := context.allocator) -> (fi: []File_Info, err: Error) { read_dir :: proc(fd: Handle, n: int, allocator := context.allocator) -> (fi: []File_Info, err: Error) {
unimplemented("core:os procedure not supported on JS target") unimplemented("core:os procedure not supported on JS target")
} }
@@ -251,20 +261,23 @@ args := _alloc_command_line_arguments()
@(require_results)
last_write_time :: proc(fd: Handle) -> (File_Time, Error) { last_write_time :: proc(fd: Handle) -> (File_Time, Error) {
unimplemented("core:os procedure not supported on JS target") unimplemented("core:os procedure not supported on JS target")
} }
@(require_results)
last_write_time_by_name :: proc(name: string) -> (File_Time, Error) { last_write_time_by_name :: proc(name: string) -> (File_Time, Error) {
unimplemented("core:os procedure not supported on JS target") unimplemented("core:os procedure not supported on JS target")
} }
@(require_results)
get_page_size :: proc() -> int { get_page_size :: proc() -> int {
unimplemented("core:os procedure not supported on JS target") unimplemented("core:os procedure not supported on JS target")
} }
@(private) @(private, require_results)
_processor_core_count :: proc() -> int { _processor_core_count :: proc() -> int {
unimplemented("core:os procedure not supported on JS target") unimplemented("core:os procedure not supported on JS target")
} }
@@ -276,6 +289,7 @@ exit :: proc "contextless" (code: int) -> ! {
@(require_results)
current_thread_id :: proc "contextless" () -> int { current_thread_id :: proc "contextless" () -> int {
context = runtime.default_context() context = runtime.default_context()
unimplemented("core:os procedure not supported on JS target") unimplemented("core:os procedure not supported on JS target")
@@ -283,6 +297,7 @@ current_thread_id :: proc "contextless" () -> int {
@(require_results)
_alloc_command_line_arguments :: proc() -> []string { _alloc_command_line_arguments :: proc() -> []string {
return nil return nil
} }
+47 -23
View File
@@ -448,13 +448,13 @@ S_ISGID :: 0o2000 // Set group id on execution
S_ISVTX :: 0o1000 // Directory restrcted delete S_ISVTX :: 0o1000 // Directory restrcted delete
S_ISLNK :: #force_inline proc(m: u32) -> bool { return (m & S_IFMT) == S_IFLNK } @(require_results) S_ISLNK :: #force_inline proc(m: u32) -> bool { return (m & S_IFMT) == S_IFLNK }
S_ISREG :: #force_inline proc(m: u32) -> bool { return (m & S_IFMT) == S_IFREG } @(require_results) S_ISREG :: #force_inline proc(m: u32) -> bool { return (m & S_IFMT) == S_IFREG }
S_ISDIR :: #force_inline proc(m: u32) -> bool { return (m & S_IFMT) == S_IFDIR } @(require_results) S_ISDIR :: #force_inline proc(m: u32) -> bool { return (m & S_IFMT) == S_IFDIR }
S_ISCHR :: #force_inline proc(m: u32) -> bool { return (m & S_IFMT) == S_IFCHR } @(require_results) S_ISCHR :: #force_inline proc(m: u32) -> bool { return (m & S_IFMT) == S_IFCHR }
S_ISBLK :: #force_inline proc(m: u32) -> bool { return (m & S_IFMT) == S_IFBLK } @(require_results) S_ISBLK :: #force_inline proc(m: u32) -> bool { return (m & S_IFMT) == S_IFBLK }
S_ISFIFO :: #force_inline proc(m: u32) -> bool { return (m & S_IFMT) == S_IFIFO } @(require_results) S_ISFIFO :: #force_inline proc(m: u32) -> bool { return (m & S_IFMT) == S_IFIFO }
S_ISSOCK :: #force_inline proc(m: u32) -> bool { return (m & S_IFMT) == S_IFSOCK } @(require_results) S_ISSOCK :: #force_inline proc(m: u32) -> bool { return (m & S_IFMT) == S_IFSOCK }
F_OK :: 0 // Test for file existance F_OK :: 0 // Test for file existance
X_OK :: 1 // Test for execute permission X_OK :: 1 // Test for execute permission
@@ -506,12 +506,13 @@ foreign dl {
@(link_name="freeifaddrs") _freeifaddrs :: proc(ifa: ^ifaddrs) --- @(link_name="freeifaddrs") _freeifaddrs :: proc(ifa: ^ifaddrs) ---
} }
@(require_results)
is_path_separator :: proc(r: rune) -> bool { is_path_separator :: proc(r: rune) -> bool {
return r == '/' return r == '/'
} }
// determine errno from syscall return value // determine errno from syscall return value
@private @(private, require_results)
_get_errno :: proc(res: int) -> Error { _get_errno :: proc(res: int) -> Error {
if res < 0 && res > -4096 { if res < 0 && res > -4096 {
return Platform_Error(-res) return Platform_Error(-res)
@@ -536,7 +537,7 @@ get_last_error :: proc "contextless" () -> Error {
return err return err
} }
personality :: proc(persona: u64) -> (Error) { personality :: proc(persona: u64) -> Error {
res := unix.sys_personality(persona) res := unix.sys_personality(persona)
if res == -1 { if res == -1 {
return _get_errno(res) return _get_errno(res)
@@ -544,6 +545,7 @@ personality :: proc(persona: u64) -> (Error) {
return nil return nil
} }
@(require_results)
fork :: proc() -> (Pid, Error) { fork :: proc() -> (Pid, Error) {
pid := unix.sys_fork() pid := unix.sys_fork()
if pid == -1 { if pid == -1 {
@@ -567,6 +569,7 @@ execvp :: proc(path: string, args: []string) -> Error {
} }
@(require_results)
open :: proc(path: string, flags: int = O_RDONLY, mode: int = 0o000) -> (Handle, Error) { open :: proc(path: string, flags: int = O_RDONLY, mode: int = 0o000) -> (Handle, Error) {
runtime.DEFAULT_TEMP_ALLOCATOR_TEMP_GUARD() runtime.DEFAULT_TEMP_ALLOCATOR_TEMP_GUARD()
cstr := strings.clone_to_cstring(path, context.temp_allocator) cstr := strings.clone_to_cstring(path, context.temp_allocator)
@@ -659,6 +662,7 @@ seek :: proc(fd: Handle, offset: i64, whence: int) -> (i64, Error) {
return i64(res), nil return i64(res), nil
} }
@(require_results)
file_size :: proc(fd: Handle) -> (i64, Error) { file_size :: proc(fd: Handle) -> (i64, Error) {
// deliberately uninitialized; the syscall fills this buffer for us // deliberately uninitialized; the syscall fills this buffer for us
s: OS_Stat = --- s: OS_Stat = ---
@@ -694,6 +698,7 @@ remove_directory :: proc(path: string) -> Error {
return _get_errno(unix.sys_rmdir(path_cstr)) return _get_errno(unix.sys_rmdir(path_cstr))
} }
@(require_results)
is_file_handle :: proc(fd: Handle) -> bool { is_file_handle :: proc(fd: Handle) -> bool {
s, err := _fstat(fd) s, err := _fstat(fd)
if err != nil { if err != nil {
@@ -702,6 +707,7 @@ is_file_handle :: proc(fd: Handle) -> bool {
return S_ISREG(s.mode) return S_ISREG(s.mode)
} }
@(require_results)
is_file_path :: proc(path: string, follow_links: bool = true) -> bool { is_file_path :: proc(path: string, follow_links: bool = true) -> bool {
s: OS_Stat s: OS_Stat
err: Error err: Error
@@ -717,6 +723,7 @@ is_file_path :: proc(path: string, follow_links: bool = true) -> bool {
} }
@(require_results)
is_dir_handle :: proc(fd: Handle) -> bool { is_dir_handle :: proc(fd: Handle) -> bool {
s, err := _fstat(fd) s, err := _fstat(fd)
if err != nil { if err != nil {
@@ -725,6 +732,7 @@ is_dir_handle :: proc(fd: Handle) -> bool {
return S_ISDIR(s.mode) return S_ISDIR(s.mode)
} }
@(require_results)
is_dir_path :: proc(path: string, follow_links: bool = true) -> bool { is_dir_path :: proc(path: string, follow_links: bool = true) -> bool {
s: OS_Stat s: OS_Stat
err: Error err: Error
@@ -742,6 +750,7 @@ is_dir_path :: proc(path: string, follow_links: bool = true) -> bool {
is_file :: proc {is_file_path, is_file_handle} 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}
@(require_results)
exists :: proc(path: string) -> bool { exists :: proc(path: string) -> bool {
runtime.DEFAULT_TEMP_ALLOCATOR_TEMP_GUARD() runtime.DEFAULT_TEMP_ALLOCATOR_TEMP_GUARD()
cpath := strings.clone_to_cstring(path, context.temp_allocator) cpath := strings.clone_to_cstring(path, context.temp_allocator)
@@ -759,19 +768,21 @@ stderr: Handle = 2
last_write_time :: proc(fd: Handle) -> File_Time {} last_write_time :: proc(fd: Handle) -> File_Time {}
last_write_time_by_name :: proc(name: string) -> File_Time {} last_write_time_by_name :: proc(name: string) -> File_Time {}
*/ */
@(require_results)
last_write_time :: proc(fd: Handle) -> (time: File_Time, err: Error) { last_write_time :: proc(fd: Handle) -> (time: File_Time, err: Error) {
s := _fstat(fd) or_return s := _fstat(fd) or_return
modified := s.modified.seconds * 1_000_000_000 + s.modified.nanoseconds modified := s.modified.seconds * 1_000_000_000 + s.modified.nanoseconds
return File_Time(modified), nil return File_Time(modified), nil
} }
@(require_results)
last_write_time_by_name :: proc(name: string) -> (time: File_Time, err: Error) { last_write_time_by_name :: proc(name: string) -> (time: File_Time, err: Error) {
s := _stat(name) or_return s := _stat(name) or_return
modified := s.modified.seconds * 1_000_000_000 + s.modified.nanoseconds modified := s.modified.seconds * 1_000_000_000 + s.modified.nanoseconds
return File_Time(modified), nil return File_Time(modified), nil
} }
@private @(private, require_results)
_stat :: proc(path: string) -> (OS_Stat, Error) { _stat :: proc(path: string) -> (OS_Stat, Error) {
runtime.DEFAULT_TEMP_ALLOCATOR_TEMP_GUARD() runtime.DEFAULT_TEMP_ALLOCATOR_TEMP_GUARD()
cstr := strings.clone_to_cstring(path, context.temp_allocator) cstr := strings.clone_to_cstring(path, context.temp_allocator)
@@ -785,7 +796,7 @@ _stat :: proc(path: string) -> (OS_Stat, Error) {
return s, nil return s, nil
} }
@private @(private, require_results)
_lstat :: proc(path: string) -> (OS_Stat, Error) { _lstat :: proc(path: string) -> (OS_Stat, Error) {
runtime.DEFAULT_TEMP_ALLOCATOR_TEMP_GUARD() runtime.DEFAULT_TEMP_ALLOCATOR_TEMP_GUARD()
cstr := strings.clone_to_cstring(path, context.temp_allocator) cstr := strings.clone_to_cstring(path, context.temp_allocator)
@@ -799,7 +810,7 @@ _lstat :: proc(path: string) -> (OS_Stat, Error) {
return s, nil return s, nil
} }
@private @(private, require_results)
_fstat :: proc(fd: Handle) -> (OS_Stat, Error) { _fstat :: proc(fd: Handle) -> (OS_Stat, Error) {
// deliberately uninitialized; the syscall fills this buffer for us // deliberately uninitialized; the syscall fills this buffer for us
s: OS_Stat = --- s: OS_Stat = ---
@@ -810,7 +821,7 @@ _fstat :: proc(fd: Handle) -> (OS_Stat, Error) {
return s, nil return s, nil
} }
@private @(private, require_results)
_fdopendir :: proc(fd: Handle) -> (Dir, Error) { _fdopendir :: proc(fd: Handle) -> (Dir, Error) {
dirp := _unix_fdopendir(fd) dirp := _unix_fdopendir(fd)
if dirp == cast(Dir)nil { if dirp == cast(Dir)nil {
@@ -819,7 +830,7 @@ _fdopendir :: proc(fd: Handle) -> (Dir, Error) {
return dirp, nil return dirp, nil
} }
@private @(private)
_closedir :: proc(dirp: Dir) -> Error { _closedir :: proc(dirp: Dir) -> Error {
rc := _unix_closedir(dirp) rc := _unix_closedir(dirp)
if rc != 0 { if rc != 0 {
@@ -828,12 +839,12 @@ _closedir :: proc(dirp: Dir) -> Error {
return nil return nil
} }
@private @(private)
_rewinddir :: proc(dirp: Dir) { _rewinddir :: proc(dirp: Dir) {
_unix_rewinddir(dirp) _unix_rewinddir(dirp)
} }
@private @(private, require_results)
_readdir :: proc(dirp: Dir) -> (entry: Dirent, err: Error, end_of_stream: bool) { _readdir :: proc(dirp: Dir) -> (entry: Dirent, err: Error, end_of_stream: bool) {
result: ^Dirent result: ^Dirent
rc := _unix_readdir_r(dirp, &entry, &result) rc := _unix_readdir_r(dirp, &entry, &result)
@@ -853,7 +864,7 @@ _readdir :: proc(dirp: Dir) -> (entry: Dirent, err: Error, end_of_stream: bool)
return return
} }
@private @(private, require_results)
_readlink :: proc(path: string) -> (string, Error) { _readlink :: proc(path: string) -> (string, Error) {
runtime.DEFAULT_TEMP_ALLOCATOR_TEMP_GUARD(ignore = context.temp_allocator == context.allocator) 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)
@@ -876,6 +887,7 @@ _readlink :: proc(path: string) -> (string, Error) {
} }
} }
@(require_results)
absolute_path_from_handle :: proc(fd: Handle) -> (string, Error) { absolute_path_from_handle :: proc(fd: Handle) -> (string, Error) {
buf : [256]byte buf : [256]byte
fd_str := strconv.itoa( buf[:], cast(int)fd ) fd_str := strconv.itoa( buf[:], cast(int)fd )
@@ -886,6 +898,7 @@ absolute_path_from_handle :: proc(fd: Handle) -> (string, Error) {
return _readlink(procfs_path) return _readlink(procfs_path)
} }
@(require_results)
absolute_path_from_relative :: proc(rel: string) -> (path: string, err: Error) { absolute_path_from_relative :: proc(rel: string) -> (path: string, err: Error) {
rel := rel rel := rel
if rel == "" { if rel == "" {
@@ -916,6 +929,7 @@ access :: proc(path: string, mask: int) -> (bool, Error) {
return true, nil return true, nil
} }
@(require_results)
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) 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)
@@ -927,6 +941,7 @@ lookup_env :: proc(key: string, allocator := context.allocator) -> (value: strin
return strings.clone(string(cstr), allocator), true return strings.clone(string(cstr), allocator), true
} }
@(require_results)
get_env :: proc(key: string, allocator := context.allocator) -> (value: string) { get_env :: proc(key: string, allocator := context.allocator) -> (value: string) {
value, _ = lookup_env(key, allocator) value, _ = lookup_env(key, allocator)
return return
@@ -954,6 +969,7 @@ unset_env :: proc(key: string) -> Error {
return nil return nil
} }
@(require_results)
get_current_directory :: proc() -> string { get_current_directory :: proc() -> string {
// NOTE(tetra): I would use PATH_MAX here, but I was not able to find // NOTE(tetra): I would use PATH_MAX here, but I was not able to find
// an authoritative value for it across all systems. // an authoritative value for it across all systems.
@@ -990,16 +1006,19 @@ exit :: proc "contextless" (code: int) -> ! {
_unix_exit(c.int(code)) _unix_exit(c.int(code))
} }
@(require_results)
current_thread_id :: proc "contextless" () -> int { current_thread_id :: proc "contextless" () -> int {
return unix.sys_gettid() return unix.sys_gettid()
} }
@(require_results)
dlopen :: proc(filename: string, flags: int) -> rawptr { dlopen :: proc(filename: string, flags: int) -> rawptr {
runtime.DEFAULT_TEMP_ALLOCATOR_TEMP_GUARD() 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
} }
@(require_results)
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() runtime.DEFAULT_TEMP_ALLOCATOR_TEMP_GUARD()
@@ -1015,6 +1034,7 @@ dlerror :: proc() -> string {
return string(_unix_dlerror()) return string(_unix_dlerror())
} }
@(require_results)
get_page_size :: proc() -> int { get_page_size :: proc() -> int {
// NOTE(tetra): The page size never changes, so why do anything complicated // NOTE(tetra): The page size never changes, so why do anything complicated
// if we don't have to. // if we don't have to.
@@ -1027,11 +1047,12 @@ get_page_size :: proc() -> int {
return page_size return page_size
} }
@(private) @(private, require_results)
_processor_core_count :: proc() -> int { _processor_core_count :: proc() -> int {
return int(_unix_get_nprocs()) return int(_unix_get_nprocs())
} }
@(require_results)
_alloc_command_line_arguments :: proc() -> []string { _alloc_command_line_arguments :: proc() -> []string {
res := make([]string, len(runtime.args__)) res := make([]string, len(runtime.args__))
for arg, i in runtime.args__ { for arg, i in runtime.args__ {
@@ -1040,6 +1061,7 @@ _alloc_command_line_arguments :: proc() -> []string {
return res return res
} }
@(require_results)
socket :: proc(domain: int, type: int, protocol: int) -> (Socket, Error) { socket :: proc(domain: int, type: int, protocol: int) -> (Socket, Error) {
result := unix.sys_socket(domain, type, protocol) result := unix.sys_socket(domain, type, protocol)
if result < 0 { if result < 0 {
@@ -1048,7 +1070,7 @@ socket :: proc(domain: int, type: int, protocol: int) -> (Socket, Error) {
return Socket(result), nil return Socket(result), nil
} }
bind :: proc(sd: Socket, addr: ^SOCKADDR, len: socklen_t) -> (Error) { bind :: proc(sd: Socket, addr: ^SOCKADDR, len: socklen_t) -> Error {
result := unix.sys_bind(int(sd), addr, len) result := unix.sys_bind(int(sd), addr, len)
if result < 0 { if result < 0 {
return _get_errno(result) return _get_errno(result)
@@ -1057,7 +1079,7 @@ bind :: proc(sd: Socket, addr: ^SOCKADDR, len: socklen_t) -> (Error) {
} }
connect :: proc(sd: Socket, addr: ^SOCKADDR, len: socklen_t) -> (Error) { connect :: proc(sd: Socket, addr: ^SOCKADDR, len: socklen_t) -> Error {
result := unix.sys_connect(int(sd), addr, len) result := unix.sys_connect(int(sd), addr, len)
if result < 0 { if result < 0 {
return _get_errno(result) return _get_errno(result)
@@ -1073,7 +1095,7 @@ accept :: proc(sd: Socket, addr: ^SOCKADDR, len: rawptr) -> (Socket, Error) {
return Socket(result), nil return Socket(result), nil
} }
listen :: proc(sd: Socket, backlog: int) -> (Error) { listen :: proc(sd: Socket, backlog: int) -> Error {
result := unix.sys_listen(int(sd), backlog) result := unix.sys_listen(int(sd), backlog)
if result < 0 { if result < 0 {
return _get_errno(result) return _get_errno(result)
@@ -1081,7 +1103,7 @@ listen :: proc(sd: Socket, backlog: int) -> (Error) {
return nil return nil
} }
setsockopt :: proc(sd: Socket, level: int, optname: int, optval: rawptr, optlen: socklen_t) -> (Error) { setsockopt :: proc(sd: Socket, level: int, optname: int, optval: rawptr, optlen: socklen_t) -> Error {
result := unix.sys_setsockopt(int(sd), level, optname, optval, optlen) result := unix.sys_setsockopt(int(sd), level, optname, optval, optlen)
if result < 0 { if result < 0 {
return _get_errno(result) return _get_errno(result)
@@ -1123,7 +1145,7 @@ send :: proc(sd: Socket, data: []byte, flags: int) -> (u32, Error) {
return u32(result), nil return u32(result), nil
} }
shutdown :: proc(sd: Socket, how: int) -> (Error) { shutdown :: proc(sd: Socket, how: int) -> Error {
result := unix.sys_shutdown(int(sd), how) result := unix.sys_shutdown(int(sd), how)
if result < 0 { if result < 0 {
return _get_errno(result) return _get_errno(result)
@@ -1139,6 +1161,7 @@ fcntl :: proc(fd: int, cmd: int, arg: int) -> (int, Error) {
return result, nil return result, nil
} }
@(require_results)
poll :: proc(fds: []pollfd, timeout: int) -> (int, Error) { poll :: proc(fds: []pollfd, timeout: int) -> (int, Error) {
result := unix.sys_poll(raw_data(fds), uint(len(fds)), timeout) result := unix.sys_poll(raw_data(fds), uint(len(fds)), timeout)
if result < 0 { if result < 0 {
@@ -1147,6 +1170,7 @@ poll :: proc(fds: []pollfd, timeout: int) -> (int, Error) {
return result, nil return result, nil
} }
@(require_results)
ppoll :: proc(fds: []pollfd, timeout: ^unix.timespec, sigmask: ^sigset_t) -> (int, Error) { ppoll :: proc(fds: []pollfd, timeout: ^unix.timespec, sigmask: ^sigset_t) -> (int, Error) {
result := unix.sys_ppoll(raw_data(fds), uint(len(fds)), timeout, sigmask, size_of(sigset_t)) result := unix.sys_ppoll(raw_data(fds), uint(len(fds)), timeout, sigmask, size_of(sigset_t))
if result < 0 { if result < 0 {
+36 -16
View File
@@ -407,13 +407,13 @@ S_ISUID :: 0o4000 // Set user id on execution
S_ISGID :: 0o2000 // Set group id on execution S_ISGID :: 0o2000 // Set group id on execution
S_ISVTX :: 0o1000 // Directory restrcted delete S_ISVTX :: 0o1000 // Directory restrcted delete
S_ISLNK :: #force_inline proc "contextless" (m: mode_t) -> bool { return (m & S_IFMT) == S_IFLNK } @(require_results) S_ISLNK :: #force_inline proc "contextless" (m: mode_t) -> bool { return (m & S_IFMT) == S_IFLNK }
S_ISREG :: #force_inline proc "contextless" (m: mode_t) -> bool { return (m & S_IFMT) == S_IFREG } @(require_results) S_ISREG :: #force_inline proc "contextless" (m: mode_t) -> bool { return (m & S_IFMT) == S_IFREG }
S_ISDIR :: #force_inline proc "contextless" (m: mode_t) -> bool { return (m & S_IFMT) == S_IFDIR } @(require_results) S_ISDIR :: #force_inline proc "contextless" (m: mode_t) -> bool { return (m & S_IFMT) == S_IFDIR }
S_ISCHR :: #force_inline proc "contextless" (m: mode_t) -> bool { return (m & S_IFMT) == S_IFCHR } @(require_results) S_ISCHR :: #force_inline proc "contextless" (m: mode_t) -> bool { return (m & S_IFMT) == S_IFCHR }
S_ISBLK :: #force_inline proc "contextless" (m: mode_t) -> bool { return (m & S_IFMT) == S_IFBLK } @(require_results) S_ISBLK :: #force_inline proc "contextless" (m: mode_t) -> bool { return (m & S_IFMT) == S_IFBLK }
S_ISFIFO :: #force_inline proc "contextless" (m: mode_t) -> bool { return (m & S_IFMT) == S_IFIFO } @(require_results) S_ISFIFO :: #force_inline proc "contextless" (m: mode_t) -> bool { return (m & S_IFMT) == S_IFIFO }
S_ISSOCK :: #force_inline proc "contextless" (m: mode_t) -> bool { return (m & S_IFMT) == S_IFSOCK } @(require_results) S_ISSOCK :: #force_inline proc "contextless" (m: mode_t) -> bool { return (m & S_IFMT) == S_IFSOCK }
F_OK :: 0 // Test for file existance F_OK :: 0 // Test for file existance
X_OK :: 1 // Test for execute permission X_OK :: 1 // Test for execute permission
@@ -561,6 +561,7 @@ seek :: proc(fd: Handle, offset: i64, whence: int) -> (i64, Error) {
return res, nil return res, nil
} }
@(require_results)
file_size :: proc(fd: Handle) -> (size: i64, err: Error) { file_size :: proc(fd: Handle) -> (size: i64, err: Error) {
size = -1 size = -1
s := _fstat(fd) or_return s := _fstat(fd) or_return
@@ -609,6 +610,7 @@ remove_directory :: proc(path: string) -> Error {
return nil return nil
} }
@(require_results)
is_file_handle :: proc(fd: Handle) -> bool { is_file_handle :: proc(fd: Handle) -> bool {
s, err := _fstat(fd) s, err := _fstat(fd)
if err != nil { if err != nil {
@@ -617,6 +619,7 @@ is_file_handle :: proc(fd: Handle) -> bool {
return S_ISREG(s.mode) return S_ISREG(s.mode)
} }
@(require_results)
is_file_path :: proc(path: string, follow_links: bool = true) -> bool { is_file_path :: proc(path: string, follow_links: bool = true) -> bool {
s: OS_Stat s: OS_Stat
err: Error err: Error
@@ -631,6 +634,7 @@ is_file_path :: proc(path: string, follow_links: bool = true) -> bool {
return S_ISREG(s.mode) return S_ISREG(s.mode)
} }
@(require_results)
is_dir_handle :: proc(fd: Handle) -> bool { is_dir_handle :: proc(fd: Handle) -> bool {
s, err := _fstat(fd) s, err := _fstat(fd)
if err != nil { if err != nil {
@@ -639,6 +643,7 @@ is_dir_handle :: proc(fd: Handle) -> bool {
return S_ISDIR(s.mode) return S_ISDIR(s.mode)
} }
@(require_results)
is_dir_path :: proc(path: string, follow_links: bool = true) -> bool { is_dir_path :: proc(path: string, follow_links: bool = true) -> bool {
s: OS_Stat s: OS_Stat
err: Error err: Error
@@ -656,6 +661,7 @@ is_dir_path :: proc(path: string, follow_links: bool = true) -> bool {
is_file :: proc {is_file_path, is_file_handle} 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}
@(require_results)
exists :: proc(path: string) -> bool { exists :: proc(path: string) -> bool {
runtime.DEFAULT_TEMP_ALLOCATOR_TEMP_GUARD() runtime.DEFAULT_TEMP_ALLOCATOR_TEMP_GUARD()
cpath := strings.clone_to_cstring(path, context.temp_allocator) cpath := strings.clone_to_cstring(path, context.temp_allocator)
@@ -663,6 +669,7 @@ exists :: proc(path: string) -> bool {
return res == 0 return res == 0
} }
@(require_results)
fcntl :: proc(fd: int, cmd: int, arg: int) -> (int, Error) { fcntl :: proc(fd: int, cmd: int, arg: int) -> (int, Error) {
result := _unix_fcntl(Handle(fd), c.int(cmd), uintptr(arg)) result := _unix_fcntl(Handle(fd), c.int(cmd), uintptr(arg))
if result < 0 { if result < 0 {
@@ -677,19 +684,21 @@ stdin: Handle = 0
stdout: Handle = 1 stdout: Handle = 1
stderr: Handle = 2 stderr: Handle = 2
@(require_results)
last_write_time :: proc(fd: Handle) -> (time: File_Time, err: Error) { last_write_time :: proc(fd: Handle) -> (time: File_Time, err: Error) {
s := _fstat(fd) or_return s := _fstat(fd) or_return
modified := s.modified.seconds * 1_000_000_000 + s.modified.nanoseconds modified := s.modified.seconds * 1_000_000_000 + s.modified.nanoseconds
return File_Time(modified), nil return File_Time(modified), nil
} }
@(require_results)
last_write_time_by_name :: proc(name: string) -> (time: File_Time, err: Error) { last_write_time_by_name :: proc(name: string) -> (time: File_Time, err: Error) {
s := _stat(name) or_return s := _stat(name) or_return
modified := s.modified.seconds * 1_000_000_000 + s.modified.nanoseconds modified := s.modified.seconds * 1_000_000_000 + s.modified.nanoseconds
return File_Time(modified), nil return File_Time(modified), nil
} }
@private @(private, require_results)
_stat :: proc(path: string) -> (OS_Stat, Error) { _stat :: proc(path: string) -> (OS_Stat, Error) {
runtime.DEFAULT_TEMP_ALLOCATOR_TEMP_GUARD() runtime.DEFAULT_TEMP_ALLOCATOR_TEMP_GUARD()
cstr := strings.clone_to_cstring(path, context.temp_allocator) cstr := strings.clone_to_cstring(path, context.temp_allocator)
@@ -701,7 +710,7 @@ _stat :: proc(path: string) -> (OS_Stat, Error) {
return s, nil return s, nil
} }
@private @(private, require_results)
_lstat :: proc(path: string) -> (OS_Stat, Error) { _lstat :: proc(path: string) -> (OS_Stat, Error) {
runtime.DEFAULT_TEMP_ALLOCATOR_TEMP_GUARD() runtime.DEFAULT_TEMP_ALLOCATOR_TEMP_GUARD()
cstr := strings.clone_to_cstring(path, context.temp_allocator) cstr := strings.clone_to_cstring(path, context.temp_allocator)
@@ -715,7 +724,7 @@ _lstat :: proc(path: string) -> (OS_Stat, Error) {
return s, nil return s, nil
} }
@private @(private, require_results)
_fstat :: proc(fd: Handle) -> (OS_Stat, Error) { _fstat :: proc(fd: Handle) -> (OS_Stat, Error) {
s: OS_Stat = --- s: OS_Stat = ---
result := _unix_fstat(fd, &s) result := _unix_fstat(fd, &s)
@@ -725,7 +734,7 @@ _fstat :: proc(fd: Handle) -> (OS_Stat, Error) {
return s, nil return s, nil
} }
@private @(private, require_results)
_fdopendir :: proc(fd: Handle) -> (Dir, Error) { _fdopendir :: proc(fd: Handle) -> (Dir, Error) {
dirp := _unix_fdopendir(fd) dirp := _unix_fdopendir(fd)
if dirp == cast(Dir)nil { if dirp == cast(Dir)nil {
@@ -734,7 +743,7 @@ _fdopendir :: proc(fd: Handle) -> (Dir, Error) {
return dirp, nil return dirp, nil
} }
@private @(private)
_closedir :: proc(dirp: Dir) -> Error { _closedir :: proc(dirp: Dir) -> Error {
rc := _unix_closedir(dirp) rc := _unix_closedir(dirp)
if rc != 0 { if rc != 0 {
@@ -743,12 +752,12 @@ _closedir :: proc(dirp: Dir) -> Error {
return nil return nil
} }
@private @(private)
_rewinddir :: proc(dirp: Dir) { _rewinddir :: proc(dirp: Dir) {
_unix_rewinddir(dirp) _unix_rewinddir(dirp)
} }
@private @(private, require_results)
_readdir :: proc(dirp: Dir) -> (entry: Dirent, err: Error, end_of_stream: bool) { _readdir :: proc(dirp: Dir) -> (entry: Dirent, err: Error, end_of_stream: bool) {
result: ^Dirent result: ^Dirent
rc := _unix_readdir_r(dirp, &entry, &result) rc := _unix_readdir_r(dirp, &entry, &result)
@@ -767,7 +776,7 @@ _readdir :: proc(dirp: Dir) -> (entry: Dirent, err: Error, end_of_stream: bool)
return return
} }
@private @(private, require_results)
_readlink :: proc(path: string) -> (string, Error) { _readlink :: proc(path: string) -> (string, Error) {
runtime.DEFAULT_TEMP_ALLOCATOR_TEMP_GUARD(ignore = context.temp_allocator == context.allocator) runtime.DEFAULT_TEMP_ALLOCATOR_TEMP_GUARD(ignore = context.temp_allocator == context.allocator)
@@ -792,12 +801,14 @@ _readlink :: proc(path: string) -> (string, Error) {
return "", Error{} return "", Error{}
} }
@(require_results)
absolute_path_from_handle :: proc(fd: Handle) -> (path: string, err: Error) { absolute_path_from_handle :: proc(fd: Handle) -> (path: string, err: Error) {
buf: [MAX_PATH]byte buf: [MAX_PATH]byte
_ = fcntl(int(fd), F_GETPATH, int(uintptr(&buf[0]))) or_return _ = fcntl(int(fd), F_GETPATH, int(uintptr(&buf[0]))) or_return
return strings.clone_from_cstring(cstring(&buf[0])) return strings.clone_from_cstring(cstring(&buf[0]))
} }
@(require_results)
absolute_path_from_relative :: proc(rel: string) -> (path: string, err: Error) { absolute_path_from_relative :: proc(rel: string) -> (path: string, err: Error) {
rel := rel rel := rel
if rel == "" { if rel == "" {
@@ -829,6 +840,7 @@ access :: proc(path: string, mask: int) -> (bool, Error) {
return true, nil return true, nil
} }
@(require_results)
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) runtime.DEFAULT_TEMP_ALLOCATOR_TEMP_GUARD(ignore = context.temp_allocator == allocator)
@@ -840,11 +852,13 @@ lookup_env :: proc(key: string, allocator := context.allocator) -> (value: strin
return strings.clone(string(cstr), allocator), true return strings.clone(string(cstr), allocator), true
} }
@(require_results)
get_env :: proc(key: string, allocator := context.allocator) -> (value: string) { get_env :: proc(key: string, allocator := context.allocator) -> (value: string) {
value, _ = lookup_env(key, allocator) value, _ = lookup_env(key, allocator)
return return
} }
@(require_results)
get_current_directory :: proc() -> string { get_current_directory :: proc() -> string {
// NOTE(tetra): I would use PATH_MAX here, but I was not able to find // NOTE(tetra): I would use PATH_MAX here, but I was not able to find
// an authoritative value for it across all systems. // an authoritative value for it across all systems.
@@ -880,10 +894,12 @@ exit :: proc "contextless" (code: int) -> ! {
_unix_exit(c.int(code)) _unix_exit(c.int(code))
} }
@(require_results)
current_thread_id :: proc "contextless" () -> int { current_thread_id :: proc "contextless" () -> int {
return int(_lwp_self()) return int(_lwp_self())
} }
@(require_results)
dlopen :: proc(filename: string, flags: int) -> rawptr { dlopen :: proc(filename: string, flags: int) -> rawptr {
runtime.DEFAULT_TEMP_ALLOCATOR_TEMP_GUARD() runtime.DEFAULT_TEMP_ALLOCATOR_TEMP_GUARD()
cstr := strings.clone_to_cstring(filename, context.temp_allocator) cstr := strings.clone_to_cstring(filename, context.temp_allocator)
@@ -891,6 +907,7 @@ dlopen :: proc(filename: string, flags: int) -> rawptr {
return handle return handle
} }
@(require_results)
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() runtime.DEFAULT_TEMP_ALLOCATOR_TEMP_GUARD()
@@ -904,10 +921,12 @@ dlclose :: proc(handle: rawptr) -> bool {
return _unix_dlclose(handle) == 0 return _unix_dlclose(handle) == 0
} }
@(require_results)
dlerror :: proc() -> string { dlerror :: proc() -> string {
return string(_unix_dlerror()) return string(_unix_dlerror())
} }
@(require_results)
get_page_size :: proc() -> int { get_page_size :: proc() -> int {
// NOTE(tetra): The page size never changes, so why do anything complicated // NOTE(tetra): The page size never changes, so why do anything complicated
// if we don't have to. // if we don't have to.
@@ -920,7 +939,7 @@ get_page_size :: proc() -> int {
return page_size return page_size
} }
@(private) @(private, require_results)
_processor_core_count :: proc() -> int { _processor_core_count :: proc() -> int {
count : int = 0 count : int = 0
count_size := size_of(count) count_size := size_of(count)
@@ -933,6 +952,7 @@ _processor_core_count :: proc() -> int {
return 1 return 1
} }
@(require_results)
_alloc_command_line_arguments :: proc() -> []string { _alloc_command_line_arguments :: proc() -> []string {
res := make([]string, len(runtime.args__)) res := make([]string, len(runtime.args__))
for arg, i in runtime.args__ { for arg, i in runtime.args__ {
+34 -16
View File
@@ -322,13 +322,13 @@ S_ISUID :: 0o4000 // Set user id on execution
S_ISGID :: 0o2000 // Set group id on execution S_ISGID :: 0o2000 // Set group id on execution
S_ISTXT :: 0o1000 // Sticky bit S_ISTXT :: 0o1000 // Sticky bit
S_ISLNK :: #force_inline proc(m: u32) -> bool { return (m & S_IFMT) == S_IFLNK } @(require_results) S_ISLNK :: #force_inline proc(m: u32) -> bool { return (m & S_IFMT) == S_IFLNK }
S_ISREG :: #force_inline proc(m: u32) -> bool { return (m & S_IFMT) == S_IFREG } @(require_results) S_ISREG :: #force_inline proc(m: u32) -> bool { return (m & S_IFMT) == S_IFREG }
S_ISDIR :: #force_inline proc(m: u32) -> bool { return (m & S_IFMT) == S_IFDIR } @(require_results) S_ISDIR :: #force_inline proc(m: u32) -> bool { return (m & S_IFMT) == S_IFDIR }
S_ISCHR :: #force_inline proc(m: u32) -> bool { return (m & S_IFMT) == S_IFCHR } @(require_results) S_ISCHR :: #force_inline proc(m: u32) -> bool { return (m & S_IFMT) == S_IFCHR }
S_ISBLK :: #force_inline proc(m: u32) -> bool { return (m & S_IFMT) == S_IFBLK } @(require_results) S_ISBLK :: #force_inline proc(m: u32) -> bool { return (m & S_IFMT) == S_IFBLK }
S_ISFIFO :: #force_inline proc(m: u32) -> bool { return (m & S_IFMT) == S_IFIFO } @(require_results) S_ISFIFO :: #force_inline proc(m: u32) -> bool { return (m & S_IFMT) == S_IFIFO }
S_ISSOCK :: #force_inline proc(m: u32) -> bool { return (m & S_IFMT) == S_IFSOCK } @(require_results) S_ISSOCK :: #force_inline proc(m: u32) -> bool { return (m & S_IFMT) == S_IFSOCK }
F_OK :: 0x00 // Test for file existance F_OK :: 0x00 // Test for file existance
X_OK :: 0x01 // Test for execute permission X_OK :: 0x01 // Test for execute permission
@@ -489,6 +489,7 @@ seek :: proc(fd: Handle, offset: i64, whence: int) -> (i64, Error) {
return res, nil return res, nil
} }
@(require_results)
file_size :: proc(fd: Handle) -> (size: i64, err: Error) { file_size :: proc(fd: Handle) -> (size: i64, err: Error) {
size = -1 size = -1
s := _fstat(fd) or_return s := _fstat(fd) or_return
@@ -537,6 +538,7 @@ remove_directory :: proc(path: string) -> Error {
return nil return nil
} }
@(require_results)
is_file_handle :: proc(fd: Handle) -> bool { is_file_handle :: proc(fd: Handle) -> bool {
s, err := _fstat(fd) s, err := _fstat(fd)
if err != nil { if err != nil {
@@ -545,6 +547,7 @@ is_file_handle :: proc(fd: Handle) -> bool {
return S_ISREG(s.mode) return S_ISREG(s.mode)
} }
@(require_results)
is_file_path :: proc(path: string, follow_links: bool = true) -> bool { is_file_path :: proc(path: string, follow_links: bool = true) -> bool {
s: OS_Stat s: OS_Stat
err: Error err: Error
@@ -559,6 +562,7 @@ is_file_path :: proc(path: string, follow_links: bool = true) -> bool {
return S_ISREG(s.mode) return S_ISREG(s.mode)
} }
@(require_results)
is_dir_handle :: proc(fd: Handle) -> bool { is_dir_handle :: proc(fd: Handle) -> bool {
s, err := _fstat(fd) s, err := _fstat(fd)
if err != nil { if err != nil {
@@ -567,6 +571,7 @@ is_dir_handle :: proc(fd: Handle) -> bool {
return S_ISDIR(s.mode) return S_ISDIR(s.mode)
} }
@(require_results)
is_dir_path :: proc(path: string, follow_links: bool = true) -> bool { is_dir_path :: proc(path: string, follow_links: bool = true) -> bool {
s: OS_Stat s: OS_Stat
err: Error err: Error
@@ -594,19 +599,21 @@ stderr: Handle = 2
last_write_time :: proc(fd: Handle) -> File_Time {} last_write_time :: proc(fd: Handle) -> File_Time {}
last_write_time_by_name :: proc(name: string) -> File_Time {} last_write_time_by_name :: proc(name: string) -> File_Time {}
*/ */
@(require_results)
last_write_time :: proc(fd: Handle) -> (time: File_Time, err: Error) { last_write_time :: proc(fd: Handle) -> (time: File_Time, err: Error) {
s := _fstat(fd) or_return s := _fstat(fd) or_return
modified := s.modified.seconds * 1_000_000_000 + s.modified.nanoseconds modified := s.modified.seconds * 1_000_000_000 + s.modified.nanoseconds
return File_Time(modified), nil return File_Time(modified), nil
} }
@(require_results)
last_write_time_by_name :: proc(name: string) -> (time: File_Time, err: Error) { last_write_time_by_name :: proc(name: string) -> (time: File_Time, err: Error) {
s := _stat(name) or_return s := _stat(name) or_return
modified := s.modified.seconds * 1_000_000_000 + s.modified.nanoseconds modified := s.modified.seconds * 1_000_000_000 + s.modified.nanoseconds
return File_Time(modified), nil return File_Time(modified), nil
} }
@private @(private, require_results)
_stat :: proc(path: string) -> (OS_Stat, Error) { _stat :: proc(path: string) -> (OS_Stat, Error) {
runtime.DEFAULT_TEMP_ALLOCATOR_TEMP_GUARD() runtime.DEFAULT_TEMP_ALLOCATOR_TEMP_GUARD()
cstr := strings.clone_to_cstring(path, context.temp_allocator) cstr := strings.clone_to_cstring(path, context.temp_allocator)
@@ -620,7 +627,7 @@ _stat :: proc(path: string) -> (OS_Stat, Error) {
return s, nil return s, nil
} }
@private @(private, require_results)
_lstat :: proc(path: string) -> (OS_Stat, Error) { _lstat :: proc(path: string) -> (OS_Stat, Error) {
runtime.DEFAULT_TEMP_ALLOCATOR_TEMP_GUARD() runtime.DEFAULT_TEMP_ALLOCATOR_TEMP_GUARD()
cstr := strings.clone_to_cstring(path, context.temp_allocator) cstr := strings.clone_to_cstring(path, context.temp_allocator)
@@ -634,7 +641,7 @@ _lstat :: proc(path: string) -> (OS_Stat, Error) {
return s, nil return s, nil
} }
@private @(private, require_results)
_fstat :: proc(fd: Handle) -> (OS_Stat, Error) { _fstat :: proc(fd: Handle) -> (OS_Stat, Error) {
// deliberately uninitialized // deliberately uninitialized
s: OS_Stat = --- s: OS_Stat = ---
@@ -645,7 +652,7 @@ _fstat :: proc(fd: Handle) -> (OS_Stat, Error) {
return s, nil return s, nil
} }
@private @(private, require_results)
_fdopendir :: proc(fd: Handle) -> (Dir, Error) { _fdopendir :: proc(fd: Handle) -> (Dir, Error) {
dirp := _unix_fdopendir(fd) dirp := _unix_fdopendir(fd)
if dirp == cast(Dir)nil { if dirp == cast(Dir)nil {
@@ -654,7 +661,7 @@ _fdopendir :: proc(fd: Handle) -> (Dir, Error) {
return dirp, nil return dirp, nil
} }
@private @(private)
_closedir :: proc(dirp: Dir) -> Error { _closedir :: proc(dirp: Dir) -> Error {
rc := _unix_closedir(dirp) rc := _unix_closedir(dirp)
if rc != 0 { if rc != 0 {
@@ -663,12 +670,12 @@ _closedir :: proc(dirp: Dir) -> Error {
return nil return nil
} }
@private @(private)
_rewinddir :: proc(dirp: Dir) { _rewinddir :: proc(dirp: Dir) {
_unix_rewinddir(dirp) _unix_rewinddir(dirp)
} }
@private @(private, require_results)
_readdir :: proc(dirp: Dir) -> (entry: Dirent, err: Error, end_of_stream: bool) { _readdir :: proc(dirp: Dir) -> (entry: Dirent, err: Error, end_of_stream: bool) {
result: ^Dirent result: ^Dirent
rc := _unix_readdir_r(dirp, &entry, &result) rc := _unix_readdir_r(dirp, &entry, &result)
@@ -687,7 +694,7 @@ _readdir :: proc(dirp: Dir) -> (entry: Dirent, err: Error, end_of_stream: bool)
return return
} }
@private @(private, require_results)
_readlink :: proc(path: string) -> (string, Error) { _readlink :: proc(path: string) -> (string, Error) {
runtime.DEFAULT_TEMP_ALLOCATOR_TEMP_GUARD(ignore = context.temp_allocator == context.allocator) 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)
@@ -710,10 +717,12 @@ _readlink :: proc(path: string) -> (string, Error) {
} }
// XXX OpenBSD // XXX OpenBSD
@(require_results)
absolute_path_from_handle :: proc(fd: Handle) -> (string, Error) { absolute_path_from_handle :: proc(fd: Handle) -> (string, Error) {
return "", Error(ENOSYS) return "", Error(ENOSYS)
} }
@(require_results)
absolute_path_from_relative :: proc(rel: string) -> (path: string, err: Error) { absolute_path_from_relative :: proc(rel: string) -> (path: string, err: Error) {
rel := rel rel := rel
if rel == "" { if rel == "" {
@@ -744,6 +753,7 @@ access :: proc(path: string, mask: int) -> (bool, Error) {
return true, nil return true, nil
} }
@(require_results)
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) 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)
@@ -754,11 +764,13 @@ lookup_env :: proc(key: string, allocator := context.allocator) -> (value: strin
return strings.clone(string(cstr), allocator), true return strings.clone(string(cstr), allocator), true
} }
@(require_results)
get_env :: proc(key: string, allocator := context.allocator) -> (value: string) { get_env :: proc(key: string, allocator := context.allocator) -> (value: string) {
value, _ = lookup_env(key, allocator) value, _ = lookup_env(key, allocator)
return return
} }
@(require_results)
get_current_directory :: proc() -> string { get_current_directory :: proc() -> string {
buf := make([dynamic]u8, MAX_PATH) buf := make([dynamic]u8, MAX_PATH)
for { for {
@@ -790,16 +802,19 @@ exit :: proc "contextless" (code: int) -> ! {
_unix_exit(c.int(code)) _unix_exit(c.int(code))
} }
@(require_results)
current_thread_id :: proc "contextless" () -> int { current_thread_id :: proc "contextless" () -> int {
return _unix_getthrid() return _unix_getthrid()
} }
@(require_results)
dlopen :: proc(filename: string, flags: int) -> rawptr { dlopen :: proc(filename: string, flags: int) -> rawptr {
runtime.DEFAULT_TEMP_ALLOCATOR_TEMP_GUARD() 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
} }
@(require_results)
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() runtime.DEFAULT_TEMP_ALLOCATOR_TEMP_GUARD()
@@ -811,10 +826,12 @@ dlclose :: proc(handle: rawptr) -> bool {
assert(handle != nil) assert(handle != nil)
return _unix_dlclose(handle) == 0 return _unix_dlclose(handle) == 0
} }
@(require_results)
dlerror :: proc() -> string { dlerror :: proc() -> string {
return string(_unix_dlerror()) return string(_unix_dlerror())
} }
@(require_results)
get_page_size :: proc() -> int { get_page_size :: proc() -> int {
// NOTE(tetra): The page size never changes, so why do anything complicated // NOTE(tetra): The page size never changes, so why do anything complicated
// if we don't have to. // if we don't have to.
@@ -829,11 +846,12 @@ get_page_size :: proc() -> int {
_SC_NPROCESSORS_ONLN :: 503 _SC_NPROCESSORS_ONLN :: 503
@(private) @(private, require_results)
_processor_core_count :: proc() -> int { _processor_core_count :: proc() -> int {
return int(_sysconf(_SC_NPROCESSORS_ONLN)) return int(_sysconf(_SC_NPROCESSORS_ONLN))
} }
@(require_results)
_alloc_command_line_arguments :: proc() -> []string { _alloc_command_line_arguments :: proc() -> []string {
res := make([]string, len(runtime.args__)) res := make([]string, len(runtime.args__))
for arg, i in runtime.args__ { for arg, i in runtime.args__ {
+7 -2
View File
@@ -27,6 +27,7 @@ stderr: Handle = 2
args := _alloc_command_line_arguments() args := _alloc_command_line_arguments()
@(require_results)
_alloc_command_line_arguments :: proc() -> (args: []string) { _alloc_command_line_arguments :: proc() -> (args: []string) {
args = make([]string, len(runtime.args__)) args = make([]string, len(runtime.args__))
for &arg, i in args { for &arg, i in args {
@@ -91,8 +92,9 @@ init_preopens :: proc() {
preopens = dyn_preopens[:] preopens = dyn_preopens[:]
} }
@(require_results)
wasi_match_preopen :: proc(path: string) -> (wasi.fd_t, string, bool) { wasi_match_preopen :: proc(path: string) -> (wasi.fd_t, string, bool) {
@(require_results)
prefix_matches :: proc(prefix, path: string) -> bool { prefix_matches :: proc(prefix, path: string) -> bool {
// Empty is valid for any relative path. // Empty is valid for any relative path.
if len(prefix) == 0 && len(path) > 0 && path[0] != '/' { if len(prefix) == 0 && len(path) > 0 && path[0] != '/' {
@@ -163,6 +165,7 @@ read_at :: proc(fd: Handle, data: []byte, offset: i64) -> (int, Errno) {
n, err := wasi.fd_pread(wasi.fd_t(fd), {iovs}, wasi.filesize_t(offset)) n, err := wasi.fd_pread(wasi.fd_t(fd), {iovs}, wasi.filesize_t(offset))
return int(n), Platform_Error(err) return int(n), Platform_Error(err)
} }
@(require_results)
open :: proc(path: string, mode: int = O_RDONLY, perm: int = 0) -> (Handle, Errno) { open :: proc(path: string, mode: int = O_RDONLY, perm: int = 0) -> (Handle, Errno) {
oflags: wasi.oflags_t oflags: wasi.oflags_t
if mode & O_CREATE == O_CREATE { if mode & O_CREATE == O_CREATE {
@@ -215,14 +218,16 @@ seek :: proc(fd: Handle, offset: i64, whence: int) -> (i64, Errno) {
n, err := wasi.fd_seek(wasi.fd_t(fd), wasi.filedelta_t(offset), wasi.whence_t(whence)) n, err := wasi.fd_seek(wasi.fd_t(fd), wasi.filedelta_t(offset), wasi.whence_t(whence))
return i64(n), Platform_Error(err) return i64(n), Platform_Error(err)
} }
@(require_results)
current_thread_id :: proc "contextless" () -> int { current_thread_id :: proc "contextless" () -> int {
return 0 return 0
} }
@(private) @(private, require_results)
_processor_core_count :: proc() -> int { _processor_core_count :: proc() -> int {
return 1 return 1
} }
@(require_results)
file_size :: proc(fd: Handle) -> (size: i64, err: Errno) { file_size :: proc(fd: Handle) -> (size: i64, err: Errno) {
stat := wasi.fd_filestat_get(wasi.fd_t(fd)) or_return stat := wasi.fd_filestat_get(wasi.fd_t(fd)) or_return
size = i64(stat.size) size = i64(stat.size)
+19 -9
View File
@@ -153,7 +153,7 @@ get_page_size :: proc() -> int {
return page_size return page_size
} }
@(private) @(private, require_results)
_processor_core_count :: proc() -> int { _processor_core_count :: proc() -> int {
length : win32.DWORD = 0 length : win32.DWORD = 0
result := win32.GetLogicalProcessorInformation(nil, &length) result := win32.GetLogicalProcessorInformation(nil, &length)
@@ -184,12 +184,14 @@ exit :: proc "contextless" (code: int) -> ! {
@(require_results)
current_thread_id :: proc "contextless" () -> int { current_thread_id :: proc "contextless" () -> int {
return int(win32.GetCurrentThreadId()) return int(win32.GetCurrentThreadId())
} }
@(require_results)
_alloc_command_line_arguments :: proc() -> []string { _alloc_command_line_arguments :: proc() -> []string {
arg_count: i32 arg_count: i32
arg_list_ptr := win32.CommandLineToArgvW(win32.GetCommandLineW(), &arg_count) arg_list_ptr := win32.CommandLineToArgvW(win32.GetCommandLineW(), &arg_count)
@@ -223,44 +225,52 @@ _alloc_command_line_arguments :: proc() -> []string {
*/ */
WINDOWS_11_BUILD_CUTOFF :: 22_000 WINDOWS_11_BUILD_CUTOFF :: 22_000
get_windows_version_w :: proc() -> win32.OSVERSIONINFOEXW { @(require_results)
get_windows_version_w :: proc "contextless" () -> win32.OSVERSIONINFOEXW {
osvi : win32.OSVERSIONINFOEXW osvi : win32.OSVERSIONINFOEXW
osvi.dwOSVersionInfoSize = size_of(win32.OSVERSIONINFOEXW) osvi.dwOSVersionInfoSize = size_of(win32.OSVERSIONINFOEXW)
win32.RtlGetVersion(&osvi) win32.RtlGetVersion(&osvi)
return osvi return osvi
} }
is_windows_xp :: proc() -> bool { @(require_results)
is_windows_xp :: proc "contextless" () -> bool {
osvi := get_windows_version_w() osvi := get_windows_version_w()
return (osvi.dwMajorVersion == 5 && osvi.dwMinorVersion == 1) return (osvi.dwMajorVersion == 5 && osvi.dwMinorVersion == 1)
} }
is_windows_vista :: proc() -> bool { @(require_results)
is_windows_vista :: proc "contextless" () -> bool {
osvi := get_windows_version_w() osvi := get_windows_version_w()
return (osvi.dwMajorVersion == 6 && osvi.dwMinorVersion == 0) return (osvi.dwMajorVersion == 6 && osvi.dwMinorVersion == 0)
} }
is_windows_7 :: proc() -> bool { @(require_results)
is_windows_7 :: proc "contextless" () -> bool {
osvi := get_windows_version_w() osvi := get_windows_version_w()
return (osvi.dwMajorVersion == 6 && osvi.dwMinorVersion == 1) return (osvi.dwMajorVersion == 6 && osvi.dwMinorVersion == 1)
} }
is_windows_8 :: proc() -> bool { @(require_results)
is_windows_8 :: proc "contextless" () -> bool {
osvi := get_windows_version_w() osvi := get_windows_version_w()
return (osvi.dwMajorVersion == 6 && osvi.dwMinorVersion == 2) return (osvi.dwMajorVersion == 6 && osvi.dwMinorVersion == 2)
} }
is_windows_8_1 :: proc() -> bool { @(require_results)
is_windows_8_1 :: proc "contextless" () -> bool {
osvi := get_windows_version_w() osvi := get_windows_version_w()
return (osvi.dwMajorVersion == 6 && osvi.dwMinorVersion == 3) return (osvi.dwMajorVersion == 6 && osvi.dwMinorVersion == 3)
} }
is_windows_10 :: proc() -> bool { @(require_results)
is_windows_10 :: proc "contextless" () -> bool {
osvi := get_windows_version_w() osvi := get_windows_version_w()
return (osvi.dwMajorVersion == 10 && osvi.dwMinorVersion == 0 && osvi.dwBuildNumber < WINDOWS_11_BUILD_CUTOFF) return (osvi.dwMajorVersion == 10 && osvi.dwMinorVersion == 0 && osvi.dwBuildNumber < WINDOWS_11_BUILD_CUTOFF)
} }
is_windows_11 :: proc() -> bool { @(require_results)
is_windows_11 :: proc "contextless" () -> bool {
osvi := get_windows_version_w() osvi := get_windows_version_w()
return (osvi.dwMajorVersion == 10 && osvi.dwMinorVersion == 0 && osvi.dwBuildNumber >= WINDOWS_11_BUILD_CUTOFF) return (osvi.dwMajorVersion == 10 && osvi.dwMinorVersion == 0 && osvi.dwBuildNumber >= WINDOWS_11_BUILD_CUTOFF)
} }
+6 -3
View File
@@ -50,14 +50,14 @@ File_Info :: struct {
} }
*/ */
@private @(private, require_results)
_make_time_from_unix_file_time :: proc(uft: Unix_File_Time) -> time.Time { _make_time_from_unix_file_time :: proc(uft: Unix_File_Time) -> time.Time {
return time.Time{ return time.Time{
_nsec = uft.nanoseconds + uft.seconds * 1_000_000_000, _nsec = uft.nanoseconds + uft.seconds * 1_000_000_000,
} }
} }
@private @(private)
_fill_file_info_from_stat :: proc(fi: ^File_Info, s: OS_Stat) { _fill_file_info_from_stat :: proc(fi: ^File_Info, s: OS_Stat) {
fi.size = s.size fi.size = s.size
fi.mode = cast(File_Mode)s.mode fi.mode = cast(File_Mode)s.mode
@@ -71,7 +71,7 @@ _fill_file_info_from_stat :: proc(fi: ^File_Info, s: OS_Stat) {
} }
@private @(private, require_results)
path_base :: proc(path: string) -> string { path_base :: proc(path: string) -> string {
is_separator :: proc(c: byte) -> bool { is_separator :: proc(c: byte) -> bool {
return c == '/' return c == '/'
@@ -100,6 +100,7 @@ path_base :: proc(path: string) -> string {
} }
@(require_results)
lstat :: proc(name: string, allocator := context.allocator) -> (fi: File_Info, err: Error) { lstat :: proc(name: string, allocator := context.allocator) -> (fi: File_Info, err: Error) {
context.allocator = allocator context.allocator = allocator
@@ -110,6 +111,7 @@ lstat :: proc(name: string, allocator := context.allocator) -> (fi: File_Info, e
return return
} }
@(require_results)
stat :: proc(name: string, allocator := context.allocator) -> (fi: File_Info, err: Error) { stat :: proc(name: string, allocator := context.allocator) -> (fi: File_Info, err: Error) {
context.allocator = allocator context.allocator = allocator
@@ -120,6 +122,7 @@ stat :: proc(name: string, allocator := context.allocator) -> (fi: File_Info, er
return return
} }
@(require_results)
fstat :: proc(fd: Handle, allocator := context.allocator) -> (fi: File_Info, err: Error) { fstat :: proc(fd: Handle, allocator := context.allocator) -> (fi: File_Info, err: Error) {
context.allocator = allocator context.allocator = allocator
+15 -12
View File
@@ -4,7 +4,7 @@ import "core:time"
import "base:runtime" import "base:runtime"
import win32 "core:sys/windows" import win32 "core:sys/windows"
@(private) @(private, require_results)
full_path_from_name :: proc(name: string, allocator := context.allocator) -> (path: string, err: Errno) { full_path_from_name :: proc(name: string, allocator := context.allocator) -> (path: string, err: Errno) {
context.allocator = allocator context.allocator = allocator
@@ -30,7 +30,7 @@ full_path_from_name :: proc(name: string, allocator := context.allocator) -> (pa
return return
} }
@(private) @(private, require_results)
_stat :: proc(name: string, create_file_attributes: u32, allocator := context.allocator) -> (fi: File_Info, e: Errno) { _stat :: proc(name: string, create_file_attributes: u32, allocator := context.allocator) -> (fi: File_Info, e: Errno) {
if len(name) == 0 { if len(name) == 0 {
return {}, ERROR_PATH_NOT_FOUND return {}, ERROR_PATH_NOT_FOUND
@@ -72,17 +72,20 @@ _stat :: proc(name: string, create_file_attributes: u32, allocator := context.al
} }
@(require_results)
lstat :: proc(name: string, allocator := context.allocator) -> (File_Info, Errno) { lstat :: proc(name: string, allocator := context.allocator) -> (File_Info, Errno) {
attrs := win32.FILE_FLAG_BACKUP_SEMANTICS attrs := win32.FILE_FLAG_BACKUP_SEMANTICS
attrs |= win32.FILE_FLAG_OPEN_REPARSE_POINT attrs |= win32.FILE_FLAG_OPEN_REPARSE_POINT
return _stat(name, attrs, allocator) return _stat(name, attrs, allocator)
} }
@(require_results)
stat :: proc(name: string, allocator := context.allocator) -> (File_Info, Errno) { stat :: proc(name: string, allocator := context.allocator) -> (File_Info, Errno) {
attrs := win32.FILE_FLAG_BACKUP_SEMANTICS attrs := win32.FILE_FLAG_BACKUP_SEMANTICS
return _stat(name, attrs, allocator) return _stat(name, attrs, allocator)
} }
@(require_results)
fstat :: proc(fd: Handle, allocator := context.allocator) -> (fi: File_Info, err: Errno) { fstat :: proc(fd: Handle, allocator := context.allocator) -> (fi: File_Info, err: Errno) {
if fd == 0 { if fd == 0 {
err = ERROR_INVALID_HANDLE err = ERROR_INVALID_HANDLE
@@ -108,7 +111,7 @@ fstat :: proc(fd: Handle, allocator := context.allocator) -> (fi: File_Info, err
} }
@(private) @(private, require_results)
cleanpath_strip_prefix :: proc(buf: []u16) -> []u16 { cleanpath_strip_prefix :: proc(buf: []u16) -> []u16 {
buf := buf buf := buf
N := 0 N := 0
@@ -133,13 +136,13 @@ cleanpath_strip_prefix :: proc(buf: []u16) -> []u16 {
return buf return buf
} }
@(private) @(private, require_results)
cleanpath_from_handle :: proc(fd: Handle) -> (s: string, err: Errno) { cleanpath_from_handle :: proc(fd: Handle) -> (s: string, err: Errno) {
runtime.DEFAULT_TEMP_ALLOCATOR_TEMP_GUARD(ignore = context.temp_allocator == context.allocator) runtime.DEFAULT_TEMP_ALLOCATOR_TEMP_GUARD(ignore = context.temp_allocator == context.allocator)
buf := cleanpath_from_handle_u16(fd, context.temp_allocator) or_return buf := cleanpath_from_handle_u16(fd, context.temp_allocator) or_return
return win32.utf16_to_utf8(buf, context.allocator) return win32.utf16_to_utf8(buf, context.allocator)
} }
@(private) @(private, require_results)
cleanpath_from_handle_u16 :: proc(fd: Handle, allocator: runtime.Allocator) -> ([]u16, Errno) { cleanpath_from_handle_u16 :: proc(fd: Handle, allocator: runtime.Allocator) -> ([]u16, Errno) {
if fd == 0 { if fd == 0 {
return nil, ERROR_INVALID_HANDLE return nil, ERROR_INVALID_HANDLE
@@ -154,14 +157,14 @@ cleanpath_from_handle_u16 :: proc(fd: Handle, allocator: runtime.Allocator) -> (
buf_len := win32.GetFinalPathNameByHandleW(h, raw_data(buf), n, 0) buf_len := win32.GetFinalPathNameByHandleW(h, raw_data(buf), n, 0)
return buf[:buf_len], nil return buf[:buf_len], nil
} }
@(private) @(private, require_results)
cleanpath_from_buf :: proc(buf: []u16) -> string { cleanpath_from_buf :: proc(buf: []u16) -> string {
buf := buf buf := buf
buf = cleanpath_strip_prefix(buf) buf = cleanpath_strip_prefix(buf)
return win32.utf16_to_utf8(buf, context.allocator) or_else "" return win32.utf16_to_utf8(buf, context.allocator) or_else ""
} }
@(private) @(private, require_results)
basename :: proc(name: string) -> (base: string) { basename :: proc(name: string) -> (base: string) {
name := name name := name
if len(name) > 3 && name[:3] == `\\?` { if len(name) > 3 && name[:3] == `\\?` {
@@ -187,7 +190,7 @@ basename :: proc(name: string) -> (base: string) {
return name return name
} }
@(private) @(private, require_results)
file_type_mode :: proc(h: win32.HANDLE) -> File_Mode { file_type_mode :: proc(h: win32.HANDLE) -> File_Mode {
switch win32.GetFileType(h) { switch win32.GetFileType(h) {
case win32.FILE_TYPE_PIPE: case win32.FILE_TYPE_PIPE:
@@ -199,7 +202,7 @@ file_type_mode :: proc(h: win32.HANDLE) -> File_Mode {
} }
@(private) @(private, require_results)
file_mode_from_file_attributes :: proc(FileAttributes: win32.DWORD, h: win32.HANDLE, ReparseTag: win32.DWORD) -> (mode: File_Mode) { file_mode_from_file_attributes :: proc(FileAttributes: win32.DWORD, h: win32.HANDLE, ReparseTag: win32.DWORD) -> (mode: File_Mode) {
if FileAttributes & win32.FILE_ATTRIBUTE_READONLY != 0 { if FileAttributes & win32.FILE_ATTRIBUTE_READONLY != 0 {
mode |= 0o444 mode |= 0o444
@@ -236,7 +239,7 @@ windows_set_file_info_times :: proc(fi: ^File_Info, d: ^$T) {
fi.access_time = time.unix(0, win32.FILETIME_as_unix_nanoseconds(d.ftLastAccessTime)) fi.access_time = time.unix(0, win32.FILETIME_as_unix_nanoseconds(d.ftLastAccessTime))
} }
@(private) @(private, require_results)
file_info_from_win32_file_attribute_data :: proc(d: ^win32.WIN32_FILE_ATTRIBUTE_DATA, name: string) -> (fi: File_Info, e: Errno) { file_info_from_win32_file_attribute_data :: proc(d: ^win32.WIN32_FILE_ATTRIBUTE_DATA, name: string) -> (fi: File_Info, e: Errno) {
fi.size = i64(d.nFileSizeHigh)<<32 + i64(d.nFileSizeLow) fi.size = i64(d.nFileSizeHigh)<<32 + i64(d.nFileSizeLow)
@@ -251,7 +254,7 @@ file_info_from_win32_file_attribute_data :: proc(d: ^win32.WIN32_FILE_ATTRIBUTE_
return return
} }
@(private) @(private, require_results)
file_info_from_win32_find_data :: proc(d: ^win32.WIN32_FIND_DATAW, name: string) -> (fi: File_Info, e: Errno) { file_info_from_win32_find_data :: proc(d: ^win32.WIN32_FIND_DATAW, name: string) -> (fi: File_Info, e: Errno) {
fi.size = i64(d.nFileSizeHigh)<<32 + i64(d.nFileSizeLow) fi.size = i64(d.nFileSizeHigh)<<32 + i64(d.nFileSizeLow)
@@ -266,7 +269,7 @@ file_info_from_win32_find_data :: proc(d: ^win32.WIN32_FIND_DATAW, name: string)
return return
} }
@(private) @(private, require_results)
file_info_from_get_file_information_by_handle :: proc(path: string, h: win32.HANDLE) -> (File_Info, Errno) { file_info_from_get_file_information_by_handle :: proc(path: string, h: win32.HANDLE) -> (File_Info, Errno) {
d: win32.BY_HANDLE_FILE_INFORMATION d: win32.BY_HANDLE_FILE_INFORMATION
if !win32.GetFileInformationByHandle(h, &d) { if !win32.GetFileInformationByHandle(h, &d) {