mirror of
https://github.com/Ed94/Odin.git
synced 2026-08-05 15:18:49 +00:00
Use union #shared_nil for os.Error
This commit is contained in:
@@ -8,8 +8,8 @@ HAS_RAND_BYTES :: true
|
|||||||
|
|
||||||
@(private)
|
@(private)
|
||||||
_rand_bytes :: proc(dst: []byte) {
|
_rand_bytes :: proc(dst: []byte) {
|
||||||
ret := (os.Errno)(win32.BCryptGenRandom(nil, raw_data(dst), u32(len(dst)), win32.BCRYPT_USE_SYSTEM_PREFERRED_RNG))
|
ret := os.Platform_Error(win32.BCryptGenRandom(nil, raw_data(dst), u32(len(dst)), win32.BCRYPT_USE_SYSTEM_PREFERRED_RNG))
|
||||||
if ret != os.ERROR_NONE {
|
if ret != nil {
|
||||||
#partial switch ret {
|
#partial switch ret {
|
||||||
case os.ERROR_INVALID_HANDLE:
|
case os.ERROR_INVALID_HANDLE:
|
||||||
// The handle to the first parameter is invalid.
|
// The handle to the first parameter is invalid.
|
||||||
|
|||||||
@@ -88,7 +88,7 @@ read_dir :: proc(fd: Handle, n: int, allocator := context.allocator) -> (fi: []F
|
|||||||
find_data := &win32.WIN32_FIND_DATAW{}
|
find_data := &win32.WIN32_FIND_DATAW{}
|
||||||
find_handle := win32.FindFirstFileW(raw_data(wpath_search), find_data)
|
find_handle := win32.FindFirstFileW(raw_data(wpath_search), find_data)
|
||||||
if find_handle == win32.INVALID_HANDLE_VALUE {
|
if find_handle == win32.INVALID_HANDLE_VALUE {
|
||||||
err = Errno(win32.GetLastError())
|
err = Platform_Error(win32.GetLastError())
|
||||||
return dfi[:], err
|
return dfi[:], err
|
||||||
}
|
}
|
||||||
defer win32.FindClose(find_handle)
|
defer win32.FindClose(find_handle)
|
||||||
@@ -101,7 +101,7 @@ read_dir :: proc(fd: Handle, n: int, allocator := context.allocator) -> (fi: []F
|
|||||||
}
|
}
|
||||||
|
|
||||||
if !win32.FindNextFileW(find_handle, find_data) {
|
if !win32.FindNextFileW(find_handle, find_data) {
|
||||||
e := Errno(win32.GetLastError())
|
e := Platform_Error(win32.GetLastError())
|
||||||
if e == ERROR_NO_MORE_FILES {
|
if e == ERROR_NO_MORE_FILES {
|
||||||
break
|
break
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -50,7 +50,7 @@ set_env :: proc(key, value: string) -> Errno {
|
|||||||
v := win32.utf8_to_wstring(value)
|
v := win32.utf8_to_wstring(value)
|
||||||
|
|
||||||
if !win32.SetEnvironmentVariableW(k, v) {
|
if !win32.SetEnvironmentVariableW(k, v) {
|
||||||
return Errno(win32.GetLastError())
|
return Platform_Error(win32.GetLastError())
|
||||||
}
|
}
|
||||||
return 0
|
return 0
|
||||||
}
|
}
|
||||||
@@ -59,7 +59,7 @@ set_env :: proc(key, value: string) -> Errno {
|
|||||||
unset_env :: proc(key: string) -> Errno {
|
unset_env :: proc(key: string) -> Errno {
|
||||||
k := win32.utf8_to_wstring(key)
|
k := win32.utf8_to_wstring(key)
|
||||||
if !win32.SetEnvironmentVariableW(k, nil) {
|
if !win32.SetEnvironmentVariableW(k, nil) {
|
||||||
return Errno(win32.GetLastError())
|
return Platform_Error(win32.GetLastError())
|
||||||
}
|
}
|
||||||
return 0
|
return 0
|
||||||
}
|
}
|
||||||
|
|||||||
+19
-20
@@ -55,20 +55,20 @@ open :: proc(path: string, mode: int = O_RDONLY, perm: int = 0) -> (Handle, Errn
|
|||||||
return handle, ERROR_NONE
|
return handle, ERROR_NONE
|
||||||
}
|
}
|
||||||
|
|
||||||
err := Errno(win32.GetLastError())
|
err := Platform_Error(win32.GetLastError())
|
||||||
return INVALID_HANDLE, err
|
return INVALID_HANDLE, err
|
||||||
}
|
}
|
||||||
|
|
||||||
close :: proc(fd: Handle) -> Errno {
|
close :: proc(fd: Handle) -> Errno {
|
||||||
if !win32.CloseHandle(win32.HANDLE(fd)) {
|
if !win32.CloseHandle(win32.HANDLE(fd)) {
|
||||||
return Errno(win32.GetLastError())
|
return Platform_Error(win32.GetLastError())
|
||||||
}
|
}
|
||||||
return ERROR_NONE
|
return ERROR_NONE
|
||||||
}
|
}
|
||||||
|
|
||||||
flush :: proc(fd: Handle) -> (err: Errno) {
|
flush :: proc(fd: Handle) -> (err: Errno) {
|
||||||
if !win32.FlushFileBuffers(win32.HANDLE(fd)) {
|
if !win32.FlushFileBuffers(win32.HANDLE(fd)) {
|
||||||
err = Errno(win32.GetLastError())
|
err = Platform_Error(win32.GetLastError())
|
||||||
}
|
}
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
@@ -90,7 +90,7 @@ write :: proc(fd: Handle, data: []byte) -> (int, Errno) {
|
|||||||
|
|
||||||
e := win32.WriteFile(win32.HANDLE(fd), &data[total_write], to_write, &single_write_length, nil)
|
e := win32.WriteFile(win32.HANDLE(fd), &data[total_write], to_write, &single_write_length, nil)
|
||||||
if single_write_length <= 0 || !e {
|
if single_write_length <= 0 || !e {
|
||||||
err := Errno(win32.GetLastError())
|
err := Platform_Error(win32.GetLastError())
|
||||||
return int(total_write), err
|
return int(total_write), err
|
||||||
}
|
}
|
||||||
total_write += i64(single_write_length)
|
total_write += i64(single_write_length)
|
||||||
@@ -118,7 +118,7 @@ read_console :: proc(handle: win32.HANDLE, b: []byte) -> (n: int, err: Errno) {
|
|||||||
single_read_length: u32
|
single_read_length: u32
|
||||||
ok := win32.ReadConsoleW(handle, &buf16[0], max_read, &single_read_length, nil)
|
ok := win32.ReadConsoleW(handle, &buf16[0], max_read, &single_read_length, nil)
|
||||||
if !ok {
|
if !ok {
|
||||||
err = Errno(win32.GetLastError())
|
err = Platform_Error(win32.GetLastError())
|
||||||
}
|
}
|
||||||
|
|
||||||
buf8_len := utf16.decode_to_utf8(buf8[:], buf16[:single_read_length])
|
buf8_len := utf16.decode_to_utf8(buf8[:], buf16[:single_read_length])
|
||||||
@@ -180,7 +180,7 @@ read :: proc(fd: Handle, data: []byte) -> (total_read: int, err: Errno) {
|
|||||||
return int(bytes_read), ERROR_NONE
|
return int(bytes_read), ERROR_NONE
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
return 0, Errno(win32.GetLastError())
|
return 0, Platform_Error(win32.GetLastError())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return total_read, ERROR_NONE
|
return total_read, ERROR_NONE
|
||||||
@@ -202,7 +202,7 @@ seek :: proc(fd: Handle, offset: i64, whence: int) -> (i64, Errno) {
|
|||||||
|
|
||||||
dw_ptr := win32.SetFilePointer(win32.HANDLE(fd), lo, &hi, w)
|
dw_ptr := win32.SetFilePointer(win32.HANDLE(fd), lo, &hi, w)
|
||||||
if dw_ptr == win32.INVALID_SET_FILE_POINTER {
|
if dw_ptr == win32.INVALID_SET_FILE_POINTER {
|
||||||
err := Errno(win32.GetLastError())
|
err := Platform_Error(win32.GetLastError())
|
||||||
return 0, err
|
return 0, err
|
||||||
}
|
}
|
||||||
return i64(hi)<<32 + i64(dw_ptr), ERROR_NONE
|
return i64(hi)<<32 + i64(dw_ptr), ERROR_NONE
|
||||||
@@ -212,7 +212,7 @@ file_size :: proc(fd: Handle) -> (i64, Errno) {
|
|||||||
length: win32.LARGE_INTEGER
|
length: win32.LARGE_INTEGER
|
||||||
err: Errno
|
err: Errno
|
||||||
if !win32.GetFileSizeEx(win32.HANDLE(fd), &length) {
|
if !win32.GetFileSizeEx(win32.HANDLE(fd), &length) {
|
||||||
err = Errno(win32.GetLastError())
|
err = Platform_Error(win32.GetLastError())
|
||||||
}
|
}
|
||||||
return i64(length), err
|
return i64(length), err
|
||||||
}
|
}
|
||||||
@@ -220,7 +220,6 @@ file_size :: proc(fd: Handle) -> (i64, Errno) {
|
|||||||
|
|
||||||
@(private)
|
@(private)
|
||||||
MAX_RW :: 1<<30
|
MAX_RW :: 1<<30
|
||||||
ERROR_EOF :: 38
|
|
||||||
|
|
||||||
@(private)
|
@(private)
|
||||||
pread :: proc(fd: Handle, data: []byte, offset: i64) -> (int, Errno) {
|
pread :: proc(fd: Handle, data: []byte, offset: i64) -> (int, Errno) {
|
||||||
@@ -241,7 +240,7 @@ pread :: proc(fd: Handle, data: []byte, offset: i64) -> (int, Errno) {
|
|||||||
done: win32.DWORD
|
done: win32.DWORD
|
||||||
e: Errno
|
e: Errno
|
||||||
if !win32.ReadFile(h, raw_data(buf), u32(len(buf)), &done, &o) {
|
if !win32.ReadFile(h, raw_data(buf), u32(len(buf)), &done, &o) {
|
||||||
e = Errno(win32.GetLastError())
|
e = Platform_Error(win32.GetLastError())
|
||||||
done = 0
|
done = 0
|
||||||
}
|
}
|
||||||
return int(done), e
|
return int(done), e
|
||||||
@@ -263,7 +262,7 @@ pwrite :: proc(fd: Handle, data: []byte, offset: i64) -> (int, Errno) {
|
|||||||
done: win32.DWORD
|
done: win32.DWORD
|
||||||
e: Errno
|
e: Errno
|
||||||
if !win32.WriteFile(h, raw_data(buf), u32(len(buf)), &done, &o) {
|
if !win32.WriteFile(h, raw_data(buf), u32(len(buf)), &done, &o) {
|
||||||
e = Errno(win32.GetLastError())
|
e = Platform_Error(win32.GetLastError())
|
||||||
done = 0
|
done = 0
|
||||||
}
|
}
|
||||||
return int(done), e
|
return int(done), e
|
||||||
@@ -400,7 +399,7 @@ set_current_directory :: proc(path: string) -> (err: Errno) {
|
|||||||
win32.AcquireSRWLockExclusive(&cwd_lock)
|
win32.AcquireSRWLockExclusive(&cwd_lock)
|
||||||
|
|
||||||
if !win32.SetCurrentDirectoryW(wstr) {
|
if !win32.SetCurrentDirectoryW(wstr) {
|
||||||
err = Errno(win32.GetLastError())
|
err = Platform_Error(win32.GetLastError())
|
||||||
}
|
}
|
||||||
|
|
||||||
win32.ReleaseSRWLockExclusive(&cwd_lock)
|
win32.ReleaseSRWLockExclusive(&cwd_lock)
|
||||||
@@ -415,7 +414,7 @@ make_directory :: proc(path: string, mode: u32 = 0) -> (err: Errno) {
|
|||||||
wpath := win32.utf8_to_wstring(path, context.temp_allocator)
|
wpath := win32.utf8_to_wstring(path, context.temp_allocator)
|
||||||
|
|
||||||
if !win32.CreateDirectoryW(wpath, nil) {
|
if !win32.CreateDirectoryW(wpath, nil) {
|
||||||
err = Errno(win32.GetLastError())
|
err = Platform_Error(win32.GetLastError())
|
||||||
}
|
}
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
@@ -426,7 +425,7 @@ remove_directory :: proc(path: string) -> (err: Errno) {
|
|||||||
wpath := win32.utf8_to_wstring(path, context.temp_allocator)
|
wpath := win32.utf8_to_wstring(path, context.temp_allocator)
|
||||||
|
|
||||||
if !win32.RemoveDirectoryW(wpath) {
|
if !win32.RemoveDirectoryW(wpath) {
|
||||||
err = Errno(win32.GetLastError())
|
err = Platform_Error(win32.GetLastError())
|
||||||
}
|
}
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
@@ -498,7 +497,7 @@ link :: proc(old_name, new_name: string) -> (err: Errno) {
|
|||||||
runtime.DEFAULT_TEMP_ALLOCATOR_TEMP_GUARD()
|
runtime.DEFAULT_TEMP_ALLOCATOR_TEMP_GUARD()
|
||||||
n := win32.utf8_to_wstring(fix_long_path(new_name))
|
n := win32.utf8_to_wstring(fix_long_path(new_name))
|
||||||
o := win32.utf8_to_wstring(fix_long_path(old_name))
|
o := win32.utf8_to_wstring(fix_long_path(old_name))
|
||||||
return Errno(win32.CreateHardLinkW(n, o, nil))
|
return Platform_Error(win32.CreateHardLinkW(n, o, nil))
|
||||||
}
|
}
|
||||||
|
|
||||||
unlink :: proc(path: string) -> (err: Errno) {
|
unlink :: proc(path: string) -> (err: Errno) {
|
||||||
@@ -506,7 +505,7 @@ unlink :: proc(path: string) -> (err: Errno) {
|
|||||||
wpath := win32.utf8_to_wstring(path, context.temp_allocator)
|
wpath := win32.utf8_to_wstring(path, context.temp_allocator)
|
||||||
|
|
||||||
if !win32.DeleteFileW(wpath) {
|
if !win32.DeleteFileW(wpath) {
|
||||||
err = Errno(win32.GetLastError())
|
err = Platform_Error(win32.GetLastError())
|
||||||
}
|
}
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
@@ -519,7 +518,7 @@ rename :: proc(old_path, new_path: string) -> (err: Errno) {
|
|||||||
to := win32.utf8_to_wstring(new_path, context.temp_allocator)
|
to := win32.utf8_to_wstring(new_path, context.temp_allocator)
|
||||||
|
|
||||||
if !win32.MoveFileExW(from, to, win32.MOVEFILE_REPLACE_EXISTING) {
|
if !win32.MoveFileExW(from, to, win32.MOVEFILE_REPLACE_EXISTING) {
|
||||||
err = Errno(win32.GetLastError())
|
err = Platform_Error(win32.GetLastError())
|
||||||
}
|
}
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
@@ -537,7 +536,7 @@ ftruncate :: proc(fd: Handle, length: i64) -> (err: Errno) {
|
|||||||
}
|
}
|
||||||
ok := win32.SetEndOfFile(win32.HANDLE(fd))
|
ok := win32.SetEndOfFile(win32.HANDLE(fd))
|
||||||
if !ok {
|
if !ok {
|
||||||
return Errno(win32.GetLastError())
|
return Platform_Error(win32.GetLastError())
|
||||||
}
|
}
|
||||||
return ERROR_NONE
|
return ERROR_NONE
|
||||||
}
|
}
|
||||||
@@ -588,7 +587,7 @@ remove :: proc(name: string) -> Errno {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return Errno(err)
|
return Platform_Error(err)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -597,7 +596,7 @@ pipe :: proc() -> (r, w: Handle, err: Errno) {
|
|||||||
sa.nLength = size_of(win32.SECURITY_ATTRIBUTES)
|
sa.nLength = size_of(win32.SECURITY_ATTRIBUTES)
|
||||||
sa.bInheritHandle = true
|
sa.bInheritHandle = true
|
||||||
if !win32.CreatePipe((^win32.HANDLE)(&r), (^win32.HANDLE)(&w), &sa, 0) {
|
if !win32.CreatePipe((^win32.HANDLE)(&r), (^win32.HANDLE)(&w), &sa, 0) {
|
||||||
err = Errno(win32.GetLastError())
|
err = Platform_Error(win32.GetLastError())
|
||||||
}
|
}
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|||||||
+13
-4
@@ -1,5 +1,6 @@
|
|||||||
package os
|
package os
|
||||||
|
|
||||||
|
import "base:intrinsics"
|
||||||
import "base:runtime"
|
import "base:runtime"
|
||||||
import "core:strconv"
|
import "core:strconv"
|
||||||
import "core:unicode/utf8"
|
import "core:unicode/utf8"
|
||||||
@@ -14,10 +15,18 @@ SEEK_CUR :: 1
|
|||||||
SEEK_END :: 2
|
SEEK_END :: 2
|
||||||
|
|
||||||
Platform_Error :: _Platform_Error
|
Platform_Error :: _Platform_Error
|
||||||
Error :: Platform_Error
|
#assert(size_of(Platform_Error) <= 4)
|
||||||
Errno :: Error // alias
|
#assert(intrinsics.type_has_nil(Platform_Error))
|
||||||
|
|
||||||
ERROR_NONE :: Errno(0)
|
Errno :: Error // alias for legacy use
|
||||||
|
|
||||||
|
Error :: union #shared_nil {
|
||||||
|
Platform_Error,
|
||||||
|
runtime.Allocator_Error,
|
||||||
|
}
|
||||||
|
#assert(size_of(Error) <= 8)
|
||||||
|
|
||||||
|
ERROR_NONE :: Error{}
|
||||||
|
|
||||||
write_string :: proc(fd: Handle, str: string) -> (int, Errno) {
|
write_string :: proc(fd: Handle, str: string) -> (int, Errno) {
|
||||||
return write(fd, transmute([]byte)str)
|
return write(fd, transmute([]byte)str)
|
||||||
@@ -67,7 +76,7 @@ write_encoded_rune :: proc(fd: Handle, r: rune) {
|
|||||||
|
|
||||||
read_at_least :: proc(fd: Handle, buf: []byte, min: int) -> (n: int, err: Errno) {
|
read_at_least :: proc(fd: Handle, buf: []byte, min: int) -> (n: int, err: Errno) {
|
||||||
if len(buf) < min {
|
if len(buf) < min {
|
||||||
return 0, -1
|
return 0, Platform_Error(~intrinsics.type_core_type(Platform_Error)(0)) // TODO(bill): replace this error
|
||||||
}
|
}
|
||||||
nn := max(int)
|
nn := max(int)
|
||||||
for nn > 0 && n < min && err == 0 {
|
for nn > 0 && n < min && err == 0 {
|
||||||
|
|||||||
@@ -636,7 +636,7 @@ foreign dl {
|
|||||||
}
|
}
|
||||||
|
|
||||||
get_last_error :: proc "contextless" () -> Error {
|
get_last_error :: proc "contextless" () -> Error {
|
||||||
return Error(__error()^)
|
return Platform_Error(__error()^)
|
||||||
}
|
}
|
||||||
|
|
||||||
get_last_error_string :: proc() -> string {
|
get_last_error_string :: proc() -> string {
|
||||||
@@ -678,11 +678,11 @@ open :: proc(path: string, flags: int = O_RDWR, mode: int = 0) -> (Handle, Errno
|
|||||||
}
|
}
|
||||||
|
|
||||||
fchmod :: proc(fd: Handle, mode: u16) -> Errno {
|
fchmod :: proc(fd: Handle, mode: u16) -> Errno {
|
||||||
return cast(Errno)_unix_fchmod(fd, mode)
|
return cast(Platform_Error)_unix_fchmod(fd, mode)
|
||||||
}
|
}
|
||||||
|
|
||||||
close :: proc(fd: Handle) -> Errno {
|
close :: proc(fd: Handle) -> Errno {
|
||||||
return cast(Errno)_unix_close(fd)
|
return cast(Platform_Error)_unix_close(fd)
|
||||||
}
|
}
|
||||||
|
|
||||||
// If you read or write more than `SSIZE_MAX` bytes, most darwin implementations will return `EINVAL`
|
// If you read or write more than `SSIZE_MAX` bytes, most darwin implementations will return `EINVAL`
|
||||||
@@ -756,7 +756,7 @@ seek :: proc(fd: Handle, offset: i64, whence: int) -> (i64, Errno) {
|
|||||||
|
|
||||||
final_offset := i64(_unix_lseek(fd, int(offset), c.int(whence)))
|
final_offset := i64(_unix_lseek(fd, int(offset), c.int(whence)))
|
||||||
if final_offset == -1 {
|
if final_offset == -1 {
|
||||||
return 0, 1
|
return 0, Platform_Error.EPERM
|
||||||
}
|
}
|
||||||
return final_offset, 0
|
return final_offset, 0
|
||||||
}
|
}
|
||||||
@@ -1011,7 +1011,7 @@ access :: proc(path: string, mask: int) -> bool {
|
|||||||
}
|
}
|
||||||
|
|
||||||
flush :: proc(fd: Handle) -> Errno {
|
flush :: proc(fd: Handle) -> Errno {
|
||||||
return cast(Errno)_unix_fsync(fd)
|
return cast(Platform_Error)_unix_fsync(fd)
|
||||||
}
|
}
|
||||||
|
|
||||||
lookup_env :: proc(key: string, allocator := context.allocator) -> (value: string, found: bool) {
|
lookup_env :: proc(key: string, allocator := context.allocator) -> (value: string, found: bool) {
|
||||||
|
|||||||
@@ -420,7 +420,7 @@ is_path_separator :: proc(r: rune) -> bool {
|
|||||||
}
|
}
|
||||||
|
|
||||||
get_last_error :: proc "contextless" () -> Error {
|
get_last_error :: proc "contextless" () -> Error {
|
||||||
return Error(__errno_location()^)
|
return Platform_Error(__errno_location()^)
|
||||||
}
|
}
|
||||||
|
|
||||||
open :: proc(path: string, flags: int = O_RDONLY, mode: int = 0) -> (Handle, Errno) {
|
open :: proc(path: string, flags: int = O_RDONLY, mode: int = 0) -> (Handle, Errno) {
|
||||||
|
|||||||
@@ -182,7 +182,7 @@ is_path_separator :: proc(r: rune) -> bool {
|
|||||||
}
|
}
|
||||||
|
|
||||||
get_last_error :: proc "contextless" () -> Error {
|
get_last_error :: proc "contextless" () -> Error {
|
||||||
return Error(__error()^)
|
return Platform_Error(__error()^)
|
||||||
}
|
}
|
||||||
|
|
||||||
fork :: proc() -> (Pid, Errno) {
|
fork :: proc() -> (Pid, Errno) {
|
||||||
|
|||||||
@@ -514,14 +514,14 @@ is_path_separator :: proc(r: rune) -> bool {
|
|||||||
@private
|
@private
|
||||||
_get_errno :: proc(res: int) -> Errno {
|
_get_errno :: proc(res: int) -> Errno {
|
||||||
if res < 0 && res > -4096 {
|
if res < 0 && res > -4096 {
|
||||||
return Errno(-res)
|
return Platform_Error(-res)
|
||||||
}
|
}
|
||||||
return 0
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// get errno from libc
|
// get errno from libc
|
||||||
get_last_error :: proc "contextless" () -> Error {
|
get_last_error :: proc "contextless" () -> Error {
|
||||||
return Error(__errno_location()^)
|
return Platform_Error(__errno_location()^)
|
||||||
}
|
}
|
||||||
|
|
||||||
personality :: proc(persona: u64) -> (Errno) {
|
personality :: proc(persona: u64) -> (Errno) {
|
||||||
|
|||||||
@@ -478,7 +478,7 @@ is_path_separator :: proc(r: rune) -> bool {
|
|||||||
}
|
}
|
||||||
|
|
||||||
get_last_error :: proc "contextless" () -> Error {
|
get_last_error :: proc "contextless" () -> Error {
|
||||||
return Error(__errno_location()^)
|
return Platform_Error(__errno_location()^)
|
||||||
}
|
}
|
||||||
|
|
||||||
open :: proc(path: string, flags: int = O_RDONLY, mode: int = 0) -> (Handle, Errno) {
|
open :: proc(path: string, flags: int = O_RDONLY, mode: int = 0) -> (Handle, Errno) {
|
||||||
|
|||||||
@@ -393,7 +393,7 @@ is_path_separator :: proc(r: rune) -> bool {
|
|||||||
}
|
}
|
||||||
|
|
||||||
get_last_error :: proc "contextless" () -> Error {
|
get_last_error :: proc "contextless" () -> Error {
|
||||||
return Error(__error()^)
|
return Platform_Error(__error()^)
|
||||||
}
|
}
|
||||||
|
|
||||||
fork :: proc() -> (Pid, Errno) {
|
fork :: proc() -> (Pid, Errno) {
|
||||||
|
|||||||
+9
-11
@@ -4,9 +4,7 @@ import "core:sys/wasm/wasi"
|
|||||||
import "base:runtime"
|
import "base:runtime"
|
||||||
|
|
||||||
Handle :: distinct i32
|
Handle :: distinct i32
|
||||||
_Platform_Error :: enum i32 {
|
_Platform_Error :: wasi.errno_t
|
||||||
NONE = 0,
|
|
||||||
}
|
|
||||||
|
|
||||||
INVALID_HANDLE :: -1
|
INVALID_HANDLE :: -1
|
||||||
|
|
||||||
@@ -150,22 +148,22 @@ wasi_match_preopen :: proc(path: string) -> (wasi.fd_t, string, bool) {
|
|||||||
write :: proc(fd: Handle, data: []byte) -> (int, Errno) {
|
write :: proc(fd: Handle, data: []byte) -> (int, Errno) {
|
||||||
iovs := wasi.ciovec_t(data)
|
iovs := wasi.ciovec_t(data)
|
||||||
n, err := wasi.fd_write(wasi.fd_t(fd), {iovs})
|
n, err := wasi.fd_write(wasi.fd_t(fd), {iovs})
|
||||||
return int(n), Errno(err)
|
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)
|
iovs := wasi.iovec_t(data)
|
||||||
n, err := wasi.fd_read(wasi.fd_t(fd), {iovs})
|
n, err := wasi.fd_read(wasi.fd_t(fd), {iovs})
|
||||||
return int(n), Errno(err)
|
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)
|
iovs := wasi.ciovec_t(data)
|
||||||
n, err := wasi.fd_pwrite(wasi.fd_t(fd), {iovs}, wasi.filesize_t(offset))
|
n, err := wasi.fd_pwrite(wasi.fd_t(fd), {iovs}, wasi.filesize_t(offset))
|
||||||
return int(n), Errno(err)
|
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)
|
iovs := wasi.iovec_t(data)
|
||||||
n, err := wasi.fd_pread(wasi.fd_t(fd), {iovs}, wasi.filesize_t(offset))
|
n, err := wasi.fd_pread(wasi.fd_t(fd), {iovs}, wasi.filesize_t(offset))
|
||||||
return int(n), Errno(err)
|
return int(n), Platform_Error(err)
|
||||||
}
|
}
|
||||||
open :: proc(path: string, mode: int = O_RDONLY, perm: int = 0) -> (Handle, Errno) {
|
open :: proc(path: string, mode: int = O_RDONLY, perm: int = 0) -> (Handle, Errno) {
|
||||||
oflags: wasi.oflags_t
|
oflags: wasi.oflags_t
|
||||||
@@ -203,15 +201,15 @@ 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)
|
fd, err := wasi.path_open(dir_fd, {.SYMLINK_FOLLOW}, relative, oflags, rights, {}, fdflags)
|
||||||
return Handle(fd), Errno(err)
|
return Handle(fd), Platform_Error(err)
|
||||||
}
|
}
|
||||||
close :: proc(fd: Handle) -> Errno {
|
close :: proc(fd: Handle) -> Errno {
|
||||||
err := wasi.fd_close(wasi.fd_t(fd))
|
err := wasi.fd_close(wasi.fd_t(fd))
|
||||||
return Errno(err)
|
return Platform_Error(err)
|
||||||
}
|
}
|
||||||
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))
|
n, err := wasi.fd_seek(wasi.fd_t(fd), wasi.filedelta_t(offset), wasi.whence_t(whence))
|
||||||
return i64(n), Errno(err)
|
return i64(n), Platform_Error(err)
|
||||||
}
|
}
|
||||||
current_thread_id :: proc "contextless" () -> int {
|
current_thread_id :: proc "contextless" () -> int {
|
||||||
return 0
|
return 0
|
||||||
@@ -224,7 +222,7 @@ _processor_core_count :: proc() -> int {
|
|||||||
file_size :: proc(fd: Handle) -> (i64, Errno) {
|
file_size :: proc(fd: Handle) -> (i64, Errno) {
|
||||||
stat, err := wasi.fd_filestat_get(wasi.fd_t(fd))
|
stat, err := wasi.fd_filestat_get(wasi.fd_t(fd))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return 0, Errno(err)
|
return 0, Platform_Error(err)
|
||||||
}
|
}
|
||||||
return i64(stat.size), 0
|
return i64(stat.size), 0
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -35,6 +35,7 @@ ERROR_INVALID_HANDLE :: _Platform_Error(6)
|
|||||||
ERROR_NOT_ENOUGH_MEMORY :: _Platform_Error(8)
|
ERROR_NOT_ENOUGH_MEMORY :: _Platform_Error(8)
|
||||||
ERROR_NO_MORE_FILES :: _Platform_Error(18)
|
ERROR_NO_MORE_FILES :: _Platform_Error(18)
|
||||||
ERROR_HANDLE_EOF :: _Platform_Error(38)
|
ERROR_HANDLE_EOF :: _Platform_Error(38)
|
||||||
|
ERROR_EOF :: ERROR_HANDLE_EOF
|
||||||
ERROR_NETNAME_DELETED :: _Platform_Error(64)
|
ERROR_NETNAME_DELETED :: _Platform_Error(64)
|
||||||
ERROR_FILE_EXISTS :: _Platform_Error(80)
|
ERROR_FILE_EXISTS :: _Platform_Error(80)
|
||||||
ERROR_INVALID_PARAMETER :: _Platform_Error(87)
|
ERROR_INVALID_PARAMETER :: _Platform_Error(87)
|
||||||
@@ -62,14 +63,15 @@ ERROR_NEGATIVE_OFFSET :: _Platform_Error(1<<29 + 2)
|
|||||||
// "Argv" arguments converted to Odin strings
|
// "Argv" arguments converted to Odin strings
|
||||||
args := _alloc_command_line_arguments()
|
args := _alloc_command_line_arguments()
|
||||||
|
|
||||||
|
get_last_error :: proc "contextless" () -> Error {
|
||||||
|
return Platform_Error(win32.GetLastError())
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
last_write_time :: proc(fd: Handle) -> (File_Time, Errno) {
|
last_write_time :: proc(fd: Handle) -> (File_Time, Errno) {
|
||||||
file_info: win32.BY_HANDLE_FILE_INFORMATION
|
file_info: win32.BY_HANDLE_FILE_INFORMATION
|
||||||
if !win32.GetFileInformationByHandle(win32.HANDLE(fd), &file_info) {
|
if !win32.GetFileInformationByHandle(win32.HANDLE(fd), &file_info) {
|
||||||
return 0, Errno(win32.GetLastError())
|
return 0, Platform_Error(win32.GetLastError())
|
||||||
}
|
}
|
||||||
lo := File_Time(file_info.ftLastWriteTime.dwLowDateTime)
|
lo := File_Time(file_info.ftLastWriteTime.dwLowDateTime)
|
||||||
hi := File_Time(file_info.ftLastWriteTime.dwHighDateTime)
|
hi := File_Time(file_info.ftLastWriteTime.dwHighDateTime)
|
||||||
@@ -81,7 +83,7 @@ last_write_time_by_name :: proc(name: string) -> (File_Time, Errno) {
|
|||||||
|
|
||||||
wide_path := win32.utf8_to_wstring(name)
|
wide_path := win32.utf8_to_wstring(name)
|
||||||
if !win32.GetFileAttributesExW(wide_path, win32.GetFileExInfoStandard, &data) {
|
if !win32.GetFileAttributesExW(wide_path, win32.GetFileExInfoStandard, &data) {
|
||||||
return 0, Errno(win32.GetLastError())
|
return 0, Platform_Error(win32.GetLastError())
|
||||||
}
|
}
|
||||||
|
|
||||||
l := File_Time(data.ftLastWriteTime.dwLowDateTime)
|
l := File_Time(data.ftLastWriteTime.dwLowDateTime)
|
||||||
|
|||||||
@@ -19,7 +19,7 @@ full_path_from_name :: proc(name: string, allocator := context.allocator) -> (pa
|
|||||||
for {
|
for {
|
||||||
n := win32.GetFullPathNameW(raw_data(p), u32(len(buf)), raw_data(buf), nil)
|
n := win32.GetFullPathNameW(raw_data(p), u32(len(buf)), raw_data(buf), nil)
|
||||||
if n == 0 {
|
if n == 0 {
|
||||||
return "", Errno(win32.GetLastError())
|
return "", Platform_Error(win32.GetLastError())
|
||||||
}
|
}
|
||||||
if n <= u32(len(buf)) {
|
if n <= u32(len(buf)) {
|
||||||
return win32.utf16_to_utf8(buf[:n], allocator) or_else "", ERROR_NONE
|
return win32.utf16_to_utf8(buf[:n], allocator) or_else "", ERROR_NONE
|
||||||
@@ -54,7 +54,7 @@ _stat :: proc(name: string, create_file_attributes: u32, allocator := context.al
|
|||||||
fd: win32.WIN32_FIND_DATAW
|
fd: win32.WIN32_FIND_DATAW
|
||||||
sh := win32.FindFirstFileW(wname, &fd)
|
sh := win32.FindFirstFileW(wname, &fd)
|
||||||
if sh == win32.INVALID_HANDLE_VALUE {
|
if sh == win32.INVALID_HANDLE_VALUE {
|
||||||
e = Errno(win32.GetLastError())
|
e = Platform_Error(win32.GetLastError())
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
win32.FindClose(sh)
|
win32.FindClose(sh)
|
||||||
@@ -64,7 +64,7 @@ _stat :: proc(name: string, create_file_attributes: u32, allocator := context.al
|
|||||||
|
|
||||||
h := win32.CreateFileW(wname, 0, 0, nil, win32.OPEN_EXISTING, create_file_attributes, nil)
|
h := win32.CreateFileW(wname, 0, 0, nil, win32.OPEN_EXISTING, create_file_attributes, nil)
|
||||||
if h == win32.INVALID_HANDLE_VALUE {
|
if h == win32.INVALID_HANDLE_VALUE {
|
||||||
e = Errno(win32.GetLastError())
|
e = Platform_Error(win32.GetLastError())
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
defer win32.CloseHandle(h)
|
defer win32.CloseHandle(h)
|
||||||
@@ -151,7 +151,7 @@ cleanpath_from_handle_u16 :: proc(fd: Handle, allocator: runtime.Allocator) -> (
|
|||||||
|
|
||||||
n := win32.GetFinalPathNameByHandleW(h, nil, 0, 0)
|
n := win32.GetFinalPathNameByHandleW(h, nil, 0, 0)
|
||||||
if n == 0 {
|
if n == 0 {
|
||||||
return nil, Errno(win32.GetLastError())
|
return nil, Platform_Error(win32.GetLastError())
|
||||||
}
|
}
|
||||||
buf := make([]u16, max(n, win32.DWORD(260))+1, allocator)
|
buf := make([]u16, max(n, win32.DWORD(260))+1, allocator)
|
||||||
buf_len := win32.GetFinalPathNameByHandleW(h, raw_data(buf), n, 0)
|
buf_len := win32.GetFinalPathNameByHandleW(h, raw_data(buf), n, 0)
|
||||||
@@ -273,16 +273,16 @@ file_info_from_win32_find_data :: proc(d: ^win32.WIN32_FIND_DATAW, name: string)
|
|||||||
file_info_from_get_file_information_by_handle :: proc(path: string, h: win32.HANDLE) -> (File_Info, Errno) {
|
file_info_from_get_file_information_by_handle :: proc(path: string, h: win32.HANDLE) -> (File_Info, Errno) {
|
||||||
d: win32.BY_HANDLE_FILE_INFORMATION
|
d: win32.BY_HANDLE_FILE_INFORMATION
|
||||||
if !win32.GetFileInformationByHandle(h, &d) {
|
if !win32.GetFileInformationByHandle(h, &d) {
|
||||||
err := Errno(win32.GetLastError())
|
err := Platform_Error(win32.GetLastError())
|
||||||
return {}, err
|
return {}, err
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
ti: win32.FILE_ATTRIBUTE_TAG_INFO
|
ti: win32.FILE_ATTRIBUTE_TAG_INFO
|
||||||
if !win32.GetFileInformationByHandleEx(h, .FileAttributeTagInfo, &ti, size_of(ti)) {
|
if !win32.GetFileInformationByHandleEx(h, .FileAttributeTagInfo, &ti, size_of(ti)) {
|
||||||
err := win32.GetLastError()
|
err := Platform_Error(win32.GetLastError())
|
||||||
if err != u32(ERROR_INVALID_PARAMETER) {
|
if err != ERROR_INVALID_PARAMETER {
|
||||||
return {}, Errno(err)
|
return {}, err
|
||||||
}
|
}
|
||||||
// Indicate this is a symlink on FAT file systems
|
// Indicate this is a symlink on FAT file systems
|
||||||
ti.ReparseTag = 0
|
ti.ReparseTag = 0
|
||||||
|
|||||||
@@ -63,14 +63,14 @@ temp_full_path :: proc(name: string) -> (path: string, err: os.Errno) {
|
|||||||
p := win32.utf8_to_utf16(name, ta)
|
p := win32.utf8_to_utf16(name, ta)
|
||||||
n := win32.GetFullPathNameW(raw_data(p), 0, nil, nil)
|
n := win32.GetFullPathNameW(raw_data(p), 0, nil, nil)
|
||||||
if n == 0 {
|
if n == 0 {
|
||||||
return "", os.Errno(win32.GetLastError())
|
return "", os.Platform_Error(win32.GetLastError())
|
||||||
}
|
}
|
||||||
|
|
||||||
buf := make([]u16, n, ta)
|
buf := make([]u16, n, ta)
|
||||||
n = win32.GetFullPathNameW(raw_data(p), u32(len(buf)), raw_data(buf), nil)
|
n = win32.GetFullPathNameW(raw_data(p), u32(len(buf)), raw_data(buf), nil)
|
||||||
if n == 0 {
|
if n == 0 {
|
||||||
delete(buf)
|
delete(buf)
|
||||||
return "", os.Errno(win32.GetLastError())
|
return "", os.Platform_Error(win32.GetLastError())
|
||||||
}
|
}
|
||||||
|
|
||||||
return win32.utf16_to_utf8(buf[:n], ta) or_else "", os.ERROR_NONE
|
return win32.utf16_to_utf8(buf[:n], ta) or_else "", os.ERROR_NONE
|
||||||
|
|||||||
@@ -25,7 +25,7 @@ _write :: proc "contextless" (fd: os.Handle, data: []byte) -> (int, os.Errno) #n
|
|||||||
|
|
||||||
e := win32.WriteFile(win32.HANDLE(fd), &data[total_write], to_write, &single_write_length, nil)
|
e := win32.WriteFile(win32.HANDLE(fd), &data[total_write], to_write, &single_write_length, nil)
|
||||||
if single_write_length <= 0 || !e {
|
if single_write_length <= 0 || !e {
|
||||||
err := os.Errno(win32.GetLastError())
|
err := os.Platform_Error(win32.GetLastError())
|
||||||
return int(total_write), err
|
return int(total_write), err
|
||||||
}
|
}
|
||||||
total_write += i64(single_write_length)
|
total_write += i64(single_write_length)
|
||||||
|
|||||||
@@ -16,6 +16,7 @@ CLOCK_REALTIME :: clockid_t(2)
|
|||||||
CLOCK_THREAD_CPUTIME_ID :: clockid_t(3)
|
CLOCK_THREAD_CPUTIME_ID :: clockid_t(3)
|
||||||
|
|
||||||
errno_t :: enum u16 {
|
errno_t :: enum u16 {
|
||||||
|
NONE = 0,
|
||||||
// No error occurred. System call completed successfully.
|
// No error occurred. System call completed successfully.
|
||||||
SUCCESS = 0,
|
SUCCESS = 0,
|
||||||
// Argument list too long.
|
// Argument list too long.
|
||||||
|
|||||||
+16
-19
@@ -4366,25 +4366,6 @@ gb_internal void convert_to_typed(CheckerContext *c, Operand *operand, Type *tar
|
|||||||
}
|
}
|
||||||
|
|
||||||
switch (t->kind) {
|
switch (t->kind) {
|
||||||
// IMPORTANT NOTE HACK(bill): This is just to allow for comparisons against `0` with the `os.Error` type
|
|
||||||
// as a kind of transition period
|
|
||||||
case Type_Enum:
|
|
||||||
if (operand->mode == Addressing_Constant &&
|
|
||||||
target_type->kind == Type_Named &&
|
|
||||||
target_type->Named.name == "Error") {
|
|
||||||
Entity *e = target_type->Named.type_name;
|
|
||||||
if (e->pkg && e->pkg->name == "os") {
|
|
||||||
if (is_exact_value_zero(operand->value)) {
|
|
||||||
check_is_expressible(c, operand, t);
|
|
||||||
if (operand->mode == Addressing_Invalid) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
update_untyped_expr_value(c, operand->expr, operand->value);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
|
|
||||||
case Type_Basic:
|
case Type_Basic:
|
||||||
if (operand->mode == Addressing_Constant) {
|
if (operand->mode == Addressing_Constant) {
|
||||||
check_is_expressible(c, operand, t);
|
check_is_expressible(c, operand, t);
|
||||||
@@ -4478,6 +4459,22 @@ gb_internal void convert_to_typed(CheckerContext *c, Operand *operand, Type *tar
|
|||||||
|
|
||||||
|
|
||||||
case Type_Union:
|
case Type_Union:
|
||||||
|
// IMPORTANT NOTE HACK(bill): This is just to allow for comparisons against `0` with the `os.Error` type
|
||||||
|
// as a kind of transition period
|
||||||
|
if (operand->mode == Addressing_Constant &&
|
||||||
|
target_type->kind == Type_Named &&
|
||||||
|
target_type->Named.name == "Error") {
|
||||||
|
Entity *e = target_type->Named.type_name;
|
||||||
|
if (e->pkg && e->pkg->name == "os") {
|
||||||
|
if (is_exact_value_zero(operand->value) &&
|
||||||
|
(operand->value.kind == ExactValue_Integer ||
|
||||||
|
operand->value.kind == ExactValue_Float)) {
|
||||||
|
update_untyped_expr_value(c, operand->expr, empty_exact_value);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// "fallthrough"
|
||||||
if (!is_operand_nil(*operand) && !is_operand_uninit(*operand)) {
|
if (!is_operand_nil(*operand) && !is_operand_uninit(*operand)) {
|
||||||
TEMPORARY_ALLOCATOR_GUARD();
|
TEMPORARY_ALLOCATOR_GUARD();
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user