diff options
| author | PucklaJ <jonaas.pucher000000@gmail.com> | 2024-04-24 15:32:43 +0200 |
|---|---|---|
| committer | PucklaJ <jonaas.pucher000000@gmail.com> | 2024-04-24 15:32:43 +0200 |
| commit | a2ad66cd9d5e93ce8789d1a1e088b254922cd88f (patch) | |
| tree | d1432e1165e497e0ae38890b4b5df69ccad445c4 /core/sys/linux | |
| parent | 2bf00d9b3f5a694bdc6d8b2c76be7a278f02f40b (diff) | |
[sys/linux]: Add clone syscall and use it in fork for arm64
Diffstat (limited to 'core/sys/linux')
| -rw-r--r-- | core/sys/linux/sys.odin | 24 |
1 files changed, 19 insertions, 5 deletions
diff --git a/core/sys/linux/sys.odin b/core/sys/linux/sys.odin index 22fe2ab50..1653a65dd 100644 --- a/core/sys/linux/sys.odin +++ b/core/sys/linux/sys.odin @@ -729,7 +729,22 @@ getsockopt :: proc { getsockopt_base, } -// TODO(flysand): clone (probably not in this PR, maybe not ever) +/* + Creates a new ("child") process, in a manner similar to fork. + Available since Linux 1.0? (<2.4) + + Note(flysand): this syscall is not documented, but the bottom 8 bits of flags + are for exit signal +*/ +clone :: proc "contextless" (flags: u64, stack: rawptr, parent_tid, child_tid: ^i32, tls: u64) -> (i64, Errno) { + when ODIN_ARCH == .amd64 { + ret := syscall(SYS_clone, flags, stack, parent_tid, child_tid, tls) + return errno_unwrap(ret, i64) + } else { + ret := syscall(SYS_clone, flags, stack, parent_tid, tls, child_tid) + return errno_unwrap(ret, i64) + } +} /* Creates a copy of the running process. @@ -737,10 +752,9 @@ getsockopt :: proc { */ fork :: proc "contextless" () -> (Pid, Errno) { 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) - return errno_unwrap(ret, Pid) + ret, err := clone(u64(Signal.SIGCHLD), nil, nil, nil, 0) + if err != .NONE do return Pid(ret), err + return Pid(ret), .NONE } else { ret := syscall(SYS_fork) return errno_unwrap(ret, Pid) |