引言
从我第一次修订《UNIX环境高级编程》一书以来已经快有8年了,期间发生了很多的变化。
在出版第2版之前,Open Group完成了2004版的Single UNIX Specification,它涵盖了两套勘误表的修改。2008年,Open Group完成了新版的Single UNIX Specification,它更新了基本定义,添加了新的接口,并且去除了弃用的接口。这套规范被称为2008年版的POSIX.1,其中包含第7版的基本规范,并在2009年发行。2010年,它与更新后的curses接口捆绑,一起作为Single UNIX Specification第4版(SUSv4)进行再版。
运行在Intel处理器上的Mac OS X操作系统的10.5、10.6和10.8版,被Open Group认证为UNIX系统。
苹果公司停止了PowerPC平台上Mac OS X的开发。在10.6发行版(Snow Leopard)之后只针对x86平台发布了新的操作系统版本。
Solaris操作系统以开源的形式发布,试图与FreeBSD、Linux和Mac OS X遵循的开源模式在声望上一争高下。在2010年,Oracle收购了Sun Microsystems之后,OpenSolaris的开发被终止。作为替代,Solaris社区组建了Illumos项目来继续基于OpenSolaris的开源开发。更多详细的信息,可以从http://www.illumos.org获得。
2011年,C语言标准被更新,但是因为系统并未能跟上其变化,本书中依然参照1999版。
最重要的是,在第2版中使用的平台已经过时了。本书这一版中涉及以下平台:
1)FreeBSD 8.0,前身是加州大学伯克利分校计算机系统研究组发布的4.4BSD系统,运行在32位Intel Pentium处理器上。
2)Linux 3.2.0(Ubuntu 12.04发布版),这是一个免费的类UNIX操作系统,运行在64位的Intel Core i5 处理器上。
3)Apple Mac OS X 10.6.8版(Darwin 10.8.0),运行在64位Intel Core2 Duo处理器上(Darwin基于FreeBSD和Mach)。我选择从PowerPC平台转向Intel平台,是因为最新版的Mac OS X不再支持PowerPC平台。这次选择带来的缺点是涉及的处理器倾斜向了Intel,而当讨论到异构性问题时,涉及的处理器如果能在字节序和整数大小等方面有不同的性质将是很有好处的。
4)Solaris 10,Sun Microsystems(现在的Oracle)的System V Release 4的派生系统,运行在64位UltraSPARC IIi处理器上。
与第2版的不同
最大的变化之一是POSIX.1-2008中的Single UNIX Specification弃用了一些STREAMS相关接口。这是准备在该标准的未来版本中去掉全部这些接口的第一步。因此,我已经不情愿地在这一版中删除了STREAMS的内容。这是一个不幸的变化,因为STREAMS接口为socket接口提供了一个很好的对照,并且在很多方面更为灵活。不可否认,当谈论到STREAMS时我并非绝对公正,但是毫无疑问的是,在现有系统中它的分量已经减轻。
Linux基础系统中未包含STREAMS,虽然添加该功能的包(LiS和OpenSS7)是可用的。
虽然Solaris 10中包含了STREAMS,但是Solaris 11的socket实现并没有构建在STREAMS之上。
Mac OS X不包含STREAMS支持。
FreeBSD不包含STREAMS支持(也从未包含过)。
随着STREAMS相关内容的去除,新的主题有机会替代它,例如POSIX异步I/O。
在本书第2版中,Linux版本是基于2.4版的。在这次的版本中,我们已经更新到了3.2版。两个版本的最大不同之一是线程系统。在Linux 2.4和Linux 2.6之间,线程的实现变为Native POSIX Thread Library(NPTL)。NPTL使得Linux线程的行为与其他系统的线程更加相似。
. 总的来说,这次的版本涵盖了超过70个新的接口,包括处理异步I/O、自旋锁、屏障和POSIX信号量等接口。除了一些普遍使用的接口被保留,大多数弃用的接口均被删除。
致谢
许多读者为第2版发来了评论和错误报告,感谢他们提高了第2版的准确性。下面提及的各位是最早提出建议或者指出错误的:Seth Arnold、Luke Bakken、Rick Ballard、Johannes Bittner、David Bronder、Vlad Buslov、Peter Butler、Yuching Chen、Mike Cheng、Jim Collins、Bob Cousins、Will Dennis、Thomas Dickey、Lo·c Domaigné、Igor Fuksman、Alex Gezerlis、M. Scott Gordon、Timothy Goya、Tony Graham、Michael Hobgood、Michael Kerrisk、Youngho Kwon、Richard Li、Xueke Liu、Yun Long、Dan McGregor、Dylan McNamee、Greg Miller、Simon Morgan、Harry Newton、Jim Oldfield、Scott Parish、Zvezdan Petkovic、David Reiss、Konstantinos Sakoutis、David Smoot、David Somers、Andriy Tkachuk、Nathan Weeks、Florian Weimer、Qingyang Xu和 Michael Zalokar。
技术审校者也提高了内容的准确性,感谢Steve Albert、Bogdan Barbu和Robert Day。特别感谢Geoff Clare和Andrew Josey为Single UNIX Specification的升华和第2章的准确性提供了帮助。另外,感谢Ken Thompson对历史问题做出了解答。
我得再一次说,与Addison-Wesley的工作人员的合作非常愉快。感谢Kim Boedigheimer、Romny French、John Fuller、Jessica Goldstein、Julie Nahil和Debra Williams-Cauley,此外,感谢Jill Hobbs的专业审稿能力。
最后,感谢我的家人对我在这次再版上花费了如此多时间给予的理解。
和以前一样,书中实例的源码可以从www.apuebook.com获得,非常欢迎读者发来邮件,发表评论,提出建议,订正错误。
Stephen A. Rago
sar@apuebook.com
2013年1月于新泽西州沃伦市
第2版前言
引言
我与Rich Stevens最早是通过电子邮件开始交往的,当时我发邮件报告他的第一本书《UNIX网络编程》的一个排版错误。他回信开玩笑说我是第一个给他发这本书勘误的人。到他1999年故去之前,我们时不时地会通邮件,一般都是在有了问题认为对方能解答的时候。我们在USENIX会议期间多次相见,并共进晚餐;Rich在会议中给大家做技术培训。
Rich Stevens真是个益友,行为举止很有绅士风度。我在1993年写《UNIX系统V网络编程》时,试图把书写成他的《UNIX网络编程》的系统V版。Rich高兴地为我审阅了好几章,并不把我当成竞争对手,而是当作一起写书的同事。我们曾多次谈到要合作给他的《TCP/IP详解》写个STREAMS版。天若有情,我们或许已经完成了这个心愿。然而,Rich已经驾鹤西去,修订《UNIX环境高级编程》就成为我跟他一起写书的最易实现的方式。
当Addison-Wesley公司的编辑找到我说想修订Rich的这本书时,我的第一反应是这本书没有多少要改的。尽管13年过去了,Rich的书还是巍然屹立。但是,与当初本书出版的时候相比,今日的UNIX行业已经有了巨大的变化。
系统V的各个变种渐渐被Linux所取代。原来生产硬件配以各自的UNIX版本的几个主要厂商,要么提供了Linux的移植版本,要么宣布支持Linux。Solaris可能算是硕果仅存的占有一定市场份额的UNIX系统V版本4的后裔了。
加州大学伯克利分校的CSRG(计算机科学研究组)在发布了4.4BSD之后,已经决定不再开发UNIX操作系统,只有几个志愿者小组还维护着一些可公开获得的版本。
Linux受到数以千计的志愿者的支持,它的引入使任何一个拥有计算机的人都能运行类似于UNIX系统的操作系统,并且可以免费获得支持最新硬件设备的源代码。在已经存在几种免费BSD版本的情况下,Linux的成功确实是个奇迹。
苹果公司作为一个富有创新精神的公司,已经放弃了老的Mac操作系统,换之以一个在Mach和FreeBSD基础上开发的新系统。
因此,我已经努力更新本书中的内容,以反映这四种平台。
在Rich 1992年出版《UNIX环境高级编程》之后,我扔掉了手头几乎所有的UNIX程序员手册。这些年来,我桌上最常摆放的就是两本书,一本是字典,另一本就是《UNIX环境高级编程》。我希望读者也能认为本修订版一样有用。
对第1版的改动
Rich的书依然屹立,我试图不去改动他这本书原来的风格。但是13年间世事兴衰,尤其是影响UNIX编程接口的有关标准变化很大。
我依据标准化组织的标准,更新了全书相关的接口方面的内容。第2章改动较大,因为它主要是讨论标准的。本书第1版是根据POSIX.1标准的1990年版写的,本修订版依据2001年版的新标准,内容要丰富很多。1990年ISO的C标准在1999年也更新了,有些改动影响到POSIX.1标准中的接口。
目前的POSIX.1规范涵盖了更多的接口。The Open Group(原称X/Open)发布的“SingleUNIX Specification”的基本规范现在已经并入POSIX.1,后者包含了几个1003.1标准和另外几个标准草案,原来这些标准是分开出版的。
我也相应地增加了些章节讨论新主题。线程和多线程编程是相当重要的概念,因为它们为程序员处理并发和异步提供了更清晰的方式。
套接字接口现在也是POSIX.1的一部分了。它为进程间通信(IPC)提供了单一的接口,而不考虑进程的位置。它成为IPC章节的自然扩展。
我省略了POSIX.1中的大部分实时接口。这些内容最好是在一本专门讲述实时编程的书中介绍。参考文献里有一本这方面的书。
我把最后面几章的案例研究也更新了,用了更接近现实的例子。例如,现在很少有系统通过串口或并口连接PostScript打印机了,多数PostScript打印机是通过网络连接的,所以我对PostScript打印机通信的例子做了修改。
有关调制解调器通信的那一章如今已经不太适用了。原始材料我们保留在本书网站上,有两种格式:PostScript(http://www.apuebook.com/lostchapter/modem.ps)和PDF(http://www.apuebook.com/lostchapter/modem.pdf)。
书中实例的源代码也可以从www.apuebook.com上获得。多数实例已经在下述四种平台上运行过:
1)FreeBSD 5.2.1,这是加州大学伯克利分校CSRG的4.4BSD的一个变种,在英特尔奔腾处理器上运行。
2)Linux 2.4.22(Mandrake 9.2发布),是一个免费的类UNIX操作系统,运行于英特尔奔腾处理器上。
3)Solaris 9,是Sun公司系统V版本4的变种,运行于64位的UltraSPARC IIi处理器上。
4) Darwin 7.4.0,是基于FreeBSD和Mach的操作系统环境,也是Apple Mac OS X 10.3版本的核心,运行于PowerPC处理器上。
致谢
首先要感谢Rich Stevens独立创作了本书第1版,它立即成为一本经典著作。
没有家人的支持,我不可能修订此书。他们容忍我满屋子散落稿纸(比平常还甚),霸占了家里的好几台机器,成天埋头于电脑屏幕前。我的妻子Jeanne甚至亲自动手帮我在一台测试的机器上安装了Linux。
多名技术审校者提出了很多改进意见,确保内容准确。我非常感谢David Bausum、DavidBoreham、Keith Bostic、Mark Ellis、Phil Howard、Andrew Josey、Mukesh Kacker、BrianKernighan、Bengt Kleberg、Ben Kuperman、Eric Raymond和Andy Rudoff。
我还要谢谢Andy Rudoff给我解答有关Solaris的问题,谢谢Dennis Ritchie不惜花时间从故纸堆中为我寻找有关历史方面问题的答案。再次谢谢Addison-Wesley公司的员工,与他们合作令人愉快。谢谢Tyrrell Albaugh、Mary Franz、John Fuller、Karen Gettman、JessicaGoldstein、Noreen Regina和John Wait。特别感谢Evelyn Pyle细致地编辑了本书。
就像Rich曾经做到的那样,我非常欢迎读者发来邮件,发表评论,提出建议,订正错误。
Stephen A. Rago
sar@apuebook.com
2005年4月于新泽西州沃伦市
第1版前言
引言
本书描述了UNIX系统的程序设计接口—系统调用接口和标准C库提供的很多函数。本书针对的是所有程序员。
与大多数操作系统一样,UNIX为程序运行提供了大量的服务—打开文件、读文件、启动一个新程序、分配存储区以及获得当前时间等。这些服务被称为系统调用接口(system call interface)。另外,标准C库提供了大量广泛用于C程序中的函数(格式化输出变量的值、比较两个字符串等)。
系统调用接口和库函数可参见《UNIX程序员手册》第2、3部分。本书不是这些内容的重复。手册中没有给出实例及基本原理,而这些正是本书所要讲述的内容。
UNIX标准
20世纪80年代出现了各种版本的UNIX,20世纪80年代后期在此基础上制定了数个国际标准,包括C程序设计语言的ANSI标准、IEEE POSIX标准系列、X/Open可移植性指南。
本书也介绍了这些标准,但是并不只是说明标准本身,而是着重说明它们与应用广泛的一些实现(主要指SVR4以及即将发布的4.4BSD)之间的关系。这是一种贴近现实世界的描述,而这正是标准本身以及仅描述标准的文献所缺少的。
本书的组织
本书分为6个部分:
1)对UNIX程序设计基本概念和术语的简要描述(第1章),以及对各种UNIX标准化工作和不同UNIX实现的讨论(第2章)。
2)I/O—不带缓冲的I/O(第3章)、文件和目录(第4章)、标准I/O库(第5章)和标准系统数据文件(第6章)。
3)进程—UNIX进程的环境(第7章)、进程控制(第8章)、进程之间的关系(第9章)和信号(第10章)。
4)更多的I/O—终端I/O(第11章)、高级I/O(第12章)和守护进程(第13章)。
5)IPC—进程间通信(第14和15章)。
6)实例—一个数据库的函数库(第16章)、与PostScript 打印机的通信(第17章)、调制解调器拨号程序(第18章)和使用伪终端(第19章)。
如果对C语言较熟悉并具有某些应用UNIX的经验,对学习本书将非常有益,但是并不要求读者必须具有UNIX编程经验。本书面向的读者主要是:熟悉UNIX的程序员和熟悉其他某个操作系统且希望了解大多数UNIX系统提供的各种服务细节的程序员。
本书中的实例
本书包含了大量实例—大约10 000行源代码。所有实例都用ANSI C语言编写。在阅读本书时,建议准备一本你所使用的UNIX系统的《UNIX程序员手册》,在细节方面有时需要参考该手册。
几乎对于每一个函数和系统调用,本书都用一个小的完整程序进行了演示。这可以让读者清楚地了解它们的用法,包括参数和返回值等。有些小程序还不足以说明库函数和系统调用的复杂功能和应用技巧,所以书中还包含了一些较大的实例(见第16~19章)。所有实例的源代码文件都可用匿名ftp从因特网主机ftp.uu.net的published/books/stevens.advprog.tar.Z文件下载。读者可以在自己的机器上修改并运行这些源代码。
用于测试实例的系统
遗憾的是,所有的操作系统都在不断变更,UNIX也不例外。下图给出了系统V和4.xBSD最近的进展情况。
4.xBSD是由加州大学伯克利分校CSRG开发的。该小组还发布了BSD Net1和BSD Net2版,其公开的源代码源自4.xBSD系统。SVRx 表示AT&T的系统V第x版。XPG3指X/Open可移植性指南的第3个发行版。ANSI C是C语言的ANSI标准。POSIX.1是IEEE和ISO的类UNIX系统接口标准。2.2节和2.3节将对这些标准和不同版本之间的差别做更多的说明。
本书中用4.3+BSD表示源自伯克利的介于BSD Net2和4.4BSD之间的UNIX系统。
在本书写作时,4.4BSD尚未发布,所以不能称一个系统是4.4BSD的。为了用一个简单的名字来引用该系统,故使用4.3+BSD。
本书中的大多数实例曾在下面4种UNIX系统上运行过:
1)U.H.公司(UHC)的UNIX系统V/386 R4.0.2(vanilla SVR4),运行于Intel 80386处理器上。
2)加州大学伯克利分校CSRG的4.3+BSD,运行于惠普工作站上。
3)伯克利软件设计公司的BSD/386(是BSD Net2的变种),运行于Intel 80386处理器上。该系统与4.3+BSD几乎相同。
4) Sun公司的SunOS 4.1.1和4.1.2(该系统与伯克利系统有很深的渊源,但也包含了许多系统V的特性),运行于SPARCstation SLC上。
本书还提供了许多时间测试及用于测试的实际系统。
致谢
在过去的一年半中,家人给予了我大力支持和爱,因为写书我们失去了很多快乐的周末,我深感歉疚。写书从许多方面影响了整个家庭。谢谢Sally、Bill、Ellen和David。
我要特别感谢Brian Kernighan对我写作此书的帮助。他审阅了全部书稿,不但提出了大量有洞察力的技术意见,还委婉地指出了多处修辞问题,但愿我在最终成稿中已经加以体现。Steve Rago也成为我的创作源泉,不但审阅了全部书稿,还为我解答了有关系统V的许多技术细节和历史问题。还要感谢Addison-Wesley公司邀请的其他技术审校者,他们对书稿的各个部分提出了很有价值的意见,他们是Maury Bach、Mark Ellis、Jeff Gitlin、PeterHoneyman、John Linderman、Doug McIlroy、Evi Nemeth、Craig Partridge、Dave Presotto、Gary Wilson、Gary Wright。
感谢加州大学伯克利分校CSRG的Keith Bostic和Kirk McKusick给了我一个账号,可在最新的BSD系统上测试书中实例。(也要感谢Peter Salus。)UHC的Sam Nataros和Joachim Sacksen给我提供了一份SVR4,用来测试书中例子。Trent Hein则帮助我获得BSD/386的alpha和beta版。
其他朋友在过去这些年以各种方式提供了帮助,看似不大,却非常重要。他们是PaulLucchina、Joe Godsil、Jim Hogue、Ed Tankus和Gary Wright。本书的编辑是Addison-Wesley公司的John Wait,他自始至终是我的忠实朋友。我不断地延期交稿,写作篇幅也一再超过计划,他从不抱怨。特别感谢美国国家光学天文台(NOAO),尤其是Sidney Wolff、Richard Wolff和Steve Grandi,为我提供准确的计算机时间。
真正的UNIX书应该用troff写成,本书也遵循了这一优秀传统。最终清样是作者用JamesClark写的groff软件包做出的。非常感谢James Clark提供了这个优异的写作软件,并迅速地修正其中所发现的bug。也许有一天我会最终弄清楚troff软件做页脚的技巧。
我十分欢迎读者发来电子邮件,发表评论,提出建议,订正错误。
W.Richard Stevens
rstevens@kohala.com
http://www.kohala.com/~rstevens
1992年4月于亚利桑那州塔克森市