libc 是什么意思?
在 Posix-y 系统上,程序会链接到一个名为 libc 的库(动态或静态)。此库提供了 C 标准定义的函数,以及 C 程序的运行时环境。许多系统还会在同一库中定义其他平台专用接口。其中许多接口是用户空间访问内核功能的首选方式。例如,Posix-y 系统的 libc 中有一个 open
函数,该函数会调用 open
系统调用。有时,这些标准是跨平台标准,例如 pthread。另一些则是指向特定于内核的功能的接口,如 epoll
或 kqueue
。在任何情况下,该库都存在于系统本身中,并且是一个稳定的接口。相反,Windows 不会在其稳定的 win32 接口中提供系统级 libc。
在 Fuchsia 上,情况与 Posix 系统略有不同。首先,Zircon 内核(Fuchsia 的内核)不提供典型的 Posix 系统调用接口。因此,Posix 函数(如 open
)无法调用 Zircon open
系统调用。其次,Fuchsia 实现了 Posix 的某些部分,但省略了 Posix 模型的大部分内容。最明显的是信号、fork 和 exec。第三,Fuchsia 不要求程序使用 libc 的 ABI。程序可以自由使用自己的 libc,也可以不使用。不过,Fucsia 确实提供了 libc.so,以便程序可以动态链接,从而与典型的 Posix 系统一样,同时提供 C 标准库和 Posix Fuchsia 支持的部分的实现。
片头
这是在 Fuchsia 的 libc 中实现(或未实现)的部分列表。
C 标准库
Fuchsia 的 libc 实现了 C11 标准。具体而言,这包括与线程相关的接口,例如线程 (thrd_t
) 和互斥量 (mtx_t
)。系统的这部分还会提供少量扩展,用于将 C11 结构(例如 thrd_t
)桥接至底层内核结构(例如其底层的 zx_handle_t
)。
波西克斯
Posix 定义了许多接口。其中包括(并非详尽无遗):文件 I/O、BSD 套接字和 pthread。
文件 I/O 和 BSD 套接字
回想一下,Zircon 是一个不负责实现文件 I/O 的内核。不过,其他 Fuchsia 用户空间服务会提供文件系统。libc 本身为 Posix 文件 I/O 函数定义了弱符号,例如 open
、write
和 fstat
。但是,所有这些调用都会失败。除了 libc.so 之外,程序还可以关联 fdio.so 库。fdio 知道如何通过通道 IPC 与这些其他 Fuchsia 服务通信,并为 libc 提供一个类似于 Posix 的层。同样地,套接字通过与用户空间网络堆栈通信的 fdio 来实现。
pthread
Fuchsia 的 libc 提供了 pthread 标准的部分。尤其是 pthread_t
的核心部分(直接映射到相应的 C11 概念的部分)和同步基元(如 pthread_mutex_t
)。某些详细信息(如进程共享互斥锁)未实现。所实现的子集并不全面。
信号
Fuchsia 没有 Unix 样式的信号。Zircon 无法直接实现这些线程(内核不支持导致其他线程跳出其执行上下文)。因此,Fuchsia 的 libc 不具备信号安全函数的概念,也没有在内部实现以便了解信号等机制。
因此,libc 函数不会 EINTR
,并且仅适用于 Fuchsia 的代码没有必要考虑这种情况。不过,这样做完全是安全的。Fucsia 仍会定义 EINTR
常量,并且为 Posix 和 Fuchsia 编写的代码可能仍会包含 EINTR
处理循环。
fork 和 exec
Zircon 没有 fork 或 exec。相反,进程创建由 fdio 提供。虽然 Zircon 包含 Process 和 Thread 对象,但这些对象是原始的,对 ELF 一无所知。fdio_spawn
函数系列知道如何将 ELF 二进制文件和某些初始状态转换为正在运行的进程。