浏览代码

Get arm64 up to speed in os2 linux

Readded open flags for arm64 to sys/linux/bits.odin. Make process_start
name based instead of descriptor based to allow running of scripts. Fix
bug in heap_linux. Fix and simplify os2.remove.
jason 8 月之前
父节点
当前提交
b73275cf42
共有 4 个文件被更改,包括 74 次插入93 次删除
  1. 3 19
      core/os/os2/file_linux.odin
  2. 1 1
      core/os/os2/heap_linux.odin
  3. 11 36
      core/os/os2/process_linux.odin
  4. 59 37
      core/sys/linux/bits.odin

+ 3 - 19
core/os/os2/file_linux.odin

@@ -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})
-	#partial switch (errno) {
-	case .ELOOP:
-		/* 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)
+	if fd, errno := linux.open(name_cstr, _OPENDIR_FLAGS); errno == .NONE {
+		linux.close(fd)
+		return _get_platform_error(linux.rmdir(name_cstr))
 	}
 	}
 
 
 	return _get_platform_error(linux.unlink(name_cstr))
 	return _get_platform_error(linux.unlink(name_cstr))

+ 1 - 1
core/os/os2/heap_linux.odin

@@ -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

+ 11 - 36
core/os/os2/process_linux.odin

@@ -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)
-			if exe_fd, errno = linux.openat(dir_fd, exe_path, {.PATH, .CLOEXEC}); errno != .NONE {
-				continue
-			}
-			if !has_executable_permissions(exe_fd) {
-				linux.close(exe_fd)
-				continue
+			exe_path = strings.to_cstring(&exe_builder)
+			if linux.access(exe_path, linux.X_OK) == .NONE {
+				found = true
+				break
 			}
 			}
-			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)
-			if exe_fd, errno = linux.openat(dir_fd, exe_path, {.PATH, .CLOEXEC}); errno != .NONE {
+			exe_path = strings.to_cstring(&exe_builder)
+			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
-		if exe_fd, errno = linux.openat(dir_fd, exe_path, {.PATH, .CLOEXEC}); errno != .NONE {
-			return process, _get_platform_error(errno)
-		}
-		if !has_executable_permissions(exe_fd) {
-			linux.close(exe_fd)
-			return process, .Permission_Denied
+		exe_path = temp_cstring(executable_name) or_return
+		if linux.access(exe_path, linux.X_OK) != .NONE {
+			return process, .Not_Exist
 		}
 		}
 	}
 	}
 
 
-	// 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)
 	}
 	}

+ 59 - 37
core/sys/linux/bits.odin

@@ -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 {
-	WRONLY    = 0,
-	RDWR      = 1,
-	CREAT     = 6,
-	EXCL      = 7,
-	NOCTTY    = 8,
-	TRUNC     = 9,
-	APPEND    = 10,
-	NONBLOCK  = 11,
-	DSYNC     = 12,
-	ASYNC     = 13,
-	DIRECT    = 14,
-	LARGEFILE = 15,
-	DIRECTORY = 16,
-	NOFOLLOW  = 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)
+when ODIN_ARCH != .arm64 && ODIN_ARCH != .arm32 {
+	Open_Flags_Bits :: enum {
+		WRONLY    = 0,
+		RDWR      = 1,
+		CREAT     = 6,
+		EXCL      = 7,
+		NOCTTY    = 8,
+		TRUNC     = 9,
+		APPEND    = 10,
+		NONBLOCK  = 11,
+		DSYNC     = 12,
+		ASYNC     = 13,
+		DIRECT    = 14,
+		LARGEFILE = 15,
+		DIRECTORY = 16,
+		NOFOLLOW  = 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)
+} 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,
+	}
+}
 
 
 /*
 /*
 	Bits for FD_Flags bitset
 	Bits for FD_Flags bitset