aboutsummaryrefslogtreecommitdiff
path: root/core/sys/linux
diff options
context:
space:
mode:
authorPucklaJ <jonaas.pucher000000@gmail.com>2024-04-24 15:32:43 +0200
committerPucklaJ <jonaas.pucher000000@gmail.com>2024-04-24 15:32:43 +0200
commita2ad66cd9d5e93ce8789d1a1e088b254922cd88f (patch)
treed1432e1165e497e0ae38890b4b5df69ccad445c4 /core/sys/linux
parent2bf00d9b3f5a694bdc6d8b2c76be7a278f02f40b (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.odin24
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)