diff --git a/core/os/dir_unix.odin b/core/os/dir_unix.odin index 6f6bed36d0b..ea5a86bcada 100644 --- a/core/os/dir_unix.odin +++ b/core/os/dir_unix.odin @@ -4,7 +4,7 @@ package os import "core:strings" @(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) { dirp := _fdopendir(fd) or_return defer _closedir(dirp) diff --git a/core/os/dir_windows.odin b/core/os/dir_windows.odin index ae3e6922c23..c8472a5ad95 100644 --- a/core/os/dir_windows.odin +++ b/core/os/dir_windows.odin @@ -5,7 +5,7 @@ import "core:strings" import "base:runtime" @(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) { // Ignore "." and ".." diff --git a/core/os/env_windows.odin b/core/os/env_windows.odin index efd002342b3..466859019f1 100644 --- a/core/os/env_windows.odin +++ b/core/os/env_windows.odin @@ -8,7 +8,7 @@ import "base:runtime" // Otherwise the returned value will be empty and the boolean will be false // NOTE: the value will be allocated with the supplied allocator @(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) { if key == "" { return } @@ -35,13 +35,13 @@ lookup_env :: proc(key: string, allocator := context.allocator) -> (value: strin // To distinguish between an empty value and an unset value, use lookup_env // NOTE: the value will be allocated with the supplied allocator @(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) return } // set_env sets the value of the environment variable named by the key -set_env :: proc(key, value: string) -> Error { +_set_env :: proc(key, value: string) -> Error { k := win32.utf8_to_wstring(key) v := win32.utf8_to_wstring(value) @@ -52,7 +52,7 @@ set_env :: proc(key, value: string) -> Error { } // unset_env unsets a single environment variable -unset_env :: proc(key: string) -> Error { +_unset_env :: proc(key: string) -> Error { k := win32.utf8_to_wstring(key) if !win32.SetEnvironmentVariableW(k, nil) { return get_last_error() @@ -63,7 +63,7 @@ unset_env :: proc(key: string) -> Error { // environ returns a copy of strings representing the environment, in the form "key=value" // NOTE: the slice of strings and the strings with be allocated using the supplied allocator @(require_results) -environ :: proc(allocator := context.allocator) -> []string { +_environ :: proc(allocator := context.allocator) -> []string { envs := ([^]win32.WCHAR)(win32.GetEnvironmentStringsW()) if envs == nil { return nil @@ -89,7 +89,7 @@ environ :: proc(allocator := context.allocator) -> []string { // clear_env deletes all environment variables -clear_env :: proc() { +_clear_env :: proc() { runtime.DEFAULT_TEMP_ALLOCATOR_TEMP_GUARD() envs := environ(context.temp_allocator) for env in envs { diff --git a/core/os/file_windows.odin b/core/os/file_windows.odin index 3f6f781aa0a..000a4f76cea 100644 --- a/core/os/file_windows.odin +++ b/core/os/file_windows.odin @@ -6,12 +6,12 @@ import "base:runtime" import "core:unicode/utf16" @(require_results) -is_path_separator :: proc(c: byte) -> bool { +_is_path_separator :: proc "contextless" (c: rune) -> bool { 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 { return INVALID_HANDLE, General_Error.Not_Exist } @@ -60,14 +60,14 @@ open :: proc(path: string, mode: int = O_RDONLY, perm: int = 0) -> (Handle, Erro return INVALID_HANDLE, get_last_error() } -close :: proc(fd: Handle) -> Error { +_close :: proc(fd: Handle) -> Error { if !win32.CloseHandle(win32.HANDLE(fd)) { return get_last_error() } return nil } -flush :: proc(fd: Handle) -> (err: Error) { +_flush :: proc(fd: Handle) -> (err: Error) { if !win32.FlushFileBuffers(win32.HANDLE(fd)) { err = get_last_error() } @@ -76,7 +76,7 @@ flush :: proc(fd: Handle) -> (err: Error) { -write :: proc(fd: Handle, data: []byte) -> (int, Error) { +_write :: proc(fd: Handle, data: []byte) -> (int, Error) { if len(data) == 0 { return 0, nil } @@ -149,7 +149,7 @@ read_console :: proc(handle: win32.HANDLE, b: []byte) -> (n: int, err: Error) { return } -read :: proc(fd: Handle, data: []byte) -> (total_read: int, err: Error) { +_read :: proc(fd: Handle, data: []byte) -> (total_read: int, err: Error) { if len(data) == 0 { return 0, nil } @@ -186,7 +186,7 @@ read :: proc(fd: Handle, data: []byte) -> (total_read: int, err: Error) { return total_read, nil } -seek :: proc(fd: Handle, offset: i64, whence: int) -> (i64, Error) { +_seek :: proc(fd: Handle, offset: i64, whence: int) -> (i64, Error) { w: u32 switch whence { case 0: w = win32.FILE_BEGIN @@ -209,7 +209,7 @@ seek :: proc(fd: Handle, offset: i64, whence: int) -> (i64, Error) { } @(require_results) -file_size :: proc(fd: Handle) -> (i64, Error) { +_file_size :: proc(fd: Handle) -> (i64, Error) { length: win32.LARGE_INTEGER err: Error if !win32.GetFileSizeEx(win32.HANDLE(fd), &length) { @@ -279,7 +279,7 @@ on Windows, read_at changes the position of the file cursor, on *nix, it does no will read from the location twice on *nix, and from two different locations on Windows */ -read_at :: proc(fd: Handle, data: []byte, offset: i64) -> (n: int, err: Error) { +_read_at :: proc(fd: Handle, data: []byte, offset: i64) -> (n: int, err: Error) { if offset < 0 { return 0, .Invalid_Offset } @@ -311,7 +311,7 @@ on Windows, write_at changes the position of the file cursor, on *nix, it does n will write to the location twice on *nix, and to two different locations on Windows */ -write_at :: proc(fd: Handle, data: []byte, offset: i64) -> (n: int, err: Error) { +_write_at :: proc(fd: Handle, data: []byte, offset: i64) -> (n: int, err: Error) { if offset < 0 { return 0, .Invalid_Offset } @@ -341,7 +341,7 @@ get_std_handle :: proc "contextless" (h: uint) -> Handle { } -exists :: proc(path: string) -> bool { +_exists :: proc(path: string) -> bool { runtime.DEFAULT_TEMP_ALLOCATOR_TEMP_GUARD() wpath := win32.utf8_to_wstring(path, context.temp_allocator) attribs := win32.GetFileAttributesW(wpath) @@ -350,7 +350,7 @@ exists :: proc(path: string) -> bool { } @(require_results) -is_file :: proc(path: string) -> bool { +_is_file_path :: proc(path: string, _: bool) -> bool { runtime.DEFAULT_TEMP_ALLOCATOR_TEMP_GUARD() wpath := win32.utf8_to_wstring(path, context.temp_allocator) attribs := win32.GetFileAttributesW(wpath) @@ -362,7 +362,7 @@ is_file :: proc(path: string) -> bool { } @(require_results) -is_dir :: proc(path: string) -> bool { +_is_dir_path :: proc(path: string, _: bool) -> bool { runtime.DEFAULT_TEMP_ALLOCATOR_TEMP_GUARD() wpath := win32.utf8_to_wstring(path, context.temp_allocator) attribs := win32.GetFileAttributesW(wpath) @@ -373,11 +373,21 @@ is_dir :: proc(path: string) -> bool { return false } +@(require_results) +_is_file_handle :: proc(fd: Handle) -> bool { + return false +} + +@(require_results) +_is_dir_handle :: proc(fd: Handle) -> bool { + return false +} + // NOTE(tetra): GetCurrentDirectory is not thread safe with SetCurrentDirectory and GetFullPathName @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) runtime.DEFAULT_TEMP_ALLOCATOR_TEMP_GUARD(ignore = context.temp_allocator == allocator) @@ -393,7 +403,7 @@ get_current_directory :: proc(allocator := context.allocator) -> string { return win32.utf16_to_utf8(dir_buf_wstr, allocator) or_else "" } -set_current_directory :: proc(path: string) -> (err: Error) { +_set_current_directory :: proc(path: string) -> (err: Error) { runtime.DEFAULT_TEMP_ALLOCATOR_TEMP_GUARD() wstr := win32.utf8_to_wstring(path, context.temp_allocator) @@ -407,9 +417,8 @@ set_current_directory :: proc(path: string) -> (err: Error) { return } -change_directory :: set_current_directory -make_directory :: proc(path: string, mode: u32 = 0) -> (err: Error) { +_make_directory :: proc(path: string, mode: u32 = 0) -> (err: Error) { runtime.DEFAULT_TEMP_ALLOCATOR_TEMP_GUARD() // Mode is unused on Windows, but is needed on *nix wpath := win32.utf8_to_wstring(path, context.temp_allocator) @@ -421,7 +430,7 @@ make_directory :: proc(path: string, mode: u32 = 0) -> (err: Error) { } -remove_directory :: proc(path: string) -> (err: Error) { +_remove_directory :: proc(path: string) -> (err: Error) { runtime.DEFAULT_TEMP_ALLOCATOR_TEMP_GUARD() wpath := win32.utf8_to_wstring(path, context.temp_allocator) @@ -494,14 +503,14 @@ fix_long_path :: proc(path: string) -> string { } -link :: proc(old_name, new_name: string) -> (err: Error) { +_link :: proc(old_name, new_name: string) -> (err: Error) { runtime.DEFAULT_TEMP_ALLOCATOR_TEMP_GUARD() n := win32.utf8_to_wstring(fix_long_path(new_name)) o := win32.utf8_to_wstring(fix_long_path(old_name)) return Platform_Error(win32.CreateHardLinkW(n, o, nil)) } -unlink :: proc(path: string) -> (err: Error) { +_unlink :: proc(path: string) -> (err: Error) { runtime.DEFAULT_TEMP_ALLOCATOR_TEMP_GUARD() wpath := win32.utf8_to_wstring(path, context.temp_allocator) @@ -513,7 +522,7 @@ unlink :: proc(path: string) -> (err: Error) { -rename :: proc(old_path, new_path: string) -> (err: Error) { +_rename :: proc(old_path, new_path: string) -> (err: Error) { runtime.DEFAULT_TEMP_ALLOCATOR_TEMP_GUARD() from := win32.utf8_to_wstring(old_path, context.temp_allocator) to := win32.utf8_to_wstring(new_path, context.temp_allocator) @@ -525,7 +534,7 @@ rename :: proc(old_path, new_path: string) -> (err: Error) { } -ftruncate :: proc(fd: Handle, length: i64) -> (err: Error) { +_ftruncate :: proc(fd: Handle, length: i64) -> (err: Error) { curr_off := seek(fd, 0, 1) or_return defer seek(fd, curr_off, 0) _= seek(fd, length, 0) or_return @@ -536,14 +545,14 @@ ftruncate :: proc(fd: Handle, length: i64) -> (err: Error) { return nil } -truncate :: proc(path: string, length: i64) -> (err: Error) { +_truncate :: proc(path: string, length: i64) -> (err: Error) { fd := open(path, O_WRONLY|O_CREATE, 0o666) or_return defer close(fd) return ftruncate(fd, length) } -remove :: proc(name: string) -> Error { +_remove :: proc(name: string) -> Error { p := win32.utf8_to_wstring(fix_long_path(name)) err, err1: win32.DWORD if !win32.DeleteFileW(p) { @@ -582,7 +591,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.nLength = size_of(win32.SECURITY_ATTRIBUTES) sa.bInheritHandle = true diff --git a/core/os/os.odin b/core/os/os.odin index 568c0a2aa71..32c4afebc5c 100644 --- a/core/os/os.odin +++ b/core/os/os.odin @@ -15,6 +15,210 @@ SEEK_SET :: 0 SEEK_CUR :: 1 SEEK_END :: 2 + +@(require_results, no_instrumentation) +get_last_error :: proc "contextless" () -> Error { + return _get_last_error() +} + +@(require_results) +open :: proc(path: string, flags: int = O_RDWR, mode: int = 0) -> (handle: Handle, err: Error) { + return _open(path, flags, mode) +} + +close :: proc(fd: Handle) -> Error { + return _close(fd) +} + +flush :: proc(fd: Handle) -> Error { + return _flush(fd) +} + +write :: proc(fd: Handle, data: []byte) -> (int, Error) { + return _write(fd, data) +} +read :: proc(fd: Handle, data: []byte) -> (int, Error) { + return _read(fd, data) +} +read_at :: proc(fd: Handle, data: []byte, offset: i64) -> (int, Error) { + return _read_at(fd, data, offset) +} +write_at :: proc(fd: Handle, data: []byte, offset: i64) -> (int, Error) { + return _write_at(fd, data, offset) +} +seek :: proc(fd: Handle, offset: i64, whence: int) -> (i64, Error) { + return _seek(fd, offset, whence) +} + +@(require_results) +last_write_time :: proc(fd: Handle) -> (time: File_Time, err: Error) { + return _last_write_time(fd) +} + +@(require_results) +last_write_time_by_name :: proc(name: string) -> (time: File_Time, err: Error) { + return _last_write_time_by_name(name) +} + +@(require_results) +is_path_separator_rune :: proc "contextless" (r: rune) -> bool { + return _is_path_separator(r) +} +@(require_results) +is_path_separator_byte :: proc "contextless" (b: byte) -> bool { + return _is_path_separator(rune(b)) +} + +is_path_separator :: proc{ + is_path_separator_rune, + is_path_separator_byte, +} + +@(require_results) +is_file_handle :: proc(fd: Handle) -> bool { + return _is_file_handle(fd) +} + +@(require_results) +is_file_path :: proc(path: string, follow_links: bool = true) -> bool { + return _is_file_path(path, follow_links) +} + +@(require_results) +is_dir_handle :: proc(fd: Handle) -> bool { + return _is_dir_handle(fd) +} + +@(require_results) +is_dir_path :: proc(path: string, follow_links: bool = true) -> bool { + return _is_dir_path(path, follow_links) +} + +is_file :: proc {is_file_path, is_file_handle} +is_dir :: proc {is_dir_path, is_dir_handle} + + +@(require_results) +file_size :: proc(fd: Handle) -> (i64, Error) { + return _file_size(fd) +} + +@(require_results) +exists :: proc(path: string) -> bool { + return _exists(path) +} + +rename :: proc(old, new: string) -> Error { + return _rename(old, new) +} + +remove :: proc(path: string) -> Error { + return _remove(path) +} + +link :: proc(old_name, new_name: string) -> (err: Error) { + return _link(old_name, new_name) +} +unlink :: proc(path: string) -> (err: Error) { + return _unlink(path) +} +ftruncate :: proc(fd: Handle, length: i64) -> (err: Error) { + return _ftruncate(fd, length) +} + +truncate :: proc(path: string, length: i64) -> (err: Error) { + return _truncate(path, length) +} + + +@(require_results) +pipe :: proc() -> (r, w: Handle, err: Error) { + return _pipe() +} + +@(require_results) +read_dir :: proc(fd: Handle, n: int, allocator := context.allocator) -> (fi: []File_Info, err: Error) { + return _read_dir(fd, n, allocator) +} + + + +@(require_results) +absolute_path_from_handle :: proc(fd: Handle) -> (path: string, err: Error) { + return _absolute_path_from_handle(fd) +} +@(require_results) +absolute_path_from_relative :: proc(rel: string) -> (path: string, err: Error) { + return _absolute_path_from_relative(rel) +} + +access :: proc(path: string, mask: int) -> (bool, Error) { + return _access(path, mask) +} + + +@(require_results) +environ :: proc(allocator := context.allocator) -> []string { + return _environ(allocator) +} +@(require_results) +lookup_env :: proc(key: string, allocator := context.allocator) -> (value: string, found: bool) { + return _lookup_env(key, allocator) +} + +@(require_results) +get_env :: proc(key: string, allocator := context.allocator) -> (value: string) { + return _get_env(key, allocator) +} + +set_env :: proc(key, value: string) -> Error { + return _set_env(key, value) +} +unset_env :: proc(key: string) -> Error { + return _unset_env(key) +} + +clear_env :: proc() { + _clear_env() +} + + +@(require_results) +get_current_directory :: proc() -> string { + return _get_current_directory() +} + + +set_current_directory :: proc(path: string) -> (err: Error) { + return _set_current_directory(path) +} + +change_directory :: set_current_directory + + +make_directory :: proc(path: string, mode: u32 = 0o775) -> Error { + return _make_directory(path, mode) +} + +remove_directory :: proc(path: string) -> Error { + return _remove_directory(path) +} + +exit :: proc "contextless" (code: int) -> ! { + _exit(code) +} + +@(require_results) +current_thread_id :: proc "contextless" () -> int { + return _current_thread_id() +} + +@(require_results) +get_page_size :: proc() -> int { + return _get_page_size() +} + + write_string :: proc(fd: Handle, str: string) -> (int, Error) { return write(fd, transmute([]byte)str) } diff --git a/core/os/os2/path_linux.odin b/core/os/os2/path_linux.odin index 62386675d75..5f1e45f3fca 100644 --- a/core/os/os2/path_linux.odin +++ b/core/os/os2/path_linux.odin @@ -11,7 +11,7 @@ _Path_List_Separator :: ':' _OPENDIR_FLAGS : linux.Open_Flags : {.NONBLOCK, .DIRECTORY, .LARGEFILE, .CLOEXEC} -_is_path_separator :: proc(c: byte) -> bool { +_is_path_separator :: proc(c: rune) -> bool { return c == '/' } diff --git a/core/os/os2/path_windows.odin b/core/os/os2/path_windows.odin index 4aa695ee27d..072824015d7 100644 --- a/core/os/os2/path_windows.odin +++ b/core/os/os2/path_windows.odin @@ -8,7 +8,7 @@ _Path_Separator :: '\\' _Path_Separator_String :: "\\" _Path_List_Separator :: ';' -_is_path_separator :: proc(c: byte) -> bool { +_is_path_separator :: proc "contextless" (c: rune) -> bool { return c == '\\' || c == '/' } diff --git a/core/os/os_darwin.odin b/core/os/os_darwin.odin index 09cdd84d062..c79d139b3e3 100644 --- a/core/os/os_darwin.odin +++ b/core/os/os_darwin.odin @@ -663,7 +663,7 @@ foreign dl { } @(require_results, no_instrumentation) -get_last_error :: proc "contextless" () -> Error { +_get_last_error :: proc "contextless" () -> Error { return Platform_Error(__error()^) } @@ -673,8 +673,8 @@ get_last_error_string :: proc() -> string { } -@(require_results) -open :: proc(path: string, flags: int = O_RDWR, mode: int = 0) -> (handle: Handle, err: Error) { +@(private, require_results) +_open :: proc(path: string, flags: int = O_RDWR, mode: int = 0) -> (handle: Handle, err: Error) { isDir := is_dir_path(path) flags := flags if isDir { @@ -712,7 +712,8 @@ fchmod :: proc(fd: Handle, mode: u16) -> Error { return cast(Platform_Error)_unix_fchmod(fd, mode) } -close :: proc(fd: Handle) -> Error { +@(private) +_close :: proc(fd: Handle) -> Error { return cast(Platform_Error)_unix_close(fd) } @@ -726,7 +727,8 @@ close :: proc(fd: Handle) -> Error { @(private) MAX_RW :: 1 << 30 -write :: proc(fd: Handle, data: []byte) -> (int, Error) { +@(private, require_results) +_write :: proc(fd: Handle, data: []byte) -> (int, Error) { if len(data) == 0 { return 0, nil } @@ -740,7 +742,8 @@ write :: proc(fd: Handle, data: []byte) -> (int, Error) { return bytes_written, nil } -read :: proc(fd: Handle, data: []u8) -> (int, Error) { +@(private, require_results) +_read :: proc(fd: Handle, data: []u8) -> (int, Error) { if len(data) == 0 { return 0, nil } @@ -754,7 +757,8 @@ read :: proc(fd: Handle, data: []u8) -> (int, Error) { return bytes_read, nil } -read_at :: proc(fd: Handle, data: []byte, offset: i64) -> (int, Error) { +@(private, require_results) +_read_at :: proc(fd: Handle, data: []byte, offset: i64) -> (int, Error) { if len(data) == 0 { return 0, nil } @@ -768,7 +772,8 @@ read_at :: proc(fd: Handle, data: []byte, offset: i64) -> (int, Error) { return bytes_read, nil } -write_at :: proc(fd: Handle, data: []byte, offset: i64) -> (int, Error) { +@(private, require_results) +_write_at :: proc(fd: Handle, data: []byte, offset: i64) -> (int, Error) { if len(data) == 0 { return 0, nil } @@ -782,7 +787,8 @@ write_at :: proc(fd: Handle, data: []byte, offset: i64) -> (int, Error) { return bytes_written, nil } -seek :: proc(fd: Handle, offset: i64, whence: int) -> (i64, Error) { +@(private, require_results) +_seek :: proc(fd: Handle, offset: i64, whence: int) -> (i64, Error) { assert(fd != -1) final_offset := i64(_unix_lseek(fd, int(offset), c.int(whence))) @@ -792,8 +798,8 @@ seek :: proc(fd: Handle, offset: i64, whence: int) -> (i64, Error) { return final_offset, nil } -@(require_results) -file_size :: proc(fd: Handle) -> (i64, Error) { +@(private, require_results) +_file_size :: proc(fd: Handle) -> (i64, Error) { prev, _ := seek(fd, 0, SEEK_CUR) size, err := seek(fd, 0, SEEK_END) seek(fd, prev, SEEK_SET) @@ -808,14 +814,14 @@ stdout: Handle = 1 // get_std_handle(win32.STD_OUTPUT_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 modified := s.modified.seconds * 1_000_000_000 + s.modified.nanoseconds 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 modified := s.modified.seconds * 1_000_000_000 + s.modified.nanoseconds return File_Time(modified), nil @@ -823,12 +829,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 "contextless" (r: rune) -> bool { return r == '/' } @(require_results) -is_file_handle :: proc(fd: Handle) -> bool { +_is_file_handle :: proc(fd: Handle) -> bool { s, err := _fstat(fd) if err != nil { return false @@ -837,7 +843,7 @@ is_file_handle :: proc(fd: Handle) -> bool { } @(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 err: Error if follow_links { @@ -853,7 +859,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) if err != nil { return false @@ -862,7 +868,7 @@ is_dir_handle :: proc(fd: Handle) -> bool { } @(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 err: Error if follow_links { @@ -876,25 +882,26 @@ is_dir_path :: proc(path: string, follow_links: bool = true) -> bool { return S_ISDIR(s.mode) } -is_file :: proc {is_file_path, is_file_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() cpath := strings.clone_to_cstring(path, context.temp_allocator) res := _unix_access(cpath, O_RDONLY) return res == 0 } -rename :: proc(old: string, new: string) -> bool { +_rename :: proc(old, new: string) -> Error { runtime.DEFAULT_TEMP_ALLOCATOR_TEMP_GUARD() old_cstr := strings.clone_to_cstring(old, context.temp_allocator) new_cstr := strings.clone_to_cstring(new, context.temp_allocator) - return _unix_rename(old_cstr, new_cstr) != -1 + res := _unix_rename(old_cstr, new_cstr) + if res == -1 { + return get_last_error() + } + return nil } -remove :: proc(path: string) -> Error { +_remove :: proc(path: string) -> Error { runtime.DEFAULT_TEMP_ALLOCATOR_TEMP_GUARD() path_cstr := strings.clone_to_cstring(path, context.temp_allocator) res := _unix_remove(path_cstr) @@ -1005,15 +1012,15 @@ _readlink :: proc(path: string) -> (string, Error) { } } -@(require_results) -absolute_path_from_handle :: proc(fd: Handle) -> (path: string, err: Error) { +@(private, require_results) +_absolute_path_from_handle :: proc(fd: Handle) -> (path: string, err: Error) { buf: [DARWIN_MAXPATHLEN]byte _ = fcntl(int(fd), F_GETPATH, int(uintptr(&buf[0]))) or_return return strings.clone_from_cstring(cstring(&buf[0])) } -@(require_results) -absolute_path_from_relative :: proc(rel: string) -> (path: string, err: Error) { +@(private, require_results) +_absolute_path_from_relative :: proc(rel: string) -> (path: string, err: Error) { rel := rel if rel == "" { rel = "." @@ -1034,18 +1041,40 @@ absolute_path_from_relative :: proc(rel: string) -> (path: string, err: Error) { return path, nil } -access :: proc(path: string, mask: int) -> bool { +@(private) +_access :: proc(path: string, mask: int) -> (bool, Error) { runtime.DEFAULT_TEMP_ALLOCATOR_TEMP_GUARD() cstr := strings.clone_to_cstring(path, context.temp_allocator) - return _unix_access(cstr, c.int(mask)) == 0 + res := _unix_access(cstr, c.int(mask)) + if res == 0 { + return true, nil + } + return false, get_last_error() +} + +_link :: proc(old_name, new_name: string) -> (err: Error) { + unimplemented("TODO: _link") +} +_unlink :: proc(path: string) -> (err: Error) { + unimplemented("TODO: _unlink") +} +_ftruncate :: proc(fd: Handle, length: i64) -> (err: Error) { + unimplemented("TODO: _ftruncate") +} + +_truncate :: proc(path: string, length: i64) -> (err: Error) { + unimplemented("TODO: _truncate") } -flush :: proc(fd: Handle) -> Error { + + +@(private) +_flush :: proc(fd: Handle) -> Error { return cast(Platform_Error)_unix_fsync(fd) } -@(require_results) -lookup_env :: proc(key: string, allocator := context.allocator) -> (value: string, found: bool) { +@(private, require_results) +_lookup_env :: proc(key: string, allocator := context.allocator) -> (value: string, found: bool) { runtime.DEFAULT_TEMP_ALLOCATOR_TEMP_GUARD(ignore = context.temp_allocator == allocator) path_str := strings.clone_to_cstring(key, context.temp_allocator) cstr := _unix_getenv(path_str) @@ -1055,13 +1084,14 @@ lookup_env :: proc(key: string, allocator := context.allocator) -> (value: strin return strings.clone(string(cstr), allocator), true } -@(require_results) -get_env :: proc(key: string, allocator := context.allocator) -> (value: string) { +@(private, require_results) +_get_env :: proc(key: string, allocator := context.allocator) -> (value: string) { value, _ = lookup_env(key, allocator) return } -set_env :: proc(key, value: string) -> Error { +@(private) +_set_env :: proc(key, value: string) -> Error { runtime.DEFAULT_TEMP_ALLOCATOR_TEMP_GUARD() key_cstring := strings.clone_to_cstring(key, context.temp_allocator) value_cstring := strings.clone_to_cstring(value, context.temp_allocator) @@ -1072,7 +1102,8 @@ set_env :: proc(key, value: string) -> Error { return nil } -unset_env :: proc(key: string) -> Error { +@(private) +_unset_env :: proc(key: string) -> Error { runtime.DEFAULT_TEMP_ALLOCATOR_TEMP_GUARD() s := strings.clone_to_cstring(key, context.temp_allocator) res := _unix_unsetenv(s) @@ -1083,7 +1114,15 @@ unset_env :: proc(key: string) -> Error { } @(require_results) -get_current_directory :: proc() -> string { +_environ :: proc(allocator := context.allocator) -> []string { + return nil +} +_clear_env :: proc() { +} + + +@(private, require_results) +_get_current_directory :: proc() -> string { page_size := get_page_size() // NOTE(tetra): See note in os_linux.odin/get_current_directory. buf := make([dynamic]u8, page_size) for { @@ -1100,7 +1139,8 @@ get_current_directory :: proc() -> string { unreachable() } -set_current_directory :: proc(path: string) -> (err: Error) { +@(private) +_set_current_directory :: proc(path: string) -> (err: Error) { runtime.DEFAULT_TEMP_ALLOCATOR_TEMP_GUARD() cstr := strings.clone_to_cstring(path, context.temp_allocator) res := _unix_chdir(cstr) @@ -1110,23 +1150,29 @@ set_current_directory :: proc(path: string) -> (err: Error) { return nil } -make_directory :: proc(path: string, mode: u16 = 0o775) -> Error { +@(private) +_make_directory :: proc(path: string, mode: u32 = 0o775) -> Error { runtime.DEFAULT_TEMP_ALLOCATOR_TEMP_GUARD() path_cstr := strings.clone_to_cstring(path, context.temp_allocator) - res := _unix_mkdir(path_cstr, mode) + res := _unix_mkdir(path_cstr, u16(mode)) if res == -1 { return get_last_error() } return nil } -exit :: proc "contextless" (code: int) -> ! { +_remove_directory :: proc(path: string) -> Error { + unimplemented("TODO: _remove_directory") +} + +@(private) +_exit :: proc "contextless" (code: int) -> ! { runtime._cleanup_runtime_contextless() _unix_exit(i32(code)) } -@(require_results) -current_thread_id :: proc "contextless" () -> int { +@(private, require_results) +_current_thread_id :: proc "contextless" () -> int { tid: u64 // NOTE(Oskar): available from OSX 10.6 and iOS 3.2. // For older versions there is `syscall(SYS_thread_selfid)`, but not really @@ -1160,7 +1206,13 @@ dlerror :: proc() -> string { } @(require_results) -get_page_size :: proc() -> int { +_pipe :: proc() -> (r, w: Handle, err: Error) { + // TODO + return +} + +@(require_results) +_get_page_size :: proc() -> int { // NOTE(tetra): The page size never changes, so why do anything complicated // if we don't have to. @static page_size := -1 diff --git a/core/os/os_essence.odin b/core/os/os_essence.odin index 75c4c1156f7..7c99d4d9351 100644 --- a/core/os/os_essence.odin +++ b/core/os/os_essence.odin @@ -30,31 +30,31 @@ heap_resize :: proc(ptr: rawptr, new_size: int) -> rawptr { return es.HeapReallocate(ptr, new_size, false) } -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) { return (Handle) (0), (Error) (1) } -close :: proc(fd: Handle) -> Error { +_close :: proc(fd: Handle) -> Error { return (Error) (1) } -file_size :: proc(fd: Handle) -> (i64, Error) { +_file_size :: proc(fd: Handle) -> (i64, Error) { return (i64) (0), (Error) (1) } -read :: proc(fd: Handle, data: []byte) -> (int, Error) { +_read :: proc(fd: Handle, data: []byte) -> (int, Error) { return (int) (0), (Error) (1) } -write :: proc(fd: Handle, data: []u8) -> (int, Error) { +_write :: proc(fd: Handle, data: []u8) -> (int, Error) { return (int) (0), (Error) (1) } -seek :: proc(fd: Handle, offset: i64, whence: int) -> (i64, Error) { +_seek :: proc(fd: Handle, offset: i64, whence: int) -> (i64, Error) { return (i64) (0), (Error) (1) } -flush :: proc(fd: Handle) -> Error { +_flush :: proc(fd: Handle) -> Error { // do nothing return nil } \ No newline at end of file diff --git a/core/os/os_freebsd.odin b/core/os/os_freebsd.odin index c7955368eb4..d74a9df84ce 100644 --- a/core/os/os_freebsd.odin +++ b/core/os/os_freebsd.odin @@ -416,17 +416,17 @@ foreign dl { } @(require_results) -is_path_separator :: proc(r: rune) -> bool { +_is_path_separator :: proc "contextless" (r: rune) -> bool { return r == '/' } @(require_results, no_instrumentation) -get_last_error :: proc "contextless" () -> Error { +_get_last_error :: proc "contextless" () -> Error { 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() cstr := strings.clone_to_cstring(path, context.temp_allocator) handle := _unix_open(cstr, c.int(flags), c.int(mode)) @@ -436,7 +436,7 @@ open :: proc(path: string, flags: int = O_RDONLY, mode: int = 0) -> (Handle, Err return handle, nil } -close :: proc(fd: Handle) -> Error { +_close :: proc(fd: Handle) -> Error { result := _unix_close(fd) if result == -1 { return get_last_error() @@ -444,7 +444,7 @@ close :: proc(fd: Handle) -> Error { return nil } -flush :: proc(fd: Handle) -> Error { +_flush :: proc(fd: Handle) -> Error { // do nothing return nil } @@ -457,7 +457,7 @@ flush :: proc(fd: Handle) -> Error { @(private) MAX_RW :: 1 << 30 -read :: proc(fd: Handle, data: []byte) -> (int, Error) { +_read :: proc(fd: Handle, data: []byte) -> (int, Error) { to_read := min(c.size_t(len(data)), MAX_RW) bytes_read := _unix_read(fd, &data[0], to_read) if bytes_read == -1 { @@ -466,7 +466,7 @@ read :: proc(fd: Handle, data: []byte) -> (int, Error) { return int(bytes_read), nil } -write :: proc(fd: Handle, data: []byte) -> (int, Error) { +_write :: proc(fd: Handle, data: []byte) -> (int, Error) { if len(data) == 0 { return 0, nil } @@ -479,7 +479,7 @@ write :: proc(fd: Handle, data: []byte) -> (int, Error) { return int(bytes_written), nil } -read_at :: proc(fd: Handle, data: []byte, offset: i64) -> (n: int, err: Error) { +_read_at :: proc(fd: Handle, data: []byte, offset: i64) -> (n: int, err: Error) { curr := seek(fd, offset, SEEK_CUR) or_return n, err = read(fd, data) _, err1 := seek(fd, curr, SEEK_SET) @@ -489,7 +489,7 @@ read_at :: proc(fd: Handle, data: []byte, offset: i64) -> (n: int, err: Error) { return } -write_at :: proc(fd: Handle, data: []byte, offset: i64) -> (n: int, err: Error) { +_write_at :: proc(fd: Handle, data: []byte, offset: i64) -> (n: int, err: Error) { curr := seek(fd, offset, SEEK_CUR) or_return n, err = write(fd, data) _, err1 := seek(fd, curr, SEEK_SET) @@ -499,7 +499,7 @@ write_at :: proc(fd: Handle, data: []byte, offset: i64) -> (n: int, err: Error) return } -seek :: proc(fd: Handle, offset: i64, whence: int) -> (i64, Error) { +_seek :: proc(fd: Handle, offset: i64, whence: int) -> (i64, Error) { res := _unix_seek(fd, offset, c.int(whence)) if res == -1 { return -1, get_last_error() @@ -508,14 +508,24 @@ seek :: proc(fd: Handle, offset: i64, whence: int) -> (i64, Error) { } @(require_results) -file_size :: proc(fd: Handle) -> (size: i64, err: Error) { +_file_size :: proc(fd: Handle) -> (size: i64, err: Error) { size = -1 s := _fstat(fd) or_return size = s.size return } +@(require_results) +_pipe :: proc() -> (r, w: Handle, err: Error) { + // TODO + return +} + +@(require_results) +_exists :: proc(path: string) -> bool { + unimplemented("TODO: _exists") +} -rename :: proc(old_path, new_path: string) -> Error { +_rename :: proc(old_path, new_path: string) -> Error { runtime.DEFAULT_TEMP_ALLOCATOR_TEMP_GUARD() old_path_cstr := strings.clone_to_cstring(old_path, context.temp_allocator) new_path_cstr := strings.clone_to_cstring(new_path, context.temp_allocator) @@ -526,7 +536,7 @@ rename :: proc(old_path, new_path: string) -> Error { return nil } -remove :: proc(path: string) -> Error { +_remove :: proc(path: string) -> Error { runtime.DEFAULT_TEMP_ALLOCATOR_TEMP_GUARD() path_cstr := strings.clone_to_cstring(path, context.temp_allocator) res := _unix_unlink(path_cstr) @@ -536,17 +546,17 @@ remove :: proc(path: string) -> Error { return nil } -make_directory :: proc(path: string, mode: mode_t = 0o775) -> Error { +_make_directory :: proc(path: string, mode: u32 = 0o775) -> Error { runtime.DEFAULT_TEMP_ALLOCATOR_TEMP_GUARD() path_cstr := strings.clone_to_cstring(path, context.temp_allocator) - res := _unix_mkdir(path_cstr, mode) + res := _unix_mkdir(path_cstr, mode_t(mode)) if res == -1 { return get_last_error() } return nil } -remove_directory :: proc(path: string) -> Error { +_remove_directory :: proc(path: string) -> Error { runtime.DEFAULT_TEMP_ALLOCATOR_TEMP_GUARD() path_cstr := strings.clone_to_cstring(path, context.temp_allocator) res := _unix_rmdir(path_cstr) @@ -556,8 +566,23 @@ remove_directory :: proc(path: string) -> Error { return nil } +_link :: proc(old_name, new_name: string) -> (err: Error) { + unimplemented("TODO: _link") +} +_unlink :: proc(path: string) -> (err: Error) { + unimplemented("TODO: _unlink") +} +_ftruncate :: proc(fd: Handle, length: i64) -> (err: Error) { + unimplemented("TODO: _ftruncate") +} + +_truncate :: proc(path: string, length: i64) -> (err: Error) { + unimplemented("TODO: _truncate") +} + + @(require_results) -is_file_handle :: proc(fd: Handle) -> bool { +_is_file_handle :: proc(fd: Handle) -> bool { s, err := _fstat(fd) if err != nil { return false @@ -566,7 +591,7 @@ is_file_handle :: proc(fd: Handle) -> bool { } @(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 err: Error if follow_links { @@ -581,7 +606,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) if err != nil { return false @@ -590,7 +615,7 @@ is_dir_handle :: proc(fd: Handle) -> bool { } @(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 err: Error if follow_links { @@ -604,8 +629,6 @@ is_dir_path :: proc(path: string, follow_links: bool = true) -> bool { return S_ISDIR(s.mode) } -is_file :: proc {is_file_path, is_file_handle} -is_dir :: proc {is_dir_path, is_dir_handle} // NOTE(bill): Uses startup to initialize it @@ -618,7 +641,7 @@ last_write_time :: proc(fd: Handle) -> 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) if err != nil { return 0, err @@ -628,7 +651,7 @@ last_write_time :: proc(fd: Handle) -> (File_Time, Error) { } @(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) if err != nil { return 0, err @@ -740,7 +763,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) { // 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 // regarding the desire to retrieve an absolute path from a handle, but to @@ -763,7 +786,7 @@ absolute_path_from_handle :: proc(fd: Handle) -> (string, Error) { } @(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 if rel == "" { rel = "." @@ -784,7 +807,7 @@ absolute_path_from_relative :: proc(rel: string) -> (path: string, err: Error) { return path, nil } -access :: proc(path: string, mask: int) -> (bool, Error) { +_access :: proc(path: string, mask: int) -> (bool, Error) { runtime.DEFAULT_TEMP_ALLOCATOR_TEMP_GUARD() cstr := strings.clone_to_cstring(path, context.temp_allocator) @@ -796,7 +819,7 @@ access :: proc(path: string, mask: int) -> (bool, Error) { } @(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) path_str := strings.clone_to_cstring(key, context.temp_allocator) @@ -808,13 +831,29 @@ lookup_env :: proc(key: string, allocator := context.allocator) -> (value: strin } @(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) return } +_set_env :: proc(key, value: string) -> Error { + unimplemented("TODO: _set_env") +} +_unset_env :: proc(key: string) -> Error { + unimplemented("TODO: _unset_env") +} + +_clear_env :: proc() { + unimplemented("TODO: _clear_env") +} + +@(require_results) +_environ :: proc(allocator := context.allocator) -> []string { + unimplemented("TODO: _environ") +} + @(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 // an authoritative value for it across all systems. // The largest value I could find was 4096, so might as well use the page size. @@ -834,7 +873,7 @@ get_current_directory :: proc() -> string { unreachable() } -set_current_directory :: proc(path: string) -> (err: Error) { +_set_current_directory :: proc(path: string) -> (err: Error) { runtime.DEFAULT_TEMP_ALLOCATOR_TEMP_GUARD() cstr := strings.clone_to_cstring(path, context.temp_allocator) res := _unix_chdir(cstr) @@ -844,13 +883,13 @@ set_current_directory :: proc(path: string) -> (err: Error) { return nil } -exit :: proc "contextless" (code: int) -> ! { +_exit :: proc "contextless" (code: int) -> ! { runtime._cleanup_runtime_contextless() _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() } @@ -878,7 +917,7 @@ dlerror :: proc() -> string { } @(require_results) -get_page_size :: proc() -> int { +_get_page_size :: proc() -> int { // NOTE(tetra): The page size never changes, so why do anything complicated // if we don't have to. @static page_size := -1 diff --git a/core/os/os_haiku.odin b/core/os/os_haiku.odin index 7f1ec708936..262561f8cc0 100644 --- a/core/os/os_haiku.odin +++ b/core/os/os_haiku.odin @@ -4,6 +4,7 @@ foreign import libc "system:c" import "base:runtime" import "core:c" +import "core:time" import "core:strings" import "core:sys/haiku" @@ -178,17 +179,17 @@ Dirent :: struct { Dir :: distinct rawptr // DIR* @(require_results) -is_path_separator :: proc(r: rune) -> bool { +_is_path_separator :: proc "contextless" (r: rune) -> bool { return r == '/' } @(require_results, no_instrumentation) -get_last_error :: proc "contextless" () -> Error { +_get_last_error :: proc "contextless" () -> Error { return Platform_Error(__error()^) } @(require_results) -fork :: proc() -> (Pid, Error) { +_fork :: proc() -> (Pid, Error) { pid := _unix_fork() if pid == -1 { return Pid(-1), get_last_error() @@ -197,7 +198,7 @@ fork :: proc() -> (Pid, Error) { } @(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() cstr := strings.clone_to_cstring(path, context.temp_allocator) handle := _unix_open(cstr, c.int(flags), c.int(mode)) @@ -207,7 +208,7 @@ open :: proc(path: string, flags: int = O_RDONLY, mode: int = 0) -> (Handle, Err return handle, nil } -close :: proc(fd: Handle) -> Error { +_close :: proc(fd: Handle) -> Error { result := _unix_close(fd) if result == -1 { return get_last_error() @@ -215,7 +216,7 @@ close :: proc(fd: Handle) -> Error { return nil } -flush :: proc(fd: Handle) -> Error { +_flush :: proc(fd: Handle) -> Error { // do nothing return nil } @@ -227,7 +228,7 @@ flush :: proc(fd: Handle) -> Error { @(private) MAX_RW :: 1 << 30 -read :: proc(fd: Handle, data: []byte) -> (int, Error) { +_read :: proc(fd: Handle, data: []byte) -> (int, Error) { to_read := min(c.size_t(len(data)), MAX_RW) bytes_read := _unix_read(fd, &data[0], to_read) if bytes_read == -1 { @@ -236,7 +237,7 @@ read :: proc(fd: Handle, data: []byte) -> (int, Error) { return int(bytes_read), nil } -write :: proc(fd: Handle, data: []byte) -> (int, Error) { +_write :: proc(fd: Handle, data: []byte) -> (int, Error) { if len(data) == 0 { return 0, nil } @@ -249,7 +250,7 @@ write :: proc(fd: Handle, data: []byte) -> (int, Error) { return int(bytes_written), nil } -read_at :: proc(fd: Handle, data: []byte, offset: i64) -> (n: int, err: Error) { +_read_at :: proc(fd: Handle, data: []byte, offset: i64) -> (n: int, err: Error) { curr := seek(fd, offset, SEEK_CUR) or_return n, err = read(fd, data) _, err1 := seek(fd, curr, SEEK_SET) @@ -259,7 +260,7 @@ read_at :: proc(fd: Handle, data: []byte, offset: i64) -> (n: int, err: Error) { return } -write_at :: proc(fd: Handle, data: []byte, offset: i64) -> (n: int, err: Error) { +_write_at :: proc(fd: Handle, data: []byte, offset: i64) -> (n: int, err: Error) { curr := seek(fd, offset, SEEK_CUR) or_return n, err = write(fd, data) _, err1 := seek(fd, curr, SEEK_SET) @@ -269,7 +270,7 @@ write_at :: proc(fd: Handle, data: []byte, offset: i64) -> (n: int, err: Error) return } -seek :: proc(fd: Handle, offset: i64, whence: int) -> (i64, Error) { +_seek :: proc(fd: Handle, offset: i64, whence: int) -> (i64, Error) { res := _unix_seek(fd, offset, c.int(whence)) if res == -1 { return -1, get_last_error() @@ -278,7 +279,7 @@ seek :: proc(fd: Handle, offset: i64, whence: int) -> (i64, Error) { } @(require_results) -file_size :: proc(fd: Handle) -> (i64, Error) { +_file_size :: proc(fd: Handle) -> (i64, Error) { s, err := _fstat(fd) if err != nil { return -1, err @@ -401,12 +402,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) } @(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 if rel == "" { rel = "." @@ -427,7 +428,7 @@ absolute_path_from_relative :: proc(rel: string) -> (path: string, err: Error) { return path, nil } -access :: proc(path: string, mask: int) -> (bool, Error) { +_access :: proc(path: string, mask: int) -> (bool, Error) { runtime.DEFAULT_TEMP_ALLOCATOR_TEMP_GUARD() cstr := strings.clone_to_cstring(path, context.temp_allocator) res := _unix_access(cstr, c.int(mask)) @@ -438,7 +439,7 @@ access :: proc(path: string, mask: int) -> (bool, Error) { } @(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) path_str := strings.clone_to_cstring(key, context.temp_allocator) cstr := _unix_getenv(path_str) @@ -449,11 +450,59 @@ lookup_env :: proc(key: string, allocator := context.allocator) -> (value: strin } @(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) return } +@(require_results) +_environ :: proc(allocator := context.allocator) -> []string { + unimplemented("TODO: _environ") +} + + +_set_env :: proc(key, value: string) -> Error { + unimplemented("TODO: _set_env") +} +_unset_env :: proc(key: string) -> Error { + unimplemented("TODO: _unset_env") +} + +_clear_env :: proc() { + unimplemented("TODO: _clear_env") +} + + +@(require_results) +_get_current_directory :: proc() -> string { + unimplemented("TODO: _get_current_directory") +} + + +_set_current_directory :: proc(path: string) -> (err: Error) { + unimplemented("TODO: _set_current_directory") +} + +_make_directory :: proc(path: string, mode: u32 = 0o775) -> Error { + unimplemented("TODO: _make_directory") +} + +_remove_directory :: proc(path: string) -> Error { + unimplemented("TODO: _remove_directory") +} + +_current_thread_id :: proc "contextless" () -> int { + context = runtime.default_context() + unimplemented("TODO: _current_thread_id") +} + +_get_page_size :: proc() -> int { + unimplemented("TODO: _get_page_size") +} + + + + @(private, require_results) _processor_core_count :: proc() -> int { info: haiku.system_info @@ -461,7 +510,107 @@ _processor_core_count :: proc() -> int { return int(info.cpu_count) } -exit :: proc "contextless" (code: int) -> ! { +_exit :: proc "contextless" (code: int) -> ! { runtime._cleanup_runtime_contextless() _unix_exit(i32(code)) } + + + +@(require_results) +_last_write_time :: proc(fd: Handle) -> (ft: File_Time, err: Error) { + s := fstat(fd) or_return + defer file_info_delete(s) + ft = File_Time(time.time_to_unix(s.modification_time)) // TODO: is this correct? + return +} + +@(require_results) +_last_write_time_by_name :: proc(name: string) -> (ft: File_Time, err: Error) { + s := stat(name) or_return + defer file_info_delete(s) + ft = File_Time(time.time_to_unix(s.modification_time)) // TODO: is this correct? + return +} + + +@(require_results) +_is_file_handle :: proc(fd: Handle) -> bool { + s, err := fstat(fd) + defer file_info_delete(s) + return err != nil && !s.is_dir +} + +@(require_results) +_is_file_path :: proc(path: string, follow_links: bool = true) -> bool { + if follow_links { + s, err := lstat(path) + defer file_info_delete(s) + return err != nil && !s.is_dir + } + s, err := stat(path) + defer file_info_delete(s) + return err != nil && !s.is_dir +} + +@(require_results) +_is_dir_handle :: proc(fd: Handle) -> bool { + s, err := fstat(fd) + defer file_info_delete(s) + return err != nil && s.is_dir +} + +@(require_results) +_is_dir_path :: proc(path: string, follow_links: bool = true) -> bool { + if follow_links { + s, err := lstat(path) + defer file_info_delete(s) + return err != nil && s.is_dir + } + s, err := stat(path) + defer file_info_delete(s) + return err != nil && s.is_dir +} + +@(require_results) +_exists :: proc(path: string) -> bool { + fi, err := stat(path) + file_info_delete(fi) + return err == nil +} + + + +_rename :: proc(old, new: string) -> Error { + unimplemented("TODO: _rename") +} + +_remove :: proc(path: string) -> Error { + unimplemented("TODO: _remove") +} + +_link :: proc(old_name, new_name: string) -> (err: Error) { + unimplemented("TODO: _link") +} +_unlink :: proc(path: string) -> (err: Error) { + unimplemented("TODO: _unlink") +} +_ftruncate :: proc(fd: Handle, length: i64) -> (err: Error) { + unimplemented("TODO: _ftruncate") +} + +_truncate :: proc(path: string, length: i64) -> (err: Error) { + unimplemented("TODO: _truncate") +} + + +@(require_results) +_pipe :: proc() -> (r, w: Handle, err: Error) { + unimplemented("TODO: _pipe") +} + +@(require_results) +_read_dir :: proc(fd: Handle, n: int, allocator := context.allocator) -> (fi: []File_Info, err: Error) { + unimplemented("TODO: _read_dir") +} + diff --git a/core/os/os_js.odin b/core/os/os_js.odin index eb434c7278a..a335cdf2ed7 100644 --- a/core/os/os_js.odin +++ b/core/os/os_js.odin @@ -3,45 +3,51 @@ package os import "base:runtime" + +@(require_results, no_instrumentation) +_get_last_error :: proc "contextless" () -> Error { + return nil +} + @(require_results) -is_path_separator :: proc(c: byte) -> bool { +_is_path_separator :: proc "contextless" (c: rune) -> bool { 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") } -close :: proc(fd: Handle) -> Error { +_close :: proc(fd: Handle) -> Error { unimplemented("core:os procedure not supported on JS target") } -flush :: proc(fd: Handle) -> (err: Error) { +_flush :: proc(fd: Handle) -> (err: Error) { unimplemented("core:os procedure not supported on JS target") } -write :: proc(fd: Handle, data: []byte) -> (int, Error) { +_write :: proc(fd: Handle, data: []byte) -> (int, Error) { unimplemented("core:os procedure not supported on JS target") } @(private="file") -read_console :: proc(handle: Handle, b: []byte) -> (n: int, err: Error) { +_read_console :: proc(handle: Handle, b: []byte) -> (n: int, err: Error) { unimplemented("core:os procedure not supported on JS target") } -read :: proc(fd: Handle, data: []byte) -> (int, Error) { +_read :: proc(fd: Handle, data: []byte) -> (int, Error) { unimplemented("core:os procedure not supported on JS target") } -seek :: proc(fd: Handle, offset: i64, whence: int) -> (i64, Error) { +_seek :: proc(fd: Handle, offset: i64, whence: int) -> (i64, Error) { 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") } @@ -58,10 +64,10 @@ pwrite :: proc(fd: Handle, data: []byte, offset: i64) -> (int, Error) { unimplemented("core:os procedure not supported on JS target") } -read_at :: proc(fd: Handle, data: []byte, offset: i64) -> (n: int, err: Error) { +_read_at :: proc(fd: Handle, data: []byte, offset: i64) -> (n: int, err: Error) { unimplemented("core:os procedure not supported on JS target") } -write_at :: proc(fd: Handle, data: []byte, offset: i64) -> (n: int, err: Error) { +_write_at :: proc(fd: Handle, data: []byte, offset: i64) -> (n: int, err: Error) { unimplemented("core:os procedure not supported on JS target") } @@ -76,17 +82,27 @@ get_std_handle :: proc "contextless" (h: uint) -> Handle { @(require_results) -exists :: proc(path: string) -> bool { +_exists :: proc(path: string) -> bool { unimplemented("core:os procedure not supported on JS target") } @(require_results) -is_file :: proc(path: string) -> bool { +_is_file_path :: proc(path: string, _: bool) -> bool { unimplemented("core:os procedure not supported on JS target") } @(require_results) -is_dir :: proc(path: string) -> bool { +_is_dir_path :: proc(path: string, _: bool) -> bool { + unimplemented("core:os procedure not supported on JS target") +} + +@(require_results) +_is_file_handle :: proc(handle: Handle) -> bool { + unimplemented("core:os procedure not supported on JS target") +} + +@(require_results) +_is_dir_handle :: proc(handle: Handle) -> bool { unimplemented("core:os procedure not supported on JS target") } @@ -94,26 +110,26 @@ is_dir :: proc(path: string) -> bool { //@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") } -set_current_directory :: proc(path: string) -> (err: Error) { +_set_current_directory :: proc(path: string) -> (err: Error) { unimplemented("core:os procedure not supported on JS target") } -change_directory :: proc(path: string) -> (err: Error) { +_change_directory :: proc(path: string) -> (err: Error) { unimplemented("core:os procedure not supported on JS target") } -make_directory :: proc(path: string, mode: u32 = 0) -> (err: Error) { +_make_directory :: proc(path: string, mode: u32 = 0) -> (err: Error) { unimplemented("core:os procedure not supported on JS target") } -remove_directory :: proc(path: string) -> (err: Error) { +_remove_directory :: proc(path: string) -> (err: Error) { unimplemented("core:os procedure not supported on JS target") } @@ -130,42 +146,42 @@ fix_long_path :: proc(path: string) -> string { } -link :: proc(old_name, new_name: string) -> (err: Error) { +_link :: proc(old_name, new_name: string) -> (err: Error) { unimplemented("core:os procedure not supported on JS target") } -unlink :: proc(path: string) -> (err: Error) { +_unlink :: proc(path: string) -> (err: Error) { unimplemented("core:os procedure not supported on JS target") } -rename :: proc(old_path, new_path: string) -> (err: Error) { +_rename :: proc(old_path, new_path: string) -> (err: Error) { unimplemented("core:os procedure not supported on JS target") } -ftruncate :: proc(fd: Handle, length: i64) -> (err: Error) { +_ftruncate :: proc(fd: Handle, length: i64) -> (err: Error) { unimplemented("core:os procedure not supported on JS target") } -truncate :: proc(path: string, length: i64) -> (err: Error) { +_truncate :: proc(path: string, length: i64) -> (err: Error) { unimplemented("core:os procedure not supported on JS target") } -remove :: proc(name: string) -> Error { +_remove :: proc(name: string) -> Error { unimplemented("core:os procedure not supported on JS target") } @(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") } @(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") } @@ -262,19 +278,19 @@ 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") } @(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") } @(require_results) -get_page_size :: proc() -> int { - unimplemented("core:os procedure not supported on JS target") +_get_page_size :: proc() -> int { + return 1<<16 } @(private, require_results) @@ -282,7 +298,7 @@ _processor_core_count :: proc() -> int { unimplemented("core:os procedure not supported on JS target") } -exit :: proc "contextless" (code: int) -> ! { +_exit :: proc "contextless" (code: int) -> ! { context = runtime.default_context() unimplemented("core:os procedure not supported on JS target") } @@ -290,7 +306,7 @@ exit :: proc "contextless" (code: int) -> ! { @(require_results) -current_thread_id :: proc "contextless" () -> int { +_current_thread_id :: proc "contextless" () -> int { context = runtime.default_context() unimplemented("core:os procedure not supported on JS target") } @@ -302,3 +318,41 @@ _alloc_command_line_arguments :: proc() -> []string { return nil } +@(require_results) +_absolute_path_from_handle :: proc(fd: Handle) -> (path: string, err: Error) { + unimplemented("TODO: _absolute_path_from_handle") +} +@(require_results) +_absolute_path_from_relative :: proc(rel: string) -> (path: string, err: Error) { + unimplemented("TODO: _absolute_path_from_relative") +} + +_access :: proc(path: string, mask: int) -> (bool, Error) { + unimplemented("TODO: _access") +} + + +@(require_results) +_environ :: proc(allocator := context.allocator) -> []string { + unimplemented("TODO: _environ") +} +@(require_results) +_lookup_env :: proc(key: string, allocator := context.allocator) -> (value: string, found: bool) { + unimplemented("TODO: _lookup_env") +} + +@(require_results) +_get_env :: proc(key: string, allocator := context.allocator) -> (value: string) { + unimplemented("TODO: _get_env") +} + +_set_env :: proc(key, value: string) -> Error { + unimplemented("TODO: _set_env") +} +_unset_env :: proc(key: string) -> Error { + unimplemented("TODO: _unset_env") +} + +_clear_env :: proc() { + unimplemented("TODO: _clear_env") +} diff --git a/core/os/os_linux.odin b/core/os/os_linux.odin index 1e110d18f24..7b6c89b9c77 100644 --- a/core/os/os_linux.odin +++ b/core/os/os_linux.odin @@ -507,7 +507,7 @@ foreign dl { } @(require_results) -is_path_separator :: proc(r: rune) -> bool { +_is_path_separator :: proc "contextless" (r: rune) -> bool { return r == '/' } @@ -522,7 +522,7 @@ _get_errno :: proc(res: int) -> Error { // get errno from libc @(require_results, no_instrumentation) -get_last_error :: proc "contextless" () -> Error { +_get_last_error :: proc "contextless" () -> Error { err := Platform_Error(__errno_location()^) #partial switch err { case .NONE: @@ -570,7 +570,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() cstr := strings.clone_to_cstring(path, context.temp_allocator) handle := unix.sys_open(cstr, flags, uint(mode)) @@ -580,11 +580,11 @@ open :: proc(path: string, flags: int = O_RDONLY, mode: int = 0o000) -> (Handle, return Handle(handle), nil } -close :: proc(fd: Handle) -> Error { +_close :: proc(fd: Handle) -> Error { return _get_errno(unix.sys_close(int(fd))) } -flush :: proc(fd: Handle) -> Error { +_flush :: proc(fd: Handle) -> Error { // do nothing return nil } @@ -598,7 +598,7 @@ flush :: proc(fd: Handle) -> Error { @(private) MAX_RW :: 1 << 30 -read :: proc(fd: Handle, data: []byte) -> (int, Error) { +_read :: proc(fd: Handle, data: []byte) -> (int, Error) { if len(data) == 0 { return 0, nil } @@ -612,7 +612,7 @@ read :: proc(fd: Handle, data: []byte) -> (int, Error) { return bytes_read, nil } -write :: proc(fd: Handle, data: []byte) -> (int, Error) { +_write :: proc(fd: Handle, data: []byte) -> (int, Error) { if len(data) == 0 { return 0, nil } @@ -626,7 +626,7 @@ write :: proc(fd: Handle, data: []byte) -> (int, Error) { return bytes_written, nil } -read_at :: proc(fd: Handle, data: []byte, offset: i64) -> (int, Error) { +_read_at :: proc(fd: Handle, data: []byte, offset: i64) -> (int, Error) { if len(data) == 0 { return 0, nil } @@ -640,7 +640,7 @@ read_at :: proc(fd: Handle, data: []byte, offset: i64) -> (int, Error) { return bytes_read, nil } -write_at :: proc(fd: Handle, data: []byte, offset: i64) -> (int, Error) { +_write_at :: proc(fd: Handle, data: []byte, offset: i64) -> (int, Error) { if len(data) == 0 { return 0, nil } @@ -654,7 +654,7 @@ write_at :: proc(fd: Handle, data: []byte, offset: i64) -> (int, Error) { return bytes_written, nil } -seek :: proc(fd: Handle, offset: i64, whence: int) -> (i64, Error) { +_seek :: proc(fd: Handle, offset: i64, whence: int) -> (i64, Error) { res := unix.sys_lseek(int(fd), offset, whence) if res < 0 { return -1, _get_errno(int(res)) @@ -663,7 +663,7 @@ seek :: proc(fd: Handle, offset: i64, whence: int) -> (i64, Error) { } @(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 s: OS_Stat = --- result := unix.sys_fstat(int(fd), rawptr(&s)) @@ -673,33 +673,53 @@ file_size :: proc(fd: Handle) -> (i64, Error) { return max(s.size, 0), nil } -rename :: proc(old_path, new_path: string) -> Error { +_rename :: proc(old_path, new_path: string) -> Error { runtime.DEFAULT_TEMP_ALLOCATOR_TEMP_GUARD() old_path_cstr := strings.clone_to_cstring(old_path, context.temp_allocator) new_path_cstr := strings.clone_to_cstring(new_path, context.temp_allocator) return _get_errno(unix.sys_rename(old_path_cstr, new_path_cstr)) } -remove :: proc(path: string) -> Error { +_remove :: proc(path: string) -> Error { runtime.DEFAULT_TEMP_ALLOCATOR_TEMP_GUARD() path_cstr := strings.clone_to_cstring(path, context.temp_allocator) return _get_errno(unix.sys_unlink(path_cstr)) } -make_directory :: proc(path: string, mode: u32 = 0o775) -> Error { +_make_directory :: proc(path: string, mode: u32 = 0o775) -> Error { runtime.DEFAULT_TEMP_ALLOCATOR_TEMP_GUARD() path_cstr := strings.clone_to_cstring(path, context.temp_allocator) return _get_errno(unix.sys_mkdir(path_cstr, uint(mode))) } -remove_directory :: proc(path: string) -> Error { +_remove_directory :: proc(path: string) -> Error { runtime.DEFAULT_TEMP_ALLOCATOR_TEMP_GUARD() path_cstr := strings.clone_to_cstring(path, context.temp_allocator) return _get_errno(unix.sys_rmdir(path_cstr)) } +_link :: proc(old_name, new_name: string) -> (err: Error) { + unimplemented("TODO: _link") +} +_unlink :: proc(path: string) -> (err: Error) { + unimplemented("TODO: _unlink") +} +_ftruncate :: proc(fd: Handle, length: i64) -> (err: Error) { + unimplemented("TODO: _ftruncate") +} + +_truncate :: proc(path: string, length: i64) -> (err: Error) { + unimplemented("TODO: _truncate") +} + +@(require_results) +_pipe :: proc() -> (r, w: Handle, err: Error) { + // TODO + return +} + @(require_results) -is_file_handle :: proc(fd: Handle) -> bool { +_is_file_handle :: proc(fd: Handle) -> bool { s, err := _fstat(fd) if err != nil { return false @@ -708,7 +728,7 @@ is_file_handle :: proc(fd: Handle) -> bool { } @(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 err: Error if follow_links { @@ -724,7 +744,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) if err != nil { return false @@ -733,7 +753,7 @@ is_dir_handle :: proc(fd: Handle) -> bool { } @(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 err: Error if follow_links { @@ -747,11 +767,9 @@ is_dir_path :: proc(path: string, follow_links: bool = true) -> bool { return S_ISDIR(s.mode) } -is_file :: proc {is_file_path, is_file_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() cpath := strings.clone_to_cstring(path, context.temp_allocator) res := unix.sys_access(cpath, O_RDONLY) @@ -769,14 +787,14 @@ last_write_time :: proc(fd: Handle) -> 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 modified := s.modified.seconds * 1_000_000_000 + s.modified.nanoseconds 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 modified := s.modified.seconds * 1_000_000_000 + s.modified.nanoseconds return File_Time(modified), nil @@ -888,7 +906,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 fd_str := strconv.itoa( buf[:], cast(int)fd ) @@ -899,7 +917,7 @@ absolute_path_from_handle :: proc(fd: Handle) -> (string, Error) { } @(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 if rel == "" { rel = "." @@ -919,7 +937,7 @@ absolute_path_from_relative :: proc(rel: string) -> (path: string, err: Error) { return path, nil } -access :: proc(path: string, mask: int) -> (bool, Error) { +_access :: proc(path: string, mask: int) -> (bool, Error) { runtime.DEFAULT_TEMP_ALLOCATOR_TEMP_GUARD() cstr := strings.clone_to_cstring(path, context.temp_allocator) result := unix.sys_access(cstr, mask) @@ -930,7 +948,7 @@ access :: proc(path: string, mask: int) -> (bool, Error) { } @(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) path_str := strings.clone_to_cstring(key, context.temp_allocator) // NOTE(tetra): Lifetime of 'cstr' is unclear, but _unix_free(cstr) segfaults. @@ -942,12 +960,12 @@ lookup_env :: proc(key: string, allocator := context.allocator) -> (value: strin } @(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) return } -set_env :: proc(key, value: string) -> Error { +_set_env :: proc(key, value: string) -> Error { runtime.DEFAULT_TEMP_ALLOCATOR_TEMP_GUARD() key_cstring := strings.clone_to_cstring(key, context.temp_allocator) value_cstring := strings.clone_to_cstring(value, context.temp_allocator) @@ -959,7 +977,7 @@ set_env :: proc(key, value: string) -> Error { return nil } -unset_env :: proc(key: string) -> Error { +_unset_env :: proc(key: string) -> Error { runtime.DEFAULT_TEMP_ALLOCATOR_TEMP_GUARD() s := strings.clone_to_cstring(key, context.temp_allocator) res := _unix_putenv(s) @@ -968,9 +986,17 @@ unset_env :: proc(key: string) -> Error { } return nil } +@(require_results) +_environ :: proc(allocator := context.allocator) -> []string { + return nil +} +_clear_env :: proc() { +} + + @(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 // an authoritative value for it across all systems. // The largest value I could find was 4096, so might as well use the page size. @@ -991,7 +1017,7 @@ get_current_directory :: proc() -> string { unreachable() } -set_current_directory :: proc(path: string) -> (err: Error) { +_set_current_directory :: proc(path: string) -> (err: Error) { runtime.DEFAULT_TEMP_ALLOCATOR_TEMP_GUARD() cstr := strings.clone_to_cstring(path, context.temp_allocator) res := unix.sys_chdir(cstr) @@ -1001,13 +1027,13 @@ set_current_directory :: proc(path: string) -> (err: Error) { return nil } -exit :: proc "contextless" (code: int) -> ! { +_exit :: proc "contextless" (code: int) -> ! { runtime._cleanup_runtime_contextless() _unix_exit(c.int(code)) } @(require_results) -current_thread_id :: proc "contextless" () -> int { +_current_thread_id :: proc "contextless" () -> int { return unix.sys_gettid() } @@ -1035,7 +1061,7 @@ dlerror :: proc() -> string { } @(require_results) -get_page_size :: proc() -> int { +_get_page_size :: proc() -> int { // NOTE(tetra): The page size never changes, so why do anything complicated // if we don't have to. @static page_size := -1 diff --git a/core/os/os_netbsd.odin b/core/os/os_netbsd.odin index c41dc6aa663..3081b9943b7 100644 --- a/core/os/os_netbsd.odin +++ b/core/os/os_netbsd.odin @@ -474,17 +474,17 @@ foreign libc { // NOTE(phix): Perhaps share the following functions with FreeBSD if they turn out to be the same in the end. @(require_results) -is_path_separator :: proc(r: rune) -> bool { +_is_path_separator :: proc "contextless" (r: rune) -> bool { return r == '/' } @(require_results, no_instrumentation) -get_last_error :: proc "contextless" () -> Error { +_get_last_error :: proc "contextless" () -> Error { return Platform_Error(__errno_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() cstr := strings.clone_to_cstring(path, context.temp_allocator) handle := _unix_open(cstr, c.int(flags), c.int(mode)) @@ -494,7 +494,7 @@ open :: proc(path: string, flags: int = O_RDONLY, mode: int = 0) -> (Handle, Err return handle, nil } -close :: proc(fd: Handle) -> Error { +_close :: proc(fd: Handle) -> Error { result := _unix_close(fd) if result == -1 { return get_last_error() @@ -502,7 +502,7 @@ close :: proc(fd: Handle) -> Error { return nil } -flush :: proc(fd: Handle) -> Error { +_flush :: proc(fd: Handle) -> Error { // do nothing return nil } @@ -511,7 +511,7 @@ flush :: proc(fd: Handle) -> Error { @(private) MAX_RW :: 1 << 30 -read :: proc(fd: Handle, data: []byte) -> (int, Error) { +_read :: proc(fd: Handle, data: []byte) -> (int, Error) { to_read := min(c.size_t(len(data)), MAX_RW) bytes_read := _unix_read(fd, &data[0], to_read) if bytes_read == -1 { @@ -520,7 +520,7 @@ read :: proc(fd: Handle, data: []byte) -> (int, Error) { return int(bytes_read), nil } -write :: proc(fd: Handle, data: []byte) -> (int, Error) { +_write :: proc(fd: Handle, data: []byte) -> (int, Error) { if len(data) == 0 { return 0, nil } @@ -533,7 +533,7 @@ write :: proc(fd: Handle, data: []byte) -> (int, Error) { return int(bytes_written), nil } -read_at :: proc(fd: Handle, data: []byte, offset: i64) -> (n: int, err: Error) { +_read_at :: proc(fd: Handle, data: []byte, offset: i64) -> (n: int, err: Error) { curr := seek(fd, offset, SEEK_CUR) or_return n, err = read(fd, data) _, err1 := seek(fd, curr, SEEK_SET) @@ -543,7 +543,7 @@ read_at :: proc(fd: Handle, data: []byte, offset: i64) -> (n: int, err: Error) { return } -write_at :: proc(fd: Handle, data: []byte, offset: i64) -> (n: int, err: Error) { +_write_at :: proc(fd: Handle, data: []byte, offset: i64) -> (n: int, err: Error) { curr := seek(fd, offset, SEEK_CUR) or_return n, err = write(fd, data) _, err1 := seek(fd, curr, SEEK_SET) @@ -553,7 +553,7 @@ write_at :: proc(fd: Handle, data: []byte, offset: i64) -> (n: int, err: Error) return } -seek :: proc(fd: Handle, offset: i64, whence: int) -> (i64, Error) { +_seek :: proc(fd: Handle, offset: i64, whence: int) -> (i64, Error) { res := _unix_seek(fd, offset, c.int(whence)) if res == -1 { return -1, get_last_error() @@ -562,14 +562,14 @@ seek :: proc(fd: Handle, offset: i64, whence: int) -> (i64, Error) { } @(require_results) -file_size :: proc(fd: Handle) -> (size: i64, err: Error) { +_file_size :: proc(fd: Handle) -> (size: i64, err: Error) { size = -1 s := _fstat(fd) or_return size = s.size return } -rename :: proc(old_path, new_path: string) -> Error { +_rename :: proc(old_path, new_path: string) -> Error { runtime.DEFAULT_TEMP_ALLOCATOR_TEMP_GUARD() old_path_cstr := strings.clone_to_cstring(old_path, context.temp_allocator) new_path_cstr := strings.clone_to_cstring(new_path, context.temp_allocator) @@ -580,7 +580,7 @@ rename :: proc(old_path, new_path: string) -> Error { return nil } -remove :: proc(path: string) -> Error { +_remove :: proc(path: string) -> Error { runtime.DEFAULT_TEMP_ALLOCATOR_TEMP_GUARD() path_cstr := strings.clone_to_cstring(path, context.temp_allocator) res := _unix_unlink(path_cstr) @@ -590,17 +590,32 @@ remove :: proc(path: string) -> Error { return nil } -make_directory :: proc(path: string, mode: mode_t = 0o775) -> Error { +_link :: proc(old_name, new_name: string) -> (err: Error) { + unimplemented("TODO: _link") +} +_unlink :: proc(path: string) -> (err: Error) { + unimplemented("TODO: _unlink") +} +_ftruncate :: proc(fd: Handle, length: i64) -> (err: Error) { + unimplemented("TODO: _ftruncate") +} + +_truncate :: proc(path: string, length: i64) -> (err: Error) { + unimplemented("TODO: _truncate") +} + + +_make_directory :: proc(path: string, mode: u32 = 0o775) -> Error { runtime.DEFAULT_TEMP_ALLOCATOR_TEMP_GUARD() path_cstr := strings.clone_to_cstring(path, context.temp_allocator) - res := _unix_mkdir(path_cstr, mode) + res := _unix_mkdir(path_cstr, mode_t(mode)) if res == -1 { return get_last_error() } return nil } -remove_directory :: proc(path: string) -> Error { +_remove_directory :: proc(path: string) -> Error { runtime.DEFAULT_TEMP_ALLOCATOR_TEMP_GUARD() path_cstr := strings.clone_to_cstring(path, context.temp_allocator) res := _unix_rmdir(path_cstr) @@ -611,7 +626,7 @@ remove_directory :: proc(path: string) -> Error { } @(require_results) -is_file_handle :: proc(fd: Handle) -> bool { +_is_file_handle :: proc(fd: Handle) -> bool { s, err := _fstat(fd) if err != nil { return false @@ -620,7 +635,7 @@ is_file_handle :: proc(fd: Handle) -> bool { } @(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 err: Error if follow_links { @@ -635,7 +650,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) if err != nil { return false @@ -644,7 +659,7 @@ is_dir_handle :: proc(fd: Handle) -> bool { } @(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 err: Error if follow_links { @@ -658,11 +673,14 @@ is_dir_path :: proc(path: string, follow_links: bool = true) -> bool { return S_ISDIR(s.mode) } -is_file :: proc {is_file_path, is_file_handle} -is_dir :: proc {is_dir_path, is_dir_handle} +@(require_results) +_pipe :: proc() -> (r, w: Handle, err: Error) { + // TODO + return +} @(require_results) -exists :: proc(path: string) -> bool { +_exists :: proc(path: string) -> bool { runtime.DEFAULT_TEMP_ALLOCATOR_TEMP_GUARD() cpath := strings.clone_to_cstring(path, context.temp_allocator) res := _unix_access(cpath, O_RDONLY) @@ -685,14 +703,14 @@ stdout: Handle = 1 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 modified := s.modified.seconds * 1_000_000_000 + s.modified.nanoseconds 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 modified := s.modified.seconds * 1_000_000_000 + s.modified.nanoseconds return File_Time(modified), nil @@ -802,14 +820,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: [MAX_PATH]byte _ = fcntl(int(fd), F_GETPATH, int(uintptr(&buf[0]))) or_return 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 if rel == "" { rel = "." @@ -829,7 +847,7 @@ absolute_path_from_relative :: proc(rel: string) -> (path: string, err: Error) { return path, nil } -access :: proc(path: string, mask: int) -> (bool, Error) { +_access :: proc(path: string, mask: int) -> (bool, Error) { runtime.DEFAULT_TEMP_ALLOCATOR_TEMP_GUARD() cstr := strings.clone_to_cstring(path, context.temp_allocator) @@ -841,7 +859,7 @@ access :: proc(path: string, mask: int) -> (bool, Error) { } @(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) path_str := strings.clone_to_cstring(key, context.temp_allocator) @@ -853,13 +871,32 @@ lookup_env :: proc(key: string, allocator := context.allocator) -> (value: strin } @(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) return } @(require_results) -get_current_directory :: proc() -> string { +_environ :: proc(allocator := context.allocator) -> []string { + unimplemented("TODO: _environ") +} + +_set_env :: proc(key, value: string) -> Error { + unimplemented("TODO: _set_env") +} +_unset_env :: proc(key: string) -> Error { + unimplemented("TODO: _unset_env") +} + +_clear_env :: proc() { + unimplemented("TODO: _clear_env") +} + + + + +@(require_results) +_get_current_directory :: proc() -> string { // NOTE(tetra): I would use PATH_MAX here, but I was not able to find // an authoritative value for it across all systems. // The largest value I could find was 4096, so might as well use the page size. @@ -879,7 +916,7 @@ get_current_directory :: proc() -> string { unreachable() } -set_current_directory :: proc(path: string) -> (err: Error) { +_set_current_directory :: proc(path: string) -> (err: Error) { runtime.DEFAULT_TEMP_ALLOCATOR_TEMP_GUARD() cstr := strings.clone_to_cstring(path, context.temp_allocator) res := _unix_chdir(cstr) @@ -889,13 +926,13 @@ set_current_directory :: proc(path: string) -> (err: Error) { return nil } -exit :: proc "contextless" (code: int) -> ! { +_exit :: proc "contextless" (code: int) -> ! { runtime._cleanup_runtime_contextless() _unix_exit(c.int(code)) } @(require_results) -current_thread_id :: proc "contextless" () -> int { +_current_thread_id :: proc "contextless" () -> int { return int(_lwp_self()) } @@ -927,7 +964,7 @@ dlerror :: proc() -> string { } @(require_results) -get_page_size :: proc() -> int { +_get_page_size :: proc() -> int { // NOTE(tetra): The page size never changes, so why do anything complicated // if we don't have to. @static page_size := -1 diff --git a/core/os/os_openbsd.odin b/core/os/os_openbsd.odin index 1cd26211ef1..5d1343739a5 100644 --- a/core/os/os_openbsd.odin +++ b/core/os/os_openbsd.odin @@ -389,12 +389,12 @@ foreign libc { } @(require_results) -is_path_separator :: proc(r: rune) -> bool { +_is_path_separator :: proc "contextless" (r: rune) -> bool { return r == '/' } @(require_results, no_instrumentation) -get_last_error :: proc "contextless" () -> Error { +_get_last_error :: proc "contextless" () -> Error { return Platform_Error(__error()^) } @@ -408,7 +408,7 @@ fork :: proc() -> (Pid, Error) { } @(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() cstr := strings.clone_to_cstring(path, context.temp_allocator) handle := _unix_open(cstr, c.int(flags), c.int(mode)) @@ -418,7 +418,7 @@ open :: proc(path: string, flags: int = O_RDONLY, mode: int = 0) -> (Handle, Err return handle, nil } -close :: proc(fd: Handle) -> Error { +_close :: proc(fd: Handle) -> Error { result := _unix_close(fd) if result == -1 { return get_last_error() @@ -426,7 +426,7 @@ close :: proc(fd: Handle) -> Error { return nil } -flush :: proc(fd: Handle) -> Error { +_flush :: proc(fd: Handle) -> Error { // do nothing return nil } @@ -439,7 +439,7 @@ flush :: proc(fd: Handle) -> Error { @(private) MAX_RW :: 1 << 30 -read :: proc(fd: Handle, data: []byte) -> (int, Error) { +_read :: proc(fd: Handle, data: []byte) -> (int, Error) { to_read := min(c.size_t(len(data)), MAX_RW) bytes_read := _unix_read(fd, &data[0], to_read) if bytes_read == -1 { @@ -448,7 +448,7 @@ read :: proc(fd: Handle, data: []byte) -> (int, Error) { return int(bytes_read), nil } -write :: proc(fd: Handle, data: []byte) -> (int, Error) { +_write :: proc(fd: Handle, data: []byte) -> (int, Error) { if len(data) == 0 { return 0, nil } @@ -461,7 +461,7 @@ write :: proc(fd: Handle, data: []byte) -> (int, Error) { return int(bytes_written), nil } -read_at :: proc(fd: Handle, data: []byte, offset: i64) -> (n: int, err: Error) { +_read_at :: proc(fd: Handle, data: []byte, offset: i64) -> (n: int, err: Error) { curr := seek(fd, offset, SEEK_CUR) or_return n, err = read(fd, data) _, err1 := seek(fd, curr, SEEK_SET) @@ -471,7 +471,7 @@ read_at :: proc(fd: Handle, data: []byte, offset: i64) -> (n: int, err: Error) { return } -write_at :: proc(fd: Handle, data: []byte, offset: i64) -> (n: int, err: Error) { +_write_at :: proc(fd: Handle, data: []byte, offset: i64) -> (n: int, err: Error) { curr := seek(fd, offset, SEEK_CUR) or_return n, err = write(fd, data) _, err1 := seek(fd, curr, SEEK_SET) @@ -481,7 +481,7 @@ write_at :: proc(fd: Handle, data: []byte, offset: i64) -> (n: int, err: Error) return } -seek :: proc(fd: Handle, offset: i64, whence: int) -> (i64, Error) { +_seek :: proc(fd: Handle, offset: i64, whence: int) -> (i64, Error) { res := _unix_seek(fd, offset, c.int(whence)) if res == -1 { return -1, get_last_error() @@ -490,14 +490,18 @@ seek :: proc(fd: Handle, offset: i64, whence: int) -> (i64, Error) { } @(require_results) -file_size :: proc(fd: Handle) -> (size: i64, err: Error) { +_file_size :: proc(fd: Handle) -> (size: i64, err: Error) { size = -1 s := _fstat(fd) or_return size = s.size return } -rename :: proc(old_path, new_path: string) -> Error { +_exists :: proc(path: string) -> bool { + unimplemented("TODO: _exists") +} + +_rename :: proc(old_path, new_path: string) -> Error { runtime.DEFAULT_TEMP_ALLOCATOR_TEMP_GUARD() old_path_cstr := strings.clone_to_cstring(old_path, context.temp_allocator) new_path_cstr := strings.clone_to_cstring(new_path, context.temp_allocator) @@ -508,7 +512,7 @@ rename :: proc(old_path, new_path: string) -> Error { return nil } -remove :: proc(path: string) -> Error { +_remove :: proc(path: string) -> Error { runtime.DEFAULT_TEMP_ALLOCATOR_TEMP_GUARD() path_cstr := strings.clone_to_cstring(path, context.temp_allocator) res := _unix_unlink(path_cstr) @@ -518,7 +522,7 @@ remove :: proc(path: string) -> Error { return nil } -make_directory :: proc(path: string, mode: mode_t = 0o775) -> Error { +_make_directory :: proc(path: string, mode: mode_t = 0o775) -> Error { runtime.DEFAULT_TEMP_ALLOCATOR_TEMP_GUARD() path_cstr := strings.clone_to_cstring(path, context.temp_allocator) res := _unix_mkdir(path_cstr, mode) @@ -528,7 +532,7 @@ make_directory :: proc(path: string, mode: mode_t = 0o775) -> Error { return nil } -remove_directory :: proc(path: string) -> Error { +_remove_directory :: proc(path: string) -> Error { runtime.DEFAULT_TEMP_ALLOCATOR_TEMP_GUARD() path_cstr := strings.clone_to_cstring(path, context.temp_allocator) res := _unix_rmdir(path_cstr) @@ -539,7 +543,28 @@ remove_directory :: proc(path: string) -> Error { } @(require_results) -is_file_handle :: proc(fd: Handle) -> bool { +_pipe :: proc() -> (r, w: Handle, err: Error) { + // TODO + return +} + +_link :: proc(old_name, new_name: string) -> (err: Error) { + unimplemented("TODO: _link") +} +_unlink :: proc(path: string) -> (err: Error) { + unimplemented("TODO: _unlink") +} +_ftruncate :: proc(fd: Handle, length: i64) -> (err: Error) { + unimplemented("TODO: _ftruncate") +} + +_truncate :: proc(path: string, length: i64) -> (err: Error) { + unimplemented("TODO: _truncate") +} + + +@(require_results) +_is_file_handle :: proc(fd: Handle) -> bool { s, err := _fstat(fd) if err != nil { return false @@ -548,7 +573,7 @@ is_file_handle :: proc(fd: Handle) -> bool { } @(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 err: Error if follow_links { @@ -563,7 +588,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) if err != nil { return false @@ -572,7 +597,7 @@ is_dir_handle :: proc(fd: Handle) -> bool { } @(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 err: Error if follow_links { @@ -586,9 +611,6 @@ is_dir_path :: proc(path: string, follow_links: bool = true) -> bool { return S_ISDIR(s.mode) } -is_file :: proc {is_file_path, is_file_handle} -is_dir :: proc {is_dir_path, is_dir_handle} - // NOTE(bill): Uses startup to initialize it stdin: Handle = 0 @@ -600,14 +622,14 @@ last_write_time :: proc(fd: Handle) -> 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 modified := s.modified.seconds * 1_000_000_000 + s.modified.nanoseconds 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 modified := s.modified.seconds * 1_000_000_000 + s.modified.nanoseconds return File_Time(modified), nil @@ -718,12 +740,12 @@ _readlink :: proc(path: string) -> (string, Error) { // 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) } @(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 if rel == "" { rel = "." @@ -743,7 +765,7 @@ absolute_path_from_relative :: proc(rel: string) -> (path: string, err: Error) { return path, nil } -access :: proc(path: string, mask: int) -> (bool, Error) { +_access :: proc(path: string, mask: int) -> (bool, Error) { runtime.DEFAULT_TEMP_ALLOCATOR_TEMP_GUARD() cstr := strings.clone_to_cstring(path, context.temp_allocator) res := _unix_access(cstr, c.int(mask)) @@ -754,7 +776,7 @@ access :: proc(path: string, mask: int) -> (bool, Error) { } @(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) path_str := strings.clone_to_cstring(key, context.temp_allocator) cstr := _unix_getenv(path_str) @@ -765,13 +787,30 @@ lookup_env :: proc(key: string, allocator := context.allocator) -> (value: strin } @(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) return } @(require_results) -get_current_directory :: proc() -> string { +_environ :: proc(allocator := context.allocator) -> []string { + unimplemented("TODO: _environ") +} + +_set_env :: proc(key, value: string) -> Error { + unimplemented("TODO: _set_env") +} +_unset_env :: proc(key: string) -> Error { + unimplemented("TODO: _unset_env") +} + +_clear_env :: proc() { + unimplemented("TODO: _clear_env") +} + + +@(require_results) +_get_current_directory :: proc() -> string { buf := make([dynamic]u8, MAX_PATH) for { cwd := _unix_getcwd(cstring(raw_data(buf)), c.size_t(len(buf))) @@ -787,7 +826,7 @@ get_current_directory :: proc() -> string { unreachable() } -set_current_directory :: proc(path: string) -> (err: Error) { +_set_current_directory :: proc(path: string) -> (err: Error) { runtime.DEFAULT_TEMP_ALLOCATOR_TEMP_GUARD() cstr := strings.clone_to_cstring(path, context.temp_allocator) res := _unix_chdir(cstr) @@ -797,13 +836,13 @@ set_current_directory :: proc(path: string) -> (err: Error) { return nil } -exit :: proc "contextless" (code: int) -> ! { +_exit :: proc "contextless" (code: int) -> ! { runtime._cleanup_runtime_contextless() _unix_exit(c.int(code)) } @(require_results) -current_thread_id :: proc "contextless" () -> int { +_current_thread_id :: proc "contextless" () -> int { return _unix_getthrid() } @@ -832,7 +871,7 @@ dlerror :: proc() -> string { } @(require_results) -get_page_size :: proc() -> int { +_get_page_size :: proc() -> int { // NOTE(tetra): The page size never changes, so why do anything complicated // if we don't have to. @static page_size := -1 diff --git a/core/os/os_wasi.odin b/core/os/os_wasi.odin index 28f470357b6..2393e753c27 100644 --- a/core/os/os_wasi.odin +++ b/core/os/os_wasi.odin @@ -6,6 +6,8 @@ import "base:runtime" Handle :: distinct i32 _Platform_Error :: wasi.errno_t +File_Time :: i64 + INVALID_HANDLE :: -1 O_RDONLY :: 0x00000 @@ -145,28 +147,33 @@ wasi_match_preopen :: proc(path: string) -> (wasi.fd_t, string, bool) { return match.fd, relative, true } -write :: proc(fd: Handle, data: []byte) -> (int, Errno) { +@(require_results, no_instrumentation) +_get_last_error :: proc "contextless" () -> Error { + return nil +} + +_write :: proc(fd: Handle, data: []byte) -> (int, Errno) { iovs := wasi.ciovec_t(data) n, err := wasi.fd_write(wasi.fd_t(fd), {iovs}) return int(n), Platform_Error(err) } -read :: proc(fd: Handle, data: []byte) -> (int, Errno) { +_read :: proc(fd: Handle, data: []byte) -> (int, Errno) { iovs := wasi.iovec_t(data) n, err := wasi.fd_read(wasi.fd_t(fd), {iovs}) return int(n), Platform_Error(err) } -write_at :: proc(fd: Handle, data: []byte, offset: i64) -> (int, Errno) { +_write_at :: proc(fd: Handle, data: []byte, offset: i64) -> (int, Errno) { iovs := wasi.ciovec_t(data) n, err := wasi.fd_pwrite(wasi.fd_t(fd), {iovs}, wasi.filesize_t(offset)) return int(n), Platform_Error(err) } -read_at :: proc(fd: Handle, data: []byte, offset: i64) -> (int, Errno) { +_read_at :: proc(fd: Handle, data: []byte, offset: i64) -> (int, Errno) { iovs := wasi.iovec_t(data) n, err := wasi.fd_pread(wasi.fd_t(fd), {iovs}, wasi.filesize_t(offset)) 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 if mode & O_CREATE == O_CREATE { oflags += {.CREATE} @@ -204,22 +211,22 @@ open :: proc(path: string, mode: int = O_RDONLY, perm: int = 0) -> (Handle, Errn fd, err := wasi.path_open(dir_fd, {.SYMLINK_FOLLOW}, relative, oflags, rights, {}, fdflags) return Handle(fd), Platform_Error(err) } -close :: proc(fd: Handle) -> Errno { +_close :: proc(fd: Handle) -> Errno { err := wasi.fd_close(wasi.fd_t(fd)) return Platform_Error(err) } -flush :: proc(fd: Handle) -> Error { +_flush :: proc(fd: Handle) -> Error { // do nothing return nil } -seek :: proc(fd: Handle, offset: i64, whence: int) -> (i64, Errno) { +_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)) return i64(n), Platform_Error(err) } @(require_results) -current_thread_id :: proc "contextless" () -> int { +_current_thread_id :: proc "contextless" () -> int { return 0 } @(private, require_results) @@ -228,14 +235,156 @@ _processor_core_count :: proc() -> int { } @(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 size = i64(stat.size) return } -exit :: proc "contextless" (code: int) -> ! { +_exit :: proc "contextless" (code: int) -> ! { runtime._cleanup_runtime_contextless() wasi.proc_exit(wasi.exitcode_t(code)) } + + + +@(require_results) +_last_write_time :: proc(fd: Handle) -> (time: File_Time, err: Error) { + unimplemented("TODO: _last_write_time") +} + +@(require_results) +_last_write_time_by_name :: proc(name: string) -> (time: File_Time, err: Error) { + unimplemented("TODO: _last_write_time_by_name") +} + + +_is_path_separator :: proc "contextless" (r: rune) -> bool { + return r == '/' +} + +@(require_results) +_is_file_handle :: proc(fd: Handle) -> bool { + unimplemented("TODO: _is_file_handle") +} + +@(require_results) +_is_file_path :: proc(path: string, follow_links: bool = true) -> bool { + unimplemented("TODO: _is_file_path") +} + +@(require_results) +_is_dir_handle :: proc(fd: Handle) -> bool { + unimplemented("TODO: _is_dir_handle") +} + +@(require_results) +_is_dir_path :: proc(path: string, follow_links: bool = true) -> bool { + unimplemented("TODO: _is_dir_path") +} + + +@(require_results) +_exists :: proc(path: string) -> bool { + unimplemented("TODO: _exists") +} + +_rename :: proc(old, new: string) -> Error { + unimplemented("TODO: _rename") +} + +_remove :: proc(path: string) -> Error { + unimplemented("TODO: _remove") +} + +_link :: proc(old_name, new_name: string) -> (err: Error) { + unimplemented("TODO: _link") +} +_unlink :: proc(path: string) -> (err: Error) { + unimplemented("TODO: _unlink") +} +_ftruncate :: proc(fd: Handle, length: i64) -> (err: Error) { + unimplemented("TODO: _ftruncate") +} + +_truncate :: proc(path: string, length: i64) -> (err: Error) { + unimplemented("TODO: _truncate") +} + + +@(require_results) +_pipe :: proc() -> (r, w: Handle, err: Error) { + return +} + + +@(require_results) +_read_dir :: proc(fd: Handle, n: int, allocator := context.allocator) -> (fi: []File_Info, err: Error) { + unimplemented("TODO: __read_dir") +} + +@(require_results) +_absolute_path_from_handle :: proc(fd: Handle) -> (path: string, err: Error) { + unimplemented("TODO: _absolute_path_from_handle") +} +@(require_results) +_absolute_path_from_relative :: proc(rel: string) -> (path: string, err: Error) { + unimplemented("TODO: _absolute_path_from_relative") +} + +_access :: proc(path: string, mask: int) -> (bool, Error) { + unimplemented("TODO: _access") +} + + +@(require_results) +_environ :: proc(allocator := context.allocator) -> []string { + unimplemented("TODO: _environ") +} +@(require_results) +_lookup_env :: proc(key: string, allocator := context.allocator) -> (value: string, found: bool) { + unimplemented("TODO: _lookup_env") +} + +@(require_results) +_get_env :: proc(key: string, allocator := context.allocator) -> (value: string) { + unimplemented("TODO: _get_env") +} + +_set_env :: proc(key, value: string) -> Error { + unimplemented("TODO: _set_env") +} +_unset_env :: proc(key: string) -> Error { + unimplemented("TODO: _unset_env") +} + +_clear_env :: proc() { + unimplemented("TODO: _clear_env") +} + +@(require_results) +_get_current_directory :: proc() -> string { + unimplemented("TODO: _get_current_directory") +} + + +_set_current_directory :: proc(path: string) -> (err: Error) { + unimplemented("TODO: _set_current_directory") +} + + + +_make_directory :: proc(path: string, mode: u32 = 0o775) -> Error { + unimplemented("TODO: _make_directory") +} + +_remove_directory :: proc(path: string) -> Error { + unimplemented("TODO: _remove_directory") +} + + +@(require_results) +_get_page_size :: proc() -> int { + return 1<<16 +} \ No newline at end of file diff --git a/core/os/os_windows.odin b/core/os/os_windows.odin index 273fe5af000..c61966e7c42 100644 --- a/core/os/os_windows.odin +++ b/core/os/os_windows.odin @@ -61,7 +61,7 @@ ERROR_FILE_IS_NOT_DIR :: General_Error.Not_Dir args := _alloc_command_line_arguments() @(require_results, no_instrumentation) -get_last_error :: proc "contextless" () -> Error { +_get_last_error :: proc "contextless" () -> Error { err := win32.GetLastError() if err == 0 { return nil @@ -113,7 +113,7 @@ get_last_error :: proc "contextless" () -> Error { @(require_results) -last_write_time :: proc(fd: Handle) -> (File_Time, Error) { +_last_write_time :: proc(fd: Handle) -> (File_Time, Error) { file_info: win32.BY_HANDLE_FILE_INFORMATION if !win32.GetFileInformationByHandle(win32.HANDLE(fd), &file_info) { return 0, get_last_error() @@ -124,7 +124,7 @@ last_write_time :: proc(fd: Handle) -> (File_Time, Error) { } @(require_results) -last_write_time_by_name :: proc(name: string) -> (File_Time, Error) { +_last_write_time_by_name :: proc(name: string) -> (File_Time, Error) { data: win32.WIN32_FILE_ATTRIBUTE_DATA wide_path := win32.utf8_to_wstring(name) @@ -139,7 +139,7 @@ last_write_time_by_name :: proc(name: string) -> (File_Time, Error) { @(require_results) -get_page_size :: proc() -> int { +_get_page_size :: proc() -> int { // NOTE(tetra): The page size never changes, so why do anything complicated // if we don't have to. @static page_size := -1 @@ -177,7 +177,7 @@ _processor_core_count :: proc() -> int { return thread_count } -exit :: proc "contextless" (code: int) -> ! { +_exit :: proc "contextless" (code: int) -> ! { runtime._cleanup_runtime_contextless() win32.ExitProcess(win32.DWORD(code)) } @@ -185,10 +185,23 @@ exit :: proc "contextless" (code: int) -> ! { @(require_results) -current_thread_id :: proc "contextless" () -> int { +_current_thread_id :: proc "contextless" () -> int { return int(win32.GetCurrentThreadId()) } +@(require_results) +_absolute_path_from_handle :: proc(fd: Handle) -> (path: string, err: Error) { + unimplemented("TODO: _absolute_path_from_handle") +} +@(require_results) +_absolute_path_from_relative :: proc(rel: string) -> (path: string, err: Error) { + unimplemented("TODO: _absolute_path_from_relative") +} + +@(require_results) +_access :: proc(path: string, mask: int) -> (bool, Error) { + return false, nil +} @(require_results)