libc


英文原文快照


当我们谈论libc时我们在谈论什么?

在Posix系统上,所有程序(无论动态还是静态方式)必需链接的库被称为libc。该库提供了标准C定义的函数,以及C程序运行所依赖的运行环境。除此之外,许多系统还在libc中定义了其他平台相关的接口,他们中的许多接口是获取内核功能的首选方式。例如,Posix系统的libc中有名为open的函数,它的主要功能就是进行open系统调用。libc中的一部分是跨平台的标准,例如pthread,而其他的是内核相关的功能,如epollkqueue等。在任何情况下,libc都存在于系统中,并且提供稳定的接口。相反,Windows操作系统并没有在它稳定的win32接口上提供全系统的libc。

而在Fuchsia操作系统上,情况和Posix系统有点不一样。首先,Zircon内核(Fuchsia的底层微内核)并未提供典型的Posix系统调用接口。因此,诸如open等Posix函数并不能直接进行open系统调用。其次,Fuchsia实现了部分的Posix函数,但是忽略了大部分的Posix模型。其中最显著的缺失是signal相关,fork和exec。再次,Fuchsia不要求程序使用libc的ABI接口,程序可以自由选择它们自己的libc,或完全不用libc。尽管如此,Fuchsia也提供了可供程序动态链接的libc.so,正如典型的Posix系统那样,libc.so同时实现了C标准库和Fuchsia所支持的那部分Posix函数,

一点一滴(译者注:Piece by piece是Kelly Clarkson的一张专辑名

下面是Fuchsia的libc所实现功能的(和未实现的)不完全列表。

C标准库

Fuchsia的libc实现了C11标准。特别地,它包含线程相关的接口,例如threads(thrd_t)和mutexes(mtx_t)。一小部分旨在桥接到C11的数据结构的系统扩展,也在这部分中。例如thrd_t,它实际上是桥接到底层的,诸如zx_handle_t这样的数据结构。

Posix

Posix定义了一部分的接口,包括(非完全):文件I/O,BSD socket和pthread。

文件I/O和BSD socket

这里再次重申Zircon是微内核,因此它不直接实现文件I/O部分,而是由其他Fuchsia用户态提供文件系统。libc它本身为Posix定义了这些文件I/O的符号,如openwritefstat等。但是,调用它们的所有操作将会失败。除了libc.so之外,程序可以链接到fdio.sofdio知道如何通过基于Channel的进程间通信和这些I/O相关的Fuchsia服务交互,并为libc暴露了和Posix相似的一层接口。类似地,socket也是通过fdio同用户空间网络栈通信的方式实现。

pthreads

Fuchsia的libc提供了部分的pthread标准。特别是提供了pthread_t的核心部分(即直接映射到C11相关的那些)和诸如pthread_mutex_t等同步原语。而像进程共享互斥量等细节却并未实现,因此Fuchsia实现的pthread子集并不全面。

Signals

Fuchsia中不包含Unix风格的信号,因为Zircon无法直接实现它们(内核没办法提供手段使得当前线程控制另一线程跳出其执行状态)。因此,Fuchsia的libc也不打算提供signal安全的功能,并且在实现时也不将signal等机制考虑在内。

基于这样的事实,libc的函数将无法产生EINTR(信号中断错误),仅包含基于Fuchsia的代码也不必考虑这种错误,相反即使考虑这种情况也是安全的。Fuchsia还是定义了EINTR变量,为Posix或Fuchsia而写的代码也同样可使用EINTR处理循环。

fork和exec

Zircon内核中没有fork和exec,进程的创建是由launchpad来提供支持。尽管Zircon中有Process和Thread对象,但它们是无格式的,并且和ELF无任何关系,launchpad知道如何将ELF和一些初始状态转变成运行的进程。