mirror of
https://github.com/Ed94/Odin.git
synced 2026-08-05 15:18:49 +00:00
Merge pull request #4600 from jasonKercher/arm64-linux-fixes
Get arm64 up to speed in os2 linux
This commit is contained in:
@@ -272,28 +272,12 @@ _truncate :: proc(f: ^File, size: i64) -> Error {
|
|||||||
}
|
}
|
||||||
|
|
||||||
_remove :: proc(name: string) -> Error {
|
_remove :: proc(name: string) -> Error {
|
||||||
is_dir_fd :: proc(fd: linux.Fd) -> bool {
|
|
||||||
s: linux.Stat
|
|
||||||
if linux.fstat(fd, &s) != .NONE {
|
|
||||||
return false
|
|
||||||
}
|
|
||||||
return linux.S_ISDIR(s.mode)
|
|
||||||
}
|
|
||||||
|
|
||||||
TEMP_ALLOCATOR_GUARD()
|
TEMP_ALLOCATOR_GUARD()
|
||||||
name_cstr := temp_cstring(name) or_return
|
name_cstr := temp_cstring(name) or_return
|
||||||
|
|
||||||
fd, errno := linux.open(name_cstr, {.NOFOLLOW})
|
if fd, errno := linux.open(name_cstr, _OPENDIR_FLAGS); errno == .NONE {
|
||||||
#partial switch (errno) {
|
linux.close(fd)
|
||||||
case .ELOOP:
|
return _get_platform_error(linux.rmdir(name_cstr))
|
||||||
/* symlink */
|
|
||||||
case .NONE:
|
|
||||||
defer linux.close(fd)
|
|
||||||
if is_dir_fd(fd) {
|
|
||||||
return _get_platform_error(linux.rmdir(name_cstr))
|
|
||||||
}
|
|
||||||
case:
|
|
||||||
return _get_platform_error(errno)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return _get_platform_error(linux.unlink(name_cstr))
|
return _get_platform_error(linux.unlink(name_cstr))
|
||||||
|
|||||||
@@ -415,7 +415,7 @@ _region_resize :: proc(alloc: ^Allocation_Header, new_size: int, alloc_is_free_l
|
|||||||
back_idx := -1
|
back_idx := -1
|
||||||
idx: u16
|
idx: u16
|
||||||
infinite: for {
|
infinite: for {
|
||||||
for i := 0; i < len(region_iter.hdr.free_list); i += 1 {
|
for i := 0; i < int(region_iter.hdr.free_list_len); i += 1 {
|
||||||
idx = region_iter.hdr.free_list[i]
|
idx = region_iter.hdr.free_list[i]
|
||||||
if _get_block_count(region_iter.memory[idx]) >= new_block_count {
|
if _get_block_count(region_iter.memory[idx]) >= new_block_count {
|
||||||
break infinite
|
break infinite
|
||||||
|
|||||||
@@ -384,14 +384,6 @@ _Sys_Process_Attributes :: struct {}
|
|||||||
|
|
||||||
@(private="package")
|
@(private="package")
|
||||||
_process_start :: proc(desc: Process_Desc) -> (process: Process, err: Error) {
|
_process_start :: proc(desc: Process_Desc) -> (process: Process, err: Error) {
|
||||||
has_executable_permissions :: proc(fd: linux.Fd) -> bool {
|
|
||||||
backing: [48]u8
|
|
||||||
b := strings.builder_from_bytes(backing[:])
|
|
||||||
strings.write_string(&b, "/proc/self/fd/")
|
|
||||||
strings.write_int(&b, int(fd))
|
|
||||||
return linux.access(strings.to_cstring(&b), linux.X_OK) == .NONE
|
|
||||||
}
|
|
||||||
|
|
||||||
TEMP_ALLOCATOR_GUARD()
|
TEMP_ALLOCATOR_GUARD()
|
||||||
|
|
||||||
if len(desc.command) == 0 {
|
if len(desc.command) == 0 {
|
||||||
@@ -411,7 +403,7 @@ _process_start :: proc(desc: Process_Desc) -> (process: Process, err: Error) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// search PATH if just a plain name is provided
|
// search PATH if just a plain name is provided
|
||||||
exe_fd: linux.Fd
|
exe_path: cstring
|
||||||
executable_name := desc.command[0]
|
executable_name := desc.command[0]
|
||||||
if strings.index_byte(executable_name, '/') < 0 {
|
if strings.index_byte(executable_name, '/') < 0 {
|
||||||
path_env := get_env("PATH", temp_allocator())
|
path_env := get_env("PATH", temp_allocator())
|
||||||
@@ -426,16 +418,11 @@ _process_start :: proc(desc: Process_Desc) -> (process: Process, err: Error) {
|
|||||||
strings.write_byte(&exe_builder, '/')
|
strings.write_byte(&exe_builder, '/')
|
||||||
strings.write_string(&exe_builder, executable_name)
|
strings.write_string(&exe_builder, executable_name)
|
||||||
|
|
||||||
exe_path := strings.to_cstring(&exe_builder)
|
exe_path = strings.to_cstring(&exe_builder)
|
||||||
if exe_fd, errno = linux.openat(dir_fd, exe_path, {.PATH, .CLOEXEC}); errno != .NONE {
|
if linux.access(exe_path, linux.X_OK) == .NONE {
|
||||||
continue
|
found = true
|
||||||
|
break
|
||||||
}
|
}
|
||||||
if !has_executable_permissions(exe_fd) {
|
|
||||||
linux.close(exe_fd)
|
|
||||||
continue
|
|
||||||
}
|
|
||||||
found = true
|
|
||||||
break
|
|
||||||
}
|
}
|
||||||
if !found {
|
if !found {
|
||||||
// check in cwd to match windows behavior
|
// check in cwd to match windows behavior
|
||||||
@@ -443,29 +430,18 @@ _process_start :: proc(desc: Process_Desc) -> (process: Process, err: Error) {
|
|||||||
strings.write_string(&exe_builder, "./")
|
strings.write_string(&exe_builder, "./")
|
||||||
strings.write_string(&exe_builder, executable_name)
|
strings.write_string(&exe_builder, executable_name)
|
||||||
|
|
||||||
exe_path := strings.to_cstring(&exe_builder)
|
exe_path = strings.to_cstring(&exe_builder)
|
||||||
if exe_fd, errno = linux.openat(dir_fd, exe_path, {.PATH, .CLOEXEC}); errno != .NONE {
|
if linux.access(exe_path, linux.X_OK) != .NONE {
|
||||||
return process, .Not_Exist
|
return process, .Not_Exist
|
||||||
}
|
}
|
||||||
if !has_executable_permissions(exe_fd) {
|
|
||||||
linux.close(exe_fd)
|
|
||||||
return process, .Permission_Denied
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
exe_path := temp_cstring(executable_name) or_return
|
exe_path = temp_cstring(executable_name) or_return
|
||||||
if exe_fd, errno = linux.openat(dir_fd, exe_path, {.PATH, .CLOEXEC}); errno != .NONE {
|
if linux.access(exe_path, linux.X_OK) != .NONE {
|
||||||
return process, _get_platform_error(errno)
|
return process, .Not_Exist
|
||||||
}
|
|
||||||
if !has_executable_permissions(exe_fd) {
|
|
||||||
linux.close(exe_fd)
|
|
||||||
return process, .Permission_Denied
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// At this point, we have an executable.
|
|
||||||
defer linux.close(exe_fd)
|
|
||||||
|
|
||||||
// args and environment need to be a list of cstrings
|
// args and environment need to be a list of cstrings
|
||||||
// that are terminated by a nil pointer.
|
// that are terminated by a nil pointer.
|
||||||
cargs := make([]cstring, len(desc.command) + 1, temp_allocator()) or_return
|
cargs := make([]cstring, len(desc.command) + 1, temp_allocator()) or_return
|
||||||
@@ -492,7 +468,6 @@ _process_start :: proc(desc: Process_Desc) -> (process: Process, err: Error) {
|
|||||||
}
|
}
|
||||||
defer linux.close(child_pipe_fds[READ])
|
defer linux.close(child_pipe_fds[READ])
|
||||||
|
|
||||||
|
|
||||||
// TODO: This is the traditional textbook implementation with fork.
|
// TODO: This is the traditional textbook implementation with fork.
|
||||||
// A more efficient implementation with vfork:
|
// A more efficient implementation with vfork:
|
||||||
//
|
//
|
||||||
@@ -573,7 +548,7 @@ _process_start :: proc(desc: Process_Desc) -> (process: Process, err: Error) {
|
|||||||
write_errno_to_parent_and_abort(child_pipe_fds[WRITE], errno)
|
write_errno_to_parent_and_abort(child_pipe_fds[WRITE], errno)
|
||||||
}
|
}
|
||||||
|
|
||||||
errno = linux.execveat(exe_fd, "", &cargs[0], env, {.AT_EMPTY_PATH})
|
errno = linux.execveat(dir_fd, exe_path, &cargs[0], env)
|
||||||
assert(errno != nil)
|
assert(errno != nil)
|
||||||
write_errno_to_parent_and_abort(child_pipe_fds[WRITE], errno)
|
write_errno_to_parent_and_abort(child_pipe_fds[WRITE], errno)
|
||||||
}
|
}
|
||||||
|
|||||||
+58
-36
@@ -152,43 +152,65 @@ Errno :: enum i32 {
|
|||||||
RDONLY flag is not present, because it has the value of 0, i.e. it is the
|
RDONLY flag is not present, because it has the value of 0, i.e. it is the
|
||||||
default, unless WRONLY or RDWR is specified.
|
default, unless WRONLY or RDWR is specified.
|
||||||
*/
|
*/
|
||||||
Open_Flags_Bits :: enum {
|
when ODIN_ARCH != .arm64 && ODIN_ARCH != .arm32 {
|
||||||
WRONLY = 0,
|
Open_Flags_Bits :: enum {
|
||||||
RDWR = 1,
|
WRONLY = 0,
|
||||||
CREAT = 6,
|
RDWR = 1,
|
||||||
EXCL = 7,
|
CREAT = 6,
|
||||||
NOCTTY = 8,
|
EXCL = 7,
|
||||||
TRUNC = 9,
|
NOCTTY = 8,
|
||||||
APPEND = 10,
|
TRUNC = 9,
|
||||||
NONBLOCK = 11,
|
APPEND = 10,
|
||||||
DSYNC = 12,
|
NONBLOCK = 11,
|
||||||
ASYNC = 13,
|
DSYNC = 12,
|
||||||
DIRECT = 14,
|
ASYNC = 13,
|
||||||
LARGEFILE = 15,
|
DIRECT = 14,
|
||||||
DIRECTORY = 16,
|
LARGEFILE = 15,
|
||||||
NOFOLLOW = 17,
|
DIRECTORY = 16,
|
||||||
NOATIME = 18,
|
NOFOLLOW = 17,
|
||||||
CLOEXEC = 19,
|
NOATIME = 18,
|
||||||
PATH = 21,
|
CLOEXEC = 19,
|
||||||
|
PATH = 21,
|
||||||
|
}
|
||||||
|
// https://github.com/torvalds/linux/blob/7367539ad4b0f8f9b396baf02110962333719a48/include/uapi/asm-generic/fcntl.h#L19
|
||||||
|
#assert(1 << uint(Open_Flags_Bits.WRONLY) == 0o0000000_1)
|
||||||
|
#assert(1 << uint(Open_Flags_Bits.RDWR) == 0o0000000_2)
|
||||||
|
#assert(1 << uint(Open_Flags_Bits.CREAT) == 0o00000_100)
|
||||||
|
#assert(1 << uint(Open_Flags_Bits.EXCL) == 0o00000_200)
|
||||||
|
#assert(1 << uint(Open_Flags_Bits.NOCTTY) == 0o00000_400)
|
||||||
|
#assert(1 << uint(Open_Flags_Bits.TRUNC) == 0o0000_1000)
|
||||||
|
#assert(1 << uint(Open_Flags_Bits.APPEND) == 0o0000_2000)
|
||||||
|
#assert(1 << uint(Open_Flags_Bits.NONBLOCK) == 0o0000_4000)
|
||||||
|
#assert(1 << uint(Open_Flags_Bits.DSYNC) == 0o000_10000)
|
||||||
|
#assert(1 << uint(Open_Flags_Bits.ASYNC) == 0o000_20000)
|
||||||
|
#assert(1 << uint(Open_Flags_Bits.DIRECT) == 0o000_40000)
|
||||||
|
#assert(1 << uint(Open_Flags_Bits.LARGEFILE) == 0o00_100000)
|
||||||
|
#assert(1 << uint(Open_Flags_Bits.DIRECTORY) == 0o00_200000)
|
||||||
|
#assert(1 << uint(Open_Flags_Bits.NOFOLLOW) == 0o00_400000)
|
||||||
|
#assert(1 << uint(Open_Flags_Bits.NOATIME) == 0o0_1000000)
|
||||||
|
#assert(1 << uint(Open_Flags_Bits.CLOEXEC) == 0o0_2000000)
|
||||||
|
#assert(1 << uint(Open_Flags_Bits.PATH) == 0o_10000000)
|
||||||
|
} else {
|
||||||
|
Open_Flags_Bits :: enum {
|
||||||
|
WRONLY = 0,
|
||||||
|
RDWR = 1,
|
||||||
|
CREAT = 6,
|
||||||
|
EXCL = 7,
|
||||||
|
NOCTTY = 8,
|
||||||
|
TRUNC = 9,
|
||||||
|
APPEND = 10,
|
||||||
|
NONBLOCK = 11,
|
||||||
|
DSYNC = 12,
|
||||||
|
ASYNC = 13,
|
||||||
|
DIRECTORY = 14,
|
||||||
|
NOFOLLOW = 15,
|
||||||
|
DIRECT = 16,
|
||||||
|
LARGEFILE = 17,
|
||||||
|
NOATIME = 18,
|
||||||
|
CLOEXEC = 19,
|
||||||
|
PATH = 21,
|
||||||
|
}
|
||||||
}
|
}
|
||||||
// https://github.com/torvalds/linux/blob/7367539ad4b0f8f9b396baf02110962333719a48/include/uapi/asm-generic/fcntl.h#L19
|
|
||||||
#assert(1 << uint(Open_Flags_Bits.WRONLY) == 0o0000000_1)
|
|
||||||
#assert(1 << uint(Open_Flags_Bits.RDWR) == 0o0000000_2)
|
|
||||||
#assert(1 << uint(Open_Flags_Bits.CREAT) == 0o00000_100)
|
|
||||||
#assert(1 << uint(Open_Flags_Bits.EXCL) == 0o00000_200)
|
|
||||||
#assert(1 << uint(Open_Flags_Bits.NOCTTY) == 0o00000_400)
|
|
||||||
#assert(1 << uint(Open_Flags_Bits.TRUNC) == 0o0000_1000)
|
|
||||||
#assert(1 << uint(Open_Flags_Bits.APPEND) == 0o0000_2000)
|
|
||||||
#assert(1 << uint(Open_Flags_Bits.NONBLOCK) == 0o0000_4000)
|
|
||||||
#assert(1 << uint(Open_Flags_Bits.DSYNC) == 0o000_10000)
|
|
||||||
#assert(1 << uint(Open_Flags_Bits.ASYNC) == 0o000_20000)
|
|
||||||
#assert(1 << uint(Open_Flags_Bits.DIRECT) == 0o000_40000)
|
|
||||||
#assert(1 << uint(Open_Flags_Bits.LARGEFILE) == 0o00_100000)
|
|
||||||
#assert(1 << uint(Open_Flags_Bits.DIRECTORY) == 0o00_200000)
|
|
||||||
#assert(1 << uint(Open_Flags_Bits.NOFOLLOW) == 0o00_400000)
|
|
||||||
#assert(1 << uint(Open_Flags_Bits.NOATIME) == 0o0_1000000)
|
|
||||||
#assert(1 << uint(Open_Flags_Bits.CLOEXEC) == 0o0_2000000)
|
|
||||||
#assert(1 << uint(Open_Flags_Bits.PATH) == 0o_10000000)
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
Bits for FD_Flags bitset
|
Bits for FD_Flags bitset
|
||||||
|
|||||||
Reference in New Issue
Block a user