在Posix系统上,所有程序(无论动态还是静态方式)必需链接的库被称为libc。该库提供了标准C定义的函数,以及C程序运行所依赖的运行环境。除此之外,许多系统还在libc中定义了其他平台相关的接口,他们中的许多接口是获取内核功能的首选方式。例如,Posix系统的libc中有名为open
的函数,它的主要功能就是进行open
系统调用。libc中的一部分是跨平台的标准,例如pthread
,而其他的是内核相关的功能,如epoll
或kqueue
等。在任何情况下,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函数,
下面是Fuchsia的libc所实现功能的(和未实现的)不完全列表。
Fuchsia的libc实现了C11标准。特别地,它包含线程相关的接口,例如threads(thrd_t
)和mutexes(mtx_t
)。一小部分旨在桥接到C11的数据结构的系统扩展,也在这部分中。例如thrd_t
,它实际上是桥接到底层的,诸如zx_handle_t
这样的数据结构。
Posix定义了一部分的接口,包括(非完全):文件I/O,BSD socket和pthread。
这里再次重申Zircon是微内核,因此它不直接实现文件I/O部分,而是由其他Fuchsia用户态提供文件系统。libc它本身为Posix定义了这些文件I/O的符号,如open
,write
和fstat
等。但是,调用它们的所有操作将会失败。除了libc.so之外,程序可以链接到fdio.so
。fdio
知道如何通过基于Channel的进程间通信和这些I/O相关的Fuchsia服务交互,并为libc暴露了和Posix相似的一层接口。类似地,socket也是通过fdio同用户空间网络栈通信的方式实现。
Fuchsia的libc提供了部分的pthread标准。特别是提供了pthread_t
的核心部分(即直接映射到C11相关的那些)和诸如pthread_mutex_t
等同步原语。而像进程共享互斥量等细节却并未实现,因此Fuchsia实现的pthread子集并不全面。
Fuchsia中不包含Unix风格的信号,因为Zircon无法直接实现它们(内核没办法提供手段使得当前线程控制另一线程跳出其执行状态)。因此,Fuchsia的libc也不打算提供signal安全的功能,并且在实现时也不将signal等机制考虑在内。
基于这样的事实,libc的函数将无法产生EINTR
(信号中断错误),仅包含基于Fuchsia的代码也不必考虑这种错误,相反即使考虑这种情况也是安全的。Fuchsia还是定义了EINTR
变量,为Posix或Fuchsia而写的代码也同样可使用EINTR
处理循环。
Zircon内核中没有fork和exec,进程的创建是由launchpad来提供支持。尽管Zircon中有Process和Thread对象,但它们是无格式的,并且和ELF无任何关系,launchpad知道如何将ELF和一些初始状态转变成运行的进程。