[libc-commits] [libc] [libc] Implement system function (PR #211672)

Jeff Bailey via libc-commits libc-commits at lists.llvm.org
Sat Aug 1 12:30:09 PDT 2026


================
@@ -0,0 +1,41 @@
+//===----------------------------------------------------------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+///
+/// \file
+/// Implementation header for fork.
+///
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_LIBC_SRC___SUPPORT_OSUTIL_SYSCALL_WRAPPERS_FORK_H
+#define LLVM_LIBC_SRC___SUPPORT_OSUTIL_SYSCALL_WRAPPERS_FORK_H
+
+#include "hdr/signal_macros.h"
+#include "hdr/types/pid_t.h"
+#include "src/__support/OSUtil/linux/syscall.h" // For syscall_checked
+#include "src/__support/common.h"
+#include "src/__support/error_or.h"
+#include "src/__support/macros/config.h"
+#include <sys/syscall.h> // For syscall numbers
+
+namespace LIBC_NAMESPACE_DECL {
+namespace linux_syscalls {
+
+LIBC_INLINE ErrorOr<pid_t> fork() {
+#ifdef SYS_fork
----------------
kaladron wrote:

Right - but it means fork the POSIX function, not necessarily the syscall.  If you look at src/unistd/linux/fork.cpp you can see that it does bunch of work for callbacks, setting up TID, etc.

clone3 is specifically designed to avoid problems that the fork syscall (and clone syscall) had in their design.  For our purposes, you want clone3 for a few things:

1) Passing flags like CLONE_CHILD_SETTID and CLONE_CHILD_CLEARTID in struct clone_args allows the kernel to set up the child's Thread Control Block (TCB) and Thread ID (TID) atomically before the child process executes any userspace instructions. This prevents signal handler race conditions where a child thread reads an un-updated parent TID.

2) Passing set_robust_list_head in clone3 avoids secondary set_robust_list syscalls post-fork, preventing mutex deadlocks if a child process terminates unexpectedly right after creation.

3) clone3 enables CLONE_PIDFD (immune to PID recycling race conditions) and CLONE_INTO_CGROUP (spawning child processes directly within sandbox cgroups without race windows).

And on top of this, if an newer arch doesn't support fork, you have to have two paths depending on the arch.  I think the right answer is not to provide the Linux fork syscall for our use and use clone3 for this and for fork.

https://github.com/llvm/llvm-project/pull/211672


More information about the libc-commits mailing list