diff options
-rw-r--r-- | lib/std/fmt.myr | 1 | ||||
-rw-r--r-- | lib/std/sys+linux-x64.myr | 8 | ||||
-rw-r--r-- | lib/std/syscall+linux-x64.s | 27 |
3 files changed, 36 insertions, 0 deletions
diff --git a/lib/std/fmt.myr b/lib/std/fmt.myr index b786e98..3bfcb44 100644 --- a/lib/std/fmt.myr +++ b/lib/std/fmt.myr @@ -30,6 +30,7 @@ pkg std = /* write to buffer */ const fmt : (fmt : byte[:], args : ... -> byte[:]) const fmtv : (fmt : byte[:], ap : valist# -> byte[:]) + const bfmt : (buf : byte[:], fmt : byte[:], args : ... -> byte[:]) const bfmtv : (buf : byte[:], fmt : byte[:], ap : valist# -> byte[:]) diff --git a/lib/std/sys+linux-x64.myr b/lib/std/sys+linux-x64.myr index 4860120..1f31532 100644 --- a/lib/std/sys+linux-x64.myr +++ b/lib/std/sys+linux-x64.myr @@ -593,6 +593,14 @@ pkg sys = const fork : (-> pid) /* FIXME: where the fuck is 'struct pt_reg' defined?? */ const clone : (flags : cloneopt, stk : byte#, ptid : pid#, ctid : pid#, ptreg : byte# -> pid) + extern const fnclone : ( flags : cloneopt, \ + stk : byte#, \ + ptid : pid#, \ + tls : byte#, \ + ctid : pid#, \ + ptreg : byte#, \ + fn : (-> void) \ + -> pid) const wait4 : (pid:pid, loc:int32#, opt : int64, usage:rusage# -> int64) const waitpid : (pid:pid, loc:int32#, opt : int64 -> int64) const execv : (cmd : byte[:], args : byte[:][:] -> int64) diff --git a/lib/std/syscall+linux-x64.s b/lib/std/syscall+linux-x64.s index f7c020d..53291cb 100644 --- a/lib/std/syscall+linux-x64.s +++ b/lib/std/syscall+linux-x64.s @@ -20,3 +20,30 @@ sys$syscall: ret +/* clone(flags, stack, ptid, tls, ctid, regs) */ +.globl sys$fnclone +sys$fnclone: + pushq %r15 + /* %rsp is modified by clone(), so it's saved here */ + movq 16(%rsp),%r15 + /* + %rdi: flags, %rsi: stack, %rdx: ptid, + %rcx: tls, %r8: ctid, %r9: regs + */ + movq $56,%rax /* syscall num */ + movq %rcx,%r10 /* tls */ + syscall + + /* fn() */ + testl %eax,%eax + jnz parent + call *%r15 + + /* exit(0) */ + movq $60, %rax /* exit */ + movq $0, %rdi /* arg: 0 */ + syscall + +parent: + popq %r15 + ret |