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 epoll
or 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 open
, write
, and 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 EINTR
-handling loops.
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.