第二章: UNIX 标准和实现
UNIX 以及 C 编程标准化工作经过多年努力已卓有成效.
UNIX 标准
ISO C
ISO C 标准从 89 年一版, 99 一版, 01, 04, 07 各一版, 现在实际上已经到了 23 版了.
ISO C 库可以分为 24 个部分, POSIX.1 标准已完整包含这些部分中的头文件, 其他的标准也是如此.
IEEE POSIX
POSIX 标准 最初是由 IEEE 发布的. 我们讨论的主要是 POSIX 的 1003.1 "操作系统接口标准". 这个标准的目的在于提升应用程序在不同 UNIX 系统中的兼容性.
这个标准中定义了操作系统必须提供的服务.
POSIX 1003.1 标准在许多年份都有发布和更新. 我们主要看的是2008 年的 POSIX.1 版本.
Single UNIX Specification
SUS 是 POSIX.1 的扩展. POSIX.1 标准中有一个可选的接口部分, 被称为 XSI, 实现了这些接口的系统被称为 XSI Conforming. 而只有 XSI Conforming 的系统可以称为 "UNIX 系统".
系统限制
操作系统中定义了许多的魔法数和常量. 大部分都是被硬编码到或通过 ad-hoc 的方式进入到程序中. 操作系统提供获取大部分这些魔法数和常量的函数, 以便提高程序在不同系统的兼容性. 限制可以分为两大类:
- 编译时限制: 比如 short integer 的位数
- 运行时限制: 比如 filename 的最大字节数
编译时限制的配置常数通常都在头文件中定义了. 运行时限制则需要程序在运行的时候调用函数去获取, 因此, 限制可以通过如下三个方式取得:
- 编译时限制从头文件中取得: (limits.h)
- 与文件或目录无关的运行时限制: 通过函数取得(sysconf)
- 与文件或目录有关的运行时限制: 通过函数取得(pathconf, fpathconf)
但实际上, 有些运行时限制在不同 UNIX 实现下都是固定的, 则它也可能会被定义在头文 件中, 但程序仍然需要通过上述三个 conf 组函数去获取它们.
ISO C 限制
由 ISO C 定义的所有编译时限制都在 limits.h
头文件中, 且在所有的 UNIX 系统下保持一致. 但需要注意的是这样的情况: 比如某些操作系统可能不会提供 signed/unsigned char 的区分(有些只使用 signed char).
ISO C 中也可能提供和 POSIX.1 类似语义的限制, 这种情况下, 我们需要选择 POSIX.1 提供的(因起更贴近系统), 比如 ISO C 的 FILENAME_MAX
, 在 POSIX.1 中有 NAME_MAX
和 PATH_MAX
共同决定.
POSIX 限制
有如下分组:
- 数值的限制: 如 SSIZE_MAX, WORD_BIT 等.
- 最小值的限制: 如 _POSIX_ARG_MAX
- 最大值: 如 _POSIX_CLOCKRES_MIN
- 运行时可增长的值: 如 CHARCLASS_NAME_MAX
- 运行时可变的值: 如
ARG_MAX
- 其他不变的值: 如 NL_ARGMAX
- Pathname 变量值: 如 FILESIZEBITS, LINK_MAX, NAME_MAX
需要注意, 最小值并非一成不变, 最小值限制在不同的操作系统下, 可能有变化, POSIX 只是定义了最小值应 "至少这么小".
XSI 限制
在 POSIX.1 的"可选部分", 即 XSI 中也有限制的定义, 包括:
- 最小值: 有 5 个定义
- 运行时不变值