On Posix-y systems, programs link against a library (either dynamically or statically) called libc. This library provides the functions defined by the C standard, as well as the runtime environment for C programs. Many systems also define other platform-specific interfaces in the same library. Many of these interfaces are the preferred way for userspace to access kernel functionality. For example, Posix-y systems have an
open function in their libc, which calls an
open system call. Sometimes these are cross-platform standards, such as pthreads. Others are interfaces to kernel-specific functionality, such as
kqueue. In any case, this library is present on the system itself and is a stable interface. In contrast, Windows does not provide a systemwide libc in its stable win32 interface.
On Fuchsia the story is a bit different from Posix systems. First, the Zircon kernel (Fuchsia‘s kernel) does not provide a typical Posix system call interface. So a Posix function like
open can’t call a Zircon
open syscall. Secondly, Fuchsia implements some parts of Posix, but omits large parts of the Posix model. Most conspicuously absent are signals, fork, and exec. Third, Fuchsia does not require that programs use libc's ABI. Programs are free to use their own libc, or to do without. However, Fuchsia does provide a libc.so that programs can dynamically link, which provides implementations both of the C standard library and of the parts of Posix Fuchsia supports, as typical Posix systems do.
This is a partial list of what is implemented (or not) in Fuchsia's libc.
Fuchsia's libc implements the C11 standard. In particular this includes the threading-related interfaces such as threads (
thrd_t) and mutexes (
mtx_t). A small handful of extensions are also in this portion of the system to bridge the C11 structures, like a
thrd_t, to underlying kernel structures, like the
zx_handle_t underlying it.
Posix defines a number of interfaces. These include (not exhaustively): file I/O, BSD sockets, and pthreads.
Recall that Zircon is a kernel that is not in the business of implementing file I/O. Instead, other Fuchsia userspace services provide filesystems. libc itself defines weak symbols for Posix file I/O functions such as
fstat. However, all these calls simply fail. In addition to libc.so, programs can link the fdio.so library. fdio knows how to speak to those other Fuchsia services over Channel IPC, and provides a Posix-like layer for libc to expose. Sockets are similarly implemented via fdio communicating with the userspace network stack.
Fuchsia's libc provides parts of the pthread standard. In particular, the core parts of
pthread_t (those that map straightforwardly onto the corresponding C11 concepts) and synchronization primitives like
pthread_mutex_t are provided. Some details, like process-shared mutexes, are not implemented. The implemented subset does not aim to be comprehensive.
Fuchsia does not have Unix-style signals. Zircon provides no way to directly implement them (the kernel provides no way to cause another thread to jump off its context of execution). Fuchsia's libc does not, therefore, have a notion of signal-safe functions, and is not implemented internally to be aware of mechanisms like signals.
Because of this fact, libc functions will not
EINTR, and it is not necessary for Fuchsia-only code to consider that case. However, it is perfectly safe to do so. Fuchsia still defines the
EINTR constant, and code written for both Posix and Fuchsia may still have
Zircon does not have fork or exec. Instead, process creation is provided by fdio. While Zircon has Process and Thread objects, these are pretty raw and know nothing about ELF. The
fdio_spawn function family knows how to turn an ELF binary and some initial state into a running process.