diff options
author | Stacey Son <sson@FreeBSD.org> | 2023-09-25 21:24:25 +0300 |
---|---|---|
committer | Warner Losh <imp@bsdimp.com> | 2023-10-03 17:14:06 -0600 |
commit | 6756ae283ac7fe43b8bbc1d8662dfe238f667032 (patch) | |
tree | 43dd9bcaffda500806c76432550f087bf0cd3c49 /bsd-user | |
parent | 510eecbc86e1aa93c17e9e0a3acced366b0258e1 (diff) |
bsd-user: Implement pdfork(2) system call.
Signed-off-by: Stacey Son <sson@FreeBSD.org>
Signed-off-by: Karim Taha <kariem.taha2.7@gmail.com>
Acked-by: Richard Henderson <richard.henderson@linaro.org>
Reviewed-by: Warner Losh <imp@bsdimp.com>
Message-Id: <20230925182425.3163-29-kariem.taha2.7@gmail.com>
Diffstat (limited to 'bsd-user')
-rw-r--r-- | bsd-user/freebsd/os-proc.h | 32 | ||||
-rw-r--r-- | bsd-user/freebsd/os-syscall.c | 4 |
2 files changed, 36 insertions, 0 deletions
diff --git a/bsd-user/freebsd/os-proc.h b/bsd-user/freebsd/os-proc.h index 0a3cd0ef57..d641878034 100644 --- a/bsd-user/freebsd/os-proc.h +++ b/bsd-user/freebsd/os-proc.h @@ -258,4 +258,36 @@ static inline abi_long do_freebsd_rfork(void *cpu_env, abi_long flags) } +/* pdfork(2) */ +static inline abi_long do_freebsd_pdfork(void *cpu_env, abi_ulong target_fdp, + abi_long flags) +{ + abi_long ret; + abi_ulong child_flag; + int fd; + + fork_start(); + ret = pdfork(&fd, flags); + if (ret == 0) { + /* child */ + child_flag = 1; + target_cpu_clone_regs(cpu_env, 0); + } else { + /* parent */ + child_flag = 0; + if (put_user_s32(fd, target_fdp)) { + return -TARGET_EFAULT; + } + } + + /* + * The fork system call sets a child flag in the second return + * value: 0 for parent process, 1 for child process. + */ + set_second_rval(cpu_env, child_flag); + fork_end(child_flag); + + return ret; +} + #endif /* BSD_USER_FREEBSD_OS_PROC_H */ diff --git a/bsd-user/freebsd/os-syscall.c b/bsd-user/freebsd/os-syscall.c index 4c4e773d1d..d04712f0a7 100644 --- a/bsd-user/freebsd/os-syscall.c +++ b/bsd-user/freebsd/os-syscall.c @@ -238,6 +238,10 @@ static abi_long freebsd_syscall(void *cpu_env, int num, abi_long arg1, ret = do_freebsd_rfork(cpu_env, arg1); break; + case TARGET_FREEBSD_NR_pdfork: /* pdfork(2) */ + ret = do_freebsd_pdfork(cpu_env, arg1, arg2); + break; + case TARGET_FREEBSD_NR_execve: /* execve(2) */ ret = do_freebsd_execve(arg1, arg2, arg3); break; |