glibc 知:手册01:介绍

本文介绍了GNU C库,涵盖ISOC、POSIX标准兼容性,以及使用库的入门、标准库函数、安全特性、伯克利Unix和SystemV接口。涵盖了头文件、函数宏定义、保留名称和功能测试等内容,帮助开发者理解和使用库工具进行程序开发。

1. 前言

The GNU C Library Reference Manual for version 2.35

2. 介绍

Introduction

C 语言没有提供用于执行诸如输入/输出、内存管理、字符串操作等常见操作的内置工具。相反,这些设施是在标准库中定义的,您可以编译并链接到您的程序。

本文档中描述的 GNU C 库定义了 ISO C 标准指定的所有库函数,以及特定于 POSIX 和其它 Unix 操作系统衍生产品的附加功能,以及特定于 GNU 系统的扩展。

本手册的目的是告诉您如何使用 GNU C 库的工具。我们已经提到了哪些功能属于哪些标准,以帮助您识别可能无法移植到其它系统的事物。但本手册的重点并不是严格的可移植性。

2.1. 入门

Getting Started

编写本手册的前提是您至少对 C 编程语言和基本编程概念有所熟悉。具体来说,假定熟悉 ISO 标准 C(参见ISO C),而不是“传统的” pre-ISO C 方言。

GNU C 库包括几个头文件,每个头文件都为一组相关工具提供定义和声明;C 编译器在处理您的程序时会使用此信息。比如头文件 stdio.h 声明执行输入和输出的设施,以及头文件 string.h 声明字符串处理实用程序。本手册的组织结构一般与头文件相同。

如果您是第一次阅读本手册,您应该阅读所有介绍材料并略读其余章节。GNU C 库中有很多函数,期望您能够准确记住如何使用每一个函数是不现实的。熟悉库提供的各种设施更为重要,这样当您编写程序时,您可以识别何时使用库函数,以及在本手册中的何处可以找到有关它们的更具体信息。

2.2. 标准和可移植性

Standards and Portability

本节讨论 GNU C 库所基于的各种标准和其它来源。这些来源包括 ISO C 和 POSIX 标准,以及 System V 和 Berkeley Unix 实现。

本手册的主要重点是告诉您如何有效地使用 GNU C 库工具。但是,如果您担心使您的程序与这些标准兼容,或者可移植到 GNU 以外的操作系统,这可能会影响您使用该库的方式。本节概述了这些标准,以便在手册的其它部分提到它们时了解它们是什么。

请参阅库设施摘要,以获取库提供的功能和其它符号的字母列表。该列表还说明了每个功能或符号来自哪些标准。

2.2.1. ISO C

GNU C 库与美国国家标准协会 (ANSI) 采用的 C 标准兼容:美国国家标准 X3.159-1989 —“ANSI C” 以及后来的国际标准化组织 (ISO):ISO/IEC 9899:1990,“编程语言——C”。我们在这里将标准称为 ISO C ,因为这是关于批准的更通用的标准。构成 GNU C 库的头文件和库工具是 ISO C标准 指定的那些的超集。

如果您担心严格遵守 ISO C标准,当您用 GNU C 编译器编译您的程序时,使用 ‘-ansi’ 选项。这告诉编译器只定义库头文件中的 ISO 标准功能,除非您明确要求附加功能。有关如何执行此操作的信息,请参阅功能测试宏

能够将库限制为仅包含 ISO C 功能很重要,因为 ISO C 限制了库实现可以定义的名称,而 GNU 扩展不符合这些限制。有关这些限制的更多信息,请参阅保留名称

本手册并未尝试为您提供有关 ISO C 和旧方言(older dialects)之间差异的完整详细信息。它提供了有关如何编写程序以在多种 C 方言下可移植性工作的建议,但并不旨在完整性。

2.2.2. POSIX(可移植操作系统接口)

POSIX (The Portable Operating System Interfac)

GNU C 库还与 ISO POSIX系列标准兼容,更正式地称为计算机环境的可移植操作系统接口(ISO/IEC 9945)。它们还以 ANSI/IEEE Std 1003 的形式发布。POSIX 主要来源于各种版本的 Unix 操作系统。

POSIX 标准规定的库设施是 ISO C 要求的库设施的超集;POSIX 为 ISO C函数指定了附加特性,并指定了新的附加函数。一般来说,POSIX 标准定义的附加要求和功能旨在为特定类型的操作系统环境提供较低级别的支持,而不是可以在许多不同操作系统环境中运行的通用编程语言支持。

