diff --git a/Source/Tools/LinuxEmulation/LinuxSyscalls/Syscalls.cpp b/Source/Tools/LinuxEmulation/LinuxSyscalls/Syscalls.cpp index 9541471059..bcb92096a7 100644 --- a/Source/Tools/LinuxEmulation/LinuxSyscalls/Syscalls.cpp +++ b/Source/Tools/LinuxEmulation/LinuxSyscalls/Syscalls.cpp @@ -583,7 +583,7 @@ uint64_t CloneHandler(FEXCore::Core::CpuStateFrame* Frame, FEX::HLE::clone3_args return false; } } else { - if (AnyFlagsSet(args->args.flags, CLONE_SYSVSEM | CLONE_FS | CLONE_FILES | CLONE_SIGHAND | CLONE_VM)) { + if (AnyFlagsSet(args->args.flags, CLONE_SYSVSEM | CLONE_SIGHAND | CLONE_VM)) { // CLONE_VM is particularly nasty here // Memory regions at the point of clone(More similar to a fork) are shared LogMan::Msg::IFmt("clone: Unsupported flags w/o CLONE_THREAD (Shared Resources), {:X}", args->args.flags); diff --git a/Source/Tools/LinuxEmulation/LinuxSyscalls/Syscalls/Thread.cpp b/Source/Tools/LinuxEmulation/LinuxSyscalls/Syscalls/Thread.cpp index 0a1178019b..7f2313b03e 100644 --- a/Source/Tools/LinuxEmulation/LinuxSyscalls/Syscalls/Thread.cpp +++ b/Source/Tools/LinuxEmulation/LinuxSyscalls/Syscalls/Thread.cpp @@ -26,6 +26,7 @@ tags: LinuxSyscalls|syscalls-shared #include #include #include +#include #include #include #include @@ -228,6 +229,15 @@ uint64_t HandleNewClone(FEX::HLE::ThreadStateObject* Thread, FEXCore::Context::C return Thread->Thread->StatusCode; } +static int Clone3Fork(uint32_t flags) { + struct clone_args cl_args = { + .flags = (flags & (CLONE_FS | CLONE_FILES)), + .exit_signal = SIGCHLD, + }; + + return syscall(SYS_clone3, cl_args, sizeof(cl_args)); +} + uint64_t ForkGuest(FEXCore::Core::InternalThreadState* Thread, FEXCore::Core::CpuStateFrame* Frame, uint32_t flags, void* stack, size_t StackSize, pid_t* parent_tid, pid_t* child_tid, void* tls) { // Just before we fork, we lock all syscall mutexes so that both processes will end up with a locked mutex @@ -248,7 +258,7 @@ uint64_t ForkGuest(FEXCore::Core::InternalThreadState* Thread, FEXCore::Core::Cp // XXX: We don't currently support a real `vfork` as it causes problems. // Currently behaves like a fork (with wait after the fact), which isn't correct. Need to find where the problem is - Result = fork(); + Result = Clone3Fork(flags); if (Result == 0) { // Close the read end of the pipe. @@ -259,7 +269,7 @@ uint64_t ForkGuest(FEXCore::Core::InternalThreadState* Thread, FEXCore::Core::Cp close(VForkFDs[1]); } } else { - Result = fork(); + Result = Clone3Fork(flags); } const bool IsChild = Result == 0;