Browse Source

Merge pull request #3476 from PucklaJ/syscall-fix

[sys/linux] Fix fork and execve syscalls on arm64
Laytan 1 year ago
parent
commit
73a9a97413
3 changed files with 17 additions and 8 deletions
  1. 8 0
      core/sys/linux/bits.odin
  2. 4 8
      core/sys/linux/sys.odin
  3. 5 0
      core/sys/linux/types.odin

+ 8 - 0
core/sys/linux/bits.odin

@@ -1815,3 +1815,11 @@ EPoll_Ctl_Opcode :: enum i32 {
 	DEL = 2,
 	DEL = 2,
 	MOD = 3,
 	MOD = 3,
 }
 }
+
+/*
+	Bits for execveat(2) flags.
+*/
+Execveat_Flags_Bits :: enum {
+	AT_SYMLINK_NOFOLLOW = 8,
+	AT_EMPTY_PATH       = 12,
+}

+ 4 - 8
core/sys/linux/sys.odin

@@ -749,17 +749,13 @@ getsockopt :: proc {
 	getsockopt_base,
 	getsockopt_base,
 }
 }
 
 
-// TODO(flysand): clone (probably not in this PR, maybe not ever)
-
 /*
 /*
 	Creates a copy of the running process.
 	Creates a copy of the running process.
 	Available since Linux 1.0.
 	Available since Linux 1.0.
 */
 */
 fork :: proc "contextless" () -> (Pid, Errno) {
 fork :: proc "contextless" () -> (Pid, Errno) {
 	when ODIN_ARCH == .arm64 {
 	when ODIN_ARCH == .arm64 {
-		// Note(flysand): this syscall is not documented, but the bottom 8 bits of flags
-		// are for exit signal
-		ret := syscall(SYS_clone, Signal.SIGCHLD)
+		ret := syscall(SYS_clone, u64(Signal.SIGCHLD), cast(rawptr) nil, cast(rawptr) nil, cast(rawptr) nil, u64(0))
 		return errno_unwrap(ret, Pid)
 		return errno_unwrap(ret, Pid)
 	} else {
 	} else {
 		ret := syscall(SYS_fork)
 		ret := syscall(SYS_fork)
@@ -789,8 +785,8 @@ execve :: proc "contextless" (name: cstring, argv: [^]cstring, envp: [^]cstring)
 		ret := syscall(SYS_execve, cast(rawptr) name, cast(rawptr) argv, cast(rawptr) envp)
 		ret := syscall(SYS_execve, cast(rawptr) name, cast(rawptr) argv, cast(rawptr) envp)
 		return Errno(-ret)
 		return Errno(-ret)
 	} else {
 	} else {
-		ret := syscall(SYS_execveat, AT_FDCWD, cast(rawptr) name, cast(rawptr) argv, cast(rawptr) envp)
-		return Errno(-ret)
+		ret := syscall(SYS_execveat, AT_FDCWD, cast(rawptr) name, cast(rawptr) argv, cast(rawptr) envp, i32(0))
+	 	return Errno(-ret)
 	}
 	}
 }
 }
 
 
@@ -2818,7 +2814,7 @@ getrandom :: proc "contextless" (buf: []u8, flags: Get_Random_Flags) -> (int, Er
 	Execute program relative to a directory file descriptor.
 	Execute program relative to a directory file descriptor.
 	Available since Linux 3.19.
 	Available since Linux 3.19.
 */
 */
-execveat :: proc "contextless" (dirfd: Fd, name: cstring, argv: [^]cstring, envp: [^]cstring, flags: FD_Flags = {}) -> (Errno) {
+execveat :: proc "contextless" (dirfd: Fd, name: cstring, argv: [^]cstring, envp: [^]cstring, flags: Execveat_Flags = {}) -> (Errno) {
 	ret := syscall(SYS_execveat, dirfd, cast(rawptr) name, cast(rawptr) argv, cast(rawptr) envp, transmute(i32) flags)
 	ret := syscall(SYS_execveat, dirfd, cast(rawptr) name, cast(rawptr) argv, cast(rawptr) envp, transmute(i32) flags)
 	return Errno(-ret)
 	return Errno(-ret)
 }
 }

+ 5 - 0
core/sys/linux/types.odin

@@ -1303,3 +1303,8 @@ EPoll_Event :: struct #packed {
 	events: EPoll_Event_Kind,
 	events: EPoll_Event_Kind,
 	data:   EPoll_Data,
 	data:   EPoll_Data,
 }
 }
+
+/*
+	Flags for execveat(2) syscall.
+*/
+Execveat_Flags :: bit_set[Execveat_Flags_Bits; i32]