mirror of
https://github.com/Ed94/Odin.git
synced 2026-08-05 15:18:49 +00:00
Merge pull request #311 from mattt-b/master
Fix bugs and inconsistencies with linux versions of os package
This commit is contained in:
+112
-32
@@ -11,9 +11,42 @@ OS :: "linux";
|
|||||||
Handle :: distinct i32;
|
Handle :: distinct i32;
|
||||||
File_Time :: distinct u64;
|
File_Time :: distinct u64;
|
||||||
Errno :: distinct i32;
|
Errno :: distinct i32;
|
||||||
|
Syscall :: distinct int;
|
||||||
|
|
||||||
INVALID_HANDLE :: ~Handle(0);
|
INVALID_HANDLE :: ~Handle(0);
|
||||||
|
|
||||||
|
ERROR_NONE: Errno : 0;
|
||||||
|
EPERM: Errno : 1;
|
||||||
|
ENOENT: Errno : 2;
|
||||||
|
EINTR: Errno : 4;
|
||||||
|
EIO: Errno : 5;
|
||||||
|
ENXIO: Errno : 6;
|
||||||
|
EBADF: Errno : 9;
|
||||||
|
EAGAIN: Errno : 11;
|
||||||
|
EWOULDBLOCK: Errno : EAGAIN;
|
||||||
|
ENOMEM: Errno : 12;
|
||||||
|
EACCES: Errno : 13;
|
||||||
|
EFAULT: Errno : 14;
|
||||||
|
EEXIST: Errno : 17;
|
||||||
|
ENODEV: Errno : 19;
|
||||||
|
ENOTDIR: Errno : 20;
|
||||||
|
EISDIR: Errno : 21;
|
||||||
|
EINVAL: Errno : 22;
|
||||||
|
ENFILE: Errno : 23;
|
||||||
|
EMFILE: Errno : 24;
|
||||||
|
ETXTBSY: Errno : 26;
|
||||||
|
EFBIG: Errno : 27;
|
||||||
|
ENOSPC: Errno : 28;
|
||||||
|
ESPIPE: Errno : 29;
|
||||||
|
EROFS: Errno : 30;
|
||||||
|
EPIPE: Errno : 32;
|
||||||
|
ENAMETOOLONG: Errno : 36;
|
||||||
|
ELOOP: Errno : 40;
|
||||||
|
EOVERFLOW: Errno : 75;
|
||||||
|
EDESTADDRREQ: Errno : 89;
|
||||||
|
EOPNOTSUPP: Errno : 95;
|
||||||
|
EDQUOT: Errno : 122;
|
||||||
|
|
||||||
O_RDONLY :: 0x00000;
|
O_RDONLY :: 0x00000;
|
||||||
O_WRONLY :: 0x00001;
|
O_WRONLY :: 0x00001;
|
||||||
O_RDWR :: 0x00002;
|
O_RDWR :: 0x00002;
|
||||||
@@ -47,18 +80,13 @@ args := _alloc_command_line_arguments();
|
|||||||
|
|
||||||
_File_Time :: struct {
|
_File_Time :: struct {
|
||||||
seconds: i64,
|
seconds: i64,
|
||||||
nanoseconds: i32,
|
nanoseconds: i64,
|
||||||
reserved: i32,
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Translated from
|
|
||||||
// https://android.googlesource.com/platform/prebuilts/gcc/linux-x86/host/x86_64-linux-glibc2.7-4.6/+/jb-dev/sysroot/usr/include/bits/stat.h
|
|
||||||
// Validity is not guaranteed.
|
|
||||||
|
|
||||||
Stat :: struct {
|
Stat :: struct {
|
||||||
device_id: u64, // ID of device containing file
|
device_id: u64, // ID of device containing file
|
||||||
serial: u64, // File serial number
|
serial: u64, // File serial number
|
||||||
nlink: u32, // Number of hard links
|
nlink: u64, // Number of hard links
|
||||||
mode: u32, // Mode of the file
|
mode: u32, // Mode of the file
|
||||||
uid: u32, // User ID of the file's owner
|
uid: u32, // User ID of the file's owner
|
||||||
gid: u32, // Group ID of the file's group
|
gid: u32, // Group ID of the file's group
|
||||||
@@ -75,8 +103,6 @@ Stat :: struct {
|
|||||||
_reserve1,
|
_reserve1,
|
||||||
_reserve2,
|
_reserve2,
|
||||||
_reserve3: i64,
|
_reserve3: i64,
|
||||||
serial_numbe: u64, // File serial number..? Maybe.
|
|
||||||
_reserve4: i64,
|
|
||||||
};
|
};
|
||||||
|
|
||||||
// File type
|
// File type
|
||||||
@@ -142,15 +168,21 @@ CLOCK_BOOTTIME :: 7;
|
|||||||
CLOCK_REALTIME_ALARM :: 8;
|
CLOCK_REALTIME_ALARM :: 8;
|
||||||
CLOCK_BOOTTIME_ALARM :: 9;
|
CLOCK_BOOTTIME_ALARM :: 9;
|
||||||
|
|
||||||
|
SYS_GETTID: Syscall : 186;
|
||||||
|
|
||||||
foreign libc {
|
foreign libc {
|
||||||
|
@(link_name="__errno_location") __errno_location :: proc() -> ^int ---;
|
||||||
|
@(link_name="syscall") syscall :: proc(number: Syscall, #c_vararg args: ..any) -> int ---;
|
||||||
|
|
||||||
@(link_name="open") _unix_open :: proc(path: cstring, flags: int, #c_vararg mode: ..any) -> Handle ---;
|
@(link_name="open") _unix_open :: proc(path: cstring, flags: int, #c_vararg mode: ..any) -> Handle ---;
|
||||||
@(link_name="close") _unix_close :: proc(fd: Handle) -> i32 ---;
|
@(link_name="close") _unix_close :: proc(fd: Handle) -> int ---;
|
||||||
@(link_name="read") _unix_read :: proc(fd: Handle, buf: rawptr, size: int) -> int ---;
|
@(link_name="read") _unix_read :: proc(fd: Handle, buf: rawptr, size: int) -> int ---;
|
||||||
@(link_name="write") _unix_write :: proc(fd: Handle, buf: rawptr, size: int) -> int ---;
|
@(link_name="write") _unix_write :: proc(fd: Handle, buf: rawptr, size: int) -> int ---;
|
||||||
@(link_name="lseek64") _unix_seek :: proc(fd: Handle, offset: i64, whence: i32) -> i64 ---;
|
@(link_name="lseek64") _unix_seek :: proc(fd: Handle, offset: i64, whence: i32) -> i64 ---;
|
||||||
@(link_name="gettid") _unix_gettid :: proc() -> u64 ---;
|
@(link_name="gettid") _unix_gettid :: proc() -> u64 ---;
|
||||||
@(link_name="stat") _unix_stat :: proc(path: cstring, stat: ^Stat) -> i32 ---;
|
@(link_name="stat") _unix_stat :: proc(path: cstring, stat: ^Stat) -> int ---;
|
||||||
@(link_name="access") _unix_access :: proc(path: cstring, mask: int) -> i32 ---;
|
@(link_name="fstat") _unix_fstat :: proc(fd: Handle, stat: ^Stat) -> int ---;
|
||||||
|
@(link_name="access") _unix_access :: proc(path: cstring, mask: int) -> int ---;
|
||||||
|
|
||||||
@(link_name="malloc") _unix_malloc :: proc(size: int) -> rawptr ---;
|
@(link_name="malloc") _unix_malloc :: proc(size: int) -> rawptr ---;
|
||||||
@(link_name="calloc") _unix_calloc :: proc(num, size: int) -> rawptr ---;
|
@(link_name="calloc") _unix_calloc :: proc(num, size: int) -> rawptr ---;
|
||||||
@@ -171,40 +203,58 @@ foreign dl {
|
|||||||
@(link_name="dlerror") _unix_dlerror :: proc() -> cstring ---;
|
@(link_name="dlerror") _unix_dlerror :: proc() -> cstring ---;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
get_last_error :: proc() -> int {
|
||||||
|
return __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) {
|
||||||
cstr := strings.new_cstring(path);
|
cstr := strings.new_cstring(path);
|
||||||
handle := _unix_open(cstr, flags, mode);
|
handle := _unix_open(cstr, flags, mode);
|
||||||
delete(cstr);
|
delete(cstr);
|
||||||
if handle == -1 {
|
if handle == -1 {
|
||||||
return 0, 1;
|
return INVALID_HANDLE, Errno(get_last_error());
|
||||||
}
|
}
|
||||||
return handle, 0;
|
return handle, ERROR_NONE;
|
||||||
}
|
}
|
||||||
|
|
||||||
close :: proc(fd: Handle) {
|
close :: proc(fd: Handle) -> Errno {
|
||||||
_unix_close(fd);
|
result := _unix_close(fd);
|
||||||
|
if result == -1 {
|
||||||
|
return Errno(get_last_error());
|
||||||
|
}
|
||||||
|
return ERROR_NONE;
|
||||||
}
|
}
|
||||||
|
|
||||||
read :: proc(fd: Handle, data: []byte) -> (int, Errno) {
|
read :: proc(fd: Handle, data: []byte) -> (int, Errno) {
|
||||||
sz := _unix_read(fd, &data[0], len(data));
|
bytes_read := _unix_read(fd, &data[0], len(data));
|
||||||
return sz, 0;
|
if bytes_read == -1 {
|
||||||
|
return -1, Errno(get_last_error());
|
||||||
|
}
|
||||||
|
return bytes_read, ERROR_NONE;
|
||||||
}
|
}
|
||||||
|
|
||||||
write :: proc(fd: Handle, data: []byte) -> (int, Errno) {
|
write :: proc(fd: Handle, data: []byte) -> (int, Errno) {
|
||||||
sz := _unix_write(fd, &data[0], len(data));
|
bytes_written := _unix_write(fd, &data[0], len(data));
|
||||||
return sz, 0;
|
if bytes_written == -1 {
|
||||||
|
return -1, Errno(get_last_error());
|
||||||
|
}
|
||||||
|
return bytes_written, ERROR_NONE;
|
||||||
}
|
}
|
||||||
|
|
||||||
seek :: proc(fd: Handle, offset: i64, whence: int) -> (i64, Errno) {
|
seek :: proc(fd: Handle, offset: i64, whence: int) -> (i64, Errno) {
|
||||||
res := _unix_seek(fd, offset, i32(whence));
|
res := _unix_seek(fd, offset, i32(whence));
|
||||||
return res, 0;
|
if res == -1 {
|
||||||
|
return -1, Errno(get_last_error());
|
||||||
|
}
|
||||||
|
return res, ERROR_NONE;
|
||||||
}
|
}
|
||||||
|
|
||||||
file_size :: proc(fd: Handle) -> (i64, Errno) {
|
file_size :: proc(fd: Handle) -> (i64, Errno) {
|
||||||
prev, _ := seek(fd, 0, SEEK_CUR);
|
s, err := fstat(fd);
|
||||||
size, err := seek(fd, 0, SEEK_END);
|
if err != ERROR_NONE {
|
||||||
seek(fd, prev, SEEK_SET);
|
return -1, err;
|
||||||
return size, err;
|
}
|
||||||
|
return s.size, ERROR_NONE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -218,20 +268,51 @@ stderr: Handle = 2;
|
|||||||
last_write_time :: proc(fd: Handle) -> File_Time {}
|
last_write_time :: proc(fd: Handle) -> File_Time {}
|
||||||
last_write_time_by_name :: proc(name: string) -> File_Time {}
|
last_write_time_by_name :: proc(name: string) -> File_Time {}
|
||||||
*/
|
*/
|
||||||
|
last_write_time :: proc(fd: Handle) -> (File_Time, Errno) {
|
||||||
|
s, err := fstat(fd);
|
||||||
|
if err != ERROR_NONE {
|
||||||
|
return 0, err;
|
||||||
|
}
|
||||||
|
return File_Time(s.modified.nanoseconds), ERROR_NONE;
|
||||||
|
}
|
||||||
|
|
||||||
stat :: inline proc(path: string) -> (Stat, int) {
|
last_write_time_by_name :: proc(name: string) -> (File_Time, Errno) {
|
||||||
|
s, err := stat(name);
|
||||||
|
if err != ERROR_NONE {
|
||||||
|
return 0, err;
|
||||||
|
}
|
||||||
|
return File_Time(s.modified.nanoseconds), ERROR_NONE;
|
||||||
|
}
|
||||||
|
|
||||||
|
stat :: inline proc(path: string) -> (Stat, Errno) {
|
||||||
cstr := strings.new_cstring(path);
|
cstr := strings.new_cstring(path);
|
||||||
defer delete(cstr);
|
defer delete(cstr);
|
||||||
|
|
||||||
s: Stat;
|
s: Stat;
|
||||||
ret_int := _unix_stat(cstr, &s);
|
result := _unix_stat(cstr, &s);
|
||||||
return s, int(ret_int);
|
if result == -1 {
|
||||||
|
return s, Errno(get_last_error());
|
||||||
|
}
|
||||||
|
return s, ERROR_NONE;
|
||||||
}
|
}
|
||||||
|
|
||||||
access :: inline proc(path: string, mask: int) -> bool {
|
fstat :: inline proc(fd: Handle) -> (Stat, Errno) {
|
||||||
|
s: Stat;
|
||||||
|
result := _unix_fstat(fd, &s);
|
||||||
|
if result == -1 {
|
||||||
|
return s, Errno(get_last_error());
|
||||||
|
}
|
||||||
|
return s, ERROR_NONE;
|
||||||
|
}
|
||||||
|
|
||||||
|
access :: inline proc(path: string, mask: int) -> (bool, Errno) {
|
||||||
cstr := strings.new_cstring(path);
|
cstr := strings.new_cstring(path);
|
||||||
defer delete(cstr);
|
defer delete(cstr);
|
||||||
return _unix_access(cstr, mask) == 0;
|
result := _unix_access(cstr, mask);
|
||||||
|
if result == -1 {
|
||||||
|
return false, Errno(get_last_error());
|
||||||
|
}
|
||||||
|
return true, ERROR_NONE;
|
||||||
}
|
}
|
||||||
|
|
||||||
heap_alloc :: proc(size: int) -> rawptr {
|
heap_alloc :: proc(size: int) -> rawptr {
|
||||||
@@ -281,8 +362,7 @@ nanosleep :: proc(nanoseconds: i64) -> int {
|
|||||||
}
|
}
|
||||||
|
|
||||||
current_thread_id :: proc "contextless" () -> int {
|
current_thread_id :: proc "contextless" () -> int {
|
||||||
// return int(_unix_gettid());
|
return syscall(SYS_GETTID);
|
||||||
return 0;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
dlopen :: inline proc(filename: string, flags: int) -> rawptr {
|
dlopen :: inline proc(filename: string, flags: int) -> rawptr {
|
||||||
|
|||||||
+1
-1
@@ -157,7 +157,7 @@ open :: proc(path: string, flags: int = O_RDONLY, mode: int = 0) -> (Handle, Err
|
|||||||
handle := _unix_open(cstr, flags, mode);
|
handle := _unix_open(cstr, flags, mode);
|
||||||
delete(cstr);
|
delete(cstr);
|
||||||
if handle == -1 {
|
if handle == -1 {
|
||||||
return 0, 1;
|
return INVALID_HANDLE, 1;
|
||||||
}
|
}
|
||||||
return handle, 0;
|
return handle, 0;
|
||||||
}
|
}
|
||||||
|
|||||||
+16
-10
@@ -32,6 +32,7 @@ ERROR_NONE: Errno : 0;
|
|||||||
ERROR_FILE_NOT_FOUND: Errno : 2;
|
ERROR_FILE_NOT_FOUND: Errno : 2;
|
||||||
ERROR_PATH_NOT_FOUND: Errno : 3;
|
ERROR_PATH_NOT_FOUND: Errno : 3;
|
||||||
ERROR_ACCESS_DENIED: Errno : 5;
|
ERROR_ACCESS_DENIED: Errno : 5;
|
||||||
|
ERROR_INVALID_HANDLE: Errno : 6;
|
||||||
ERROR_NO_MORE_FILES: Errno : 18;
|
ERROR_NO_MORE_FILES: Errno : 18;
|
||||||
ERROR_HANDLE_EOF: Errno : 38;
|
ERROR_HANDLE_EOF: Errno : 38;
|
||||||
ERROR_NETNAME_DELETED: Errno : 64;
|
ERROR_NETNAME_DELETED: Errno : 64;
|
||||||
@@ -106,8 +107,11 @@ open :: proc(path: string, mode: int = O_RDONLY, perm: u32 = 0) -> (Handle, Errn
|
|||||||
return INVALID_HANDLE, err;
|
return INVALID_HANDLE, err;
|
||||||
}
|
}
|
||||||
|
|
||||||
close :: proc(fd: Handle) {
|
close :: proc(fd: Handle) -> Errno {
|
||||||
win32.close_handle(win32.Handle(fd));
|
if !win32.close_handle(win32.Handle(fd)) {
|
||||||
|
return Errno(win32.get_last_error());
|
||||||
|
}
|
||||||
|
return ERROR_NONE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -203,25 +207,27 @@ get_std_handle :: proc(h: int) -> Handle {
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
last_write_time :: proc(fd: Handle) -> File_Time {
|
last_write_time :: proc(fd: Handle) -> (File_Time, Errno) {
|
||||||
file_info: win32.By_Handle_File_Information;
|
file_info: win32.By_Handle_File_Information;
|
||||||
win32.get_file_information_by_handle(win32.Handle(fd), &file_info);
|
if !win32.get_file_information_by_handle(win32.Handle(fd), &file_info) {
|
||||||
|
return 0, Errno(win32.get_last_error());
|
||||||
|
}
|
||||||
lo := File_Time(file_info.last_write_time.lo);
|
lo := File_Time(file_info.last_write_time.lo);
|
||||||
hi := File_Time(file_info.last_write_time.hi);
|
hi := File_Time(file_info.last_write_time.hi);
|
||||||
return lo | hi << 32;
|
return lo | hi << 32, ERROR_NONE;
|
||||||
}
|
}
|
||||||
|
|
||||||
last_write_time_by_name :: proc(name: string) -> File_Time {
|
last_write_time_by_name :: proc(name: string) -> (File_Time, Errno) {
|
||||||
last_write_time: win32.Filetime;
|
last_write_time: win32.Filetime;
|
||||||
data: win32.File_Attribute_Data;
|
data: win32.File_Attribute_Data;
|
||||||
|
|
||||||
wide_path := win32.utf8_to_wstring(name);
|
wide_path := win32.utf8_to_wstring(name);
|
||||||
if win32.get_file_attributes_ex_w(wide_path, win32.GetFileExInfoStandard, &data) {
|
if !win32.get_file_attributes_ex_w(wide_path, win32.GetFileExInfoStandard, &data) {
|
||||||
last_write_time = data.last_write_time;
|
return 0, Errno(win32.get_last_error());
|
||||||
}
|
}
|
||||||
|
|
||||||
l := File_Time(last_write_time.lo);
|
l := File_Time(data.last_write_time.lo);
|
||||||
h := File_Time(last_write_time.hi);
|
h := File_Time(data.last_write_time.hi);
|
||||||
return l | h << 32;
|
return l | h << 32;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user