“本章对3个主要标准——ISO C、POSIX和Single UNIX Specification进行了说明,也分析了这些标准对本书主要关注的4个实现,即FreeBSD、Linux、Mac OS X和Solaris所产生的影响。这些标准都试图定义一些可能随实现而更改的参数,但是我们已经看到这些限制并不完美。本书将涉及很多这些限制和幻常量。”
看完这一章最大的感受就是编写可移植UNIX程序确实挺麻烦的,连确定一些系统参数都这么麻烦。对于初学UNIX编程的人,这本书无疑来了个下马威,我都有点胆怯了。不过看了后面几章之后,才发觉其实就这章最麻烦,心理上过了这个坎,后来就基本如履平地了。就算这个坎过不去,完全可以把这个麻烦先抛在一边,毕竟大多数情况下我们只涉及linux或者其他某个单独的系统,编写可移植程序的场景并不是太多。等其他各方面都熟悉了,再主攻可移植这方面,就游刃有余多了。
本章基本没有需要费心理解的概念,绝大部分都是需要记忆的一些细节。这些细节也不需要死记硬背,在需要的时候查阅一下就够了。
本章有很多表格,而且以后会一直需要查阅这些表格,所以这里把这些表格都放上来了。由此本章笔记会很长,为了以后查阅的方便,第一次看时请稍加忍耐。
2.2 UNIX标准化
2.2.1 ISO C
ISO C标准的意图是提供C程序的可移植性,使其能适合于大量不同的操作系统,而不只是适合UNIX系统。此标准不仅定义了C程序设计语言的语法和语义,还定义了其标准库。
2.2.2 IEEE POSIX
POSIX是一个最初由IEEE(Institute of Electrical and Electronics Engineers,电气和电子工程师学会)制订的标准族。POSIX指的是可移植操作系统接口(Portable Operating System Interface)。它原来指的只是IEEE标准1003.1-1988(操作系统接口),后来则扩展成包括很多标记为1003的标准及标准草案,如shell和实用程序(1003.2)。与本书相关的是1003.1操作系统接口标准,该标准的目的是提升应用程序在各种UNIX系统环境之间的可移植性。它定义了“符合POSIX的”(POSIX compliant)操作系统必须提供的各种服务。
POSIX.1是该标准的一个最常用版本,本书讲述的是POSIX.1 2008年版。
2.2.3 Single UNIX Specification
Single UINX Specification(SUS,单一UNIX规范)是POSIX.1标准的一个超集,它定义了一些附加接口扩展了POSIX规范提供的功能。POSIX.1相当于Single UINX Specification中的基本规范部分。
注意:
1) 虽然POSIX标准是以UNIX操作系统为基础的,但是它并不限于UNIX和UNIX类的系统。
2) Open Group拥有UNIX商标,他们使用Single UINX Specification定义了一系列接口。一个系统要想称为UNIX系统,其实现必须支持这些接口。
POSIX.1中的X/Open系统接口(X/Open System Interface,XSI)选项描述了可选的接口,也定义了遵循XSI(XSI conforming)的实现必须支持POSIX.1的哪些可选部分。只有遵循XSI的实现才能称为UNIX系统。
2.3 UNIX系统实现
2.3.1 SVR4
2.3.2 4.4BSD
2.3.3 FreeBSD
2.3.4 Linux
2.3.5 Mac OS X
2.3.6 Solaris
2.3.7 其他UNIX系统
2.4 标准和实现的关系
2.5 限制
UNIX系统实现定义了很多幻数和常量,其中有很多已被硬编码到程序中,或用特定的技术确定。由于大量标准化工作的努力,已有若干种可移植的方法用以确定这些幻数和具体实现定义的限制。
有两种限制类型:编译时限制和运行时限制。编译时限制可在头文件中定义,程序在编译时可以包含这些头文件。但是,运行时限制则要求进程调用一个函数获得限制值。
某些限制在一个给定的实现中可能是固定的,而在另一个实现中则可能是变动的。
为了解决这类问题,标准提供了以下3种限制:
1) 编译时限制(头文件);
2) 与文件或目录无关的运行时限制(sysconf函数);
3) 与文件或目录有关的运行时限制(pathconf和fpathconf函数);
2.5.1 ISO 限制
2.5.2 POSIX 限制
2.5.3 XSI限制
2.5.4 函数sysconf、pathconf和fpathconf
2.5.5 不确定的运行时限制
2.6 选项
如同对限制的处理一样,POSIX.1定义了3种处理选项的方法:
1) 编译时选项定义在<unistd.h>中;
2) 与文件或目录无关的运行时选项用sysconf函数来判断;
3) 与文件或目录有关的运行时选项通过调用pathconf或fpathconf函数来判断。
2.7 功能测试宏
头文件中除了POSIX.1和XSI定义外,大多数实现在这些头文件中也加入了它们自己的定义。如果在编译一个程序时,希望它只与POSIX的定义相关,而不与任何实现定义的常量冲突,那么就需要定义常量_POSIX_C_SOURCE。一旦定义了_POSIX_C_SOURCE,所有POSIX.1头文件都使用此常量来排除任何实现专有的定义。
常量_POSIX_C_SOURCE被称为功能测试宏(feature test marco)。
2.8 基本系统数据类型
2.9 标准之间的冲突
就整体而言,这些不同的标准之间配合得相当好。因为SUS基本说明和POSIX.1是同一个东西,所以我们不对它们进行特别的说明,我们主要关注ISO C和POSIX.1之间的差别。它们之间的冲突并非有意,但如果出现冲突,POSIX.1服从ISO C标准。