GNU C 库实现了 ISO/IEC 9945-1:1996 中指定的所有功能,即 POSIX 系统应用程序接口,通常称为 POSIX.1。本标准规定的 ISO C 工具的主要扩展包括文件系统接口原语(参见文件系统接口)、特定于设备的终端控制功能(参见底层终端接口)和进程控制功能(参见进程)。

一些来自 ISO/IEC 9945-2:1993 的工具,POSIX Shell and Utilities 标准(POSIX.2) 也在 GNU C 库中实现。其中包括处理正则表达式的实用程序和其它模式匹配工具(请参阅模式匹配)。

2.2.2.1. POSIX 安全概念

POSIX Safety Concepts

本手册记录了 GNU C 库函数的各种安全属性,它们遵循它们的原型,如下所示:

Preliminary: | MT-Safe | AS-Safe | AC-Safe |

这些属性是根据 POSIX 标准中针对线程安全、异步信号安全和异步取消安全等安全上下文中规定的标准进行评估的。这些属性的直观定义,试图捕捉标准定义的含义,如下。

  • MT-Safe 或 Thread-Safe 函数在存在其它线程的情况下可以安全调用。MT-Safe 中的 MT 代表多线程。

    MT-Safe 并不意味着函数是原子的,也不意味着它使用 POSIX 向用户公开的任何内存同步机制。甚至有可能按顺序调用 MT-Safe 函数不会产生 MT-Safe 组合。例如,让一个线程一个接一个地调用两个 MT-Safe 函数并不能保证等同于原子执行这两个函数的组合的行为,因为其它线程中的并发调用可能会以破坏性方式干扰。

    可以跨库接口内联函数的整个程序优化可能会暴露不安全的重新排序,因此不建议跨 GNU C 库接口执行内联。在整个程序优化下,不保证记录的 MT-Safety 状态。但是,在用户可见的头文件中定义的函数被设计为内联安全。

  • AS-Safe 或 Async-Signal-Safe 函数可以安全地从异步信号处理程序中调用。AS-Safe 中的 AS 代表异步信号。

    许多 AS 安全的函数可以设置errno或修改浮点环境,因为这样做不会使它们不适合在信号处理程序中使用。但是,如果异步信号处理程序修改此线程本地状态,程序可能会出现异常行为,并且不能指望信号处理机制来保留它。因此,调用可能设置errno或修改浮点环境的函数的信号处理程序必须保存它们的原始值,并在返回之前恢复它们。

  • AC-Safe 或 Async-Cancel-Safe 函数在启用异步取消时可以安全调用。AC-Safe 中的 AC 代表异步取消。

    POSIX 标准仅定义了三个 AC 安全功能,即 pthread_cancel、pthread_setcancelstate 和 pthread_setcanceltype。目前,GNU C 库不提供这三个函数之外的保证,但会记录哪些函数目前是 AC 安全的。本文档供 GNU C 库开发人员使用。

    就像信号处理程序一样,取消清除例程必须配置它们所需的浮点环境。例程不能假设浮点环境,尤其是在启用异步取消时。如果浮点环境的配置不能原子执行,那么也有可能遇到的环境内部不一致。

  • MT-Unsafe, AS-Unsafe, AC-Unsafe 函数在上述安全上下文中调用是不安全的。在这样的上下文中调用它们会调用未定义的行为。

    在安全上下文中未明确记录为安全的功能应被视为不安全的。

  • Preliminary 安全属性,表明在 GNU C 库的未来版本中可能不会依赖这些属性。

    这些初步(Preliminary)属性是对我们当前实施的属性进行评估的结果,而不是当前和未来标准强制和允许的结果。

    尽管我们努力遵守标准,但在某些情况下,即使标准不要求安全,我们的实施也是安全的,而在其他情况下,我们的实施不符合标准的安全要求。后者最有可能是缺陷;前者,当标记为 Preliminary 时,不应指望:未来的标准可能需要与当前实施提供的额外安全特性不兼容的更改。

    此外,POSIX 标准没有提供安全的详细定义。我们假设,通过“调用安全”,POSIX 意味着,只要程序不调用未定义的行为,“调用安全”函数的行为就如指定的那样,并且不会导致其它函数偏离它们指定的行为。我们选择使用其松散的安全定义,不是因为它们是最好的定义,而是因为选择它们可以使本手册与 POSIX 保持一致。

    请记住,这些是初步定义和注释,定义的某些方面仍在讨论中,可能需要澄清或更改。

    随着时间的推移,我们设想将初步的安全说明演变成稳定的承诺,就像我们的接口一样稳定。正如我们所做的那样,我们将从安全说明中删除 Preliminary 关键字。然而,只要关键字仍然存在,它们就不能被视为对未来行为的承诺。

出现在安全说明中的其它关键字在后续部分中定义。

2.2.2.2. 不安全特性

Unsafe Features

在某些上下文中调用不安全的函数使用关键字进行注释,这些关键字记录了它们使调用不安全的特性。本节中的 AS-Unsafe 特性表明,当启用异步信号时,函数永远不会安全调用。AC-Unsafe 特性表明在启用异步取消时调用它们永远不会安全。本节中没有 MT-Unsafe 标记。

  • lock

    标记 lock 作为 AS-Unsafe 特性的函数可能会在持有非递归锁时被信号中断。如果信号处理程序调用另一个采用相同锁的此类函数,则结果是死锁。

    注释 lock 作为 AC-Unsafe 特性的函数如果被异步取消,则可能无法释放锁(如果它们的执行没有被异步线程取消中断时,本应被释放的锁)。一旦一个锁被占用,尝试占用该锁将无限期地阻塞。

  • corrupt

    标记 corrupt 作为 AS-Unsafe 特性的函数可能会损坏数据结构并在它们中断或被另一个此类函数中断时出现异常行为。与标记为 lock 的函数不同,这些函数采用递归锁来避免 MT-Safety 问题,但这不足以阻止信号处理程序观察部分更新的数据结构。被中断的函数未能注意到信号处理程序所做的更新可能会导致进一步的损坏。

    标记 corrupt 作为 AC-Unsafe 特性的函数可能会使数据结构处于损坏的、部分更新的状态。数据结构的后续使用可能行为不端。

  • heap

    标有 heap 的函数可以调用 malloc/free 系列函数中的堆内存管理函数,并且仅与这些函数一样安全。因此,此注释等效于:

    | AS-Unsafe lock | AC-Unsafe lock fd mem |

  • dlopen

    标有 dlopen 的函数使用动态加载器将共享库加载到当前执行映像中。这包括打开文件、将它们映射到内存、分配额外的内存、解析符号、应用重定位等等,所有这些都同时持有内部动态加载器锁。

    这些锁足以使这些功能成为 AS- 和 AC-Unsafe,但可能会出现其他问题。目前这是 dlopen 提出的所有潜在安全问题的占位符。

  • plugin

    使用 plugin 注解的函数可以运行来自可能在 GNU C 库外部的插件的代码。此类插件功能被假定为 MT-Safe、AS-Unsafe 和 AC-Unsafe。此类插件的示例是堆栈展开库、名称服务开关 (NSS) 和字符集转换 (iconv) 后端。

    尽管作为示例提到的插件都是通过 dlopen 引入的,但 plugin 关键字并不意味着动态加载器或 libdl 接口的任何直接参与,这些都包含在 dlopen 中。例如,如果一个函数加载一个模块并找到它的某些函数的地址,而另一个函数只是调用那些已经解析的函数,则前者将被标记为 dlopen,而后者将获得插件。当单个函数执行所有这些操作时,它会同时获得两个标记。

  • i18n

    标有 i18n 的函数可以调用 gettext 系列的国际化函数,并且仅与这些函数一样安全。因此,此注释等效于:

    | MT-Safe env | AS-Unsafe corrupt heap dlopen | AC-Unsafe corrupt |

  • timer

    标有 timer 的函数使用 alarm 函数或类似函数为系统调用或长时间运行的操作设置超时。在多线程程序中,存在超时信号将被传递到不同线程的风险,因此无法中断预期的线程。除了 MT-Unsafe 之外,这些函数始终是 AS-Unsafe,因为在信号处理程序中调用它们可能会干扰在中断代码中设置的计时器,和 AC-Unsafe,因为没有安全的方法来保证在异步取消的情况下会重置较早的计时器。

2.2.2.3. 条件安全特征

Conditionally Safe Features

对于某些使函数在某些上下文中调用不安全的特性,除了完全避免调用函数之外,还有一些已知的方法可以避免安全问

评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

canpool

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值