Linux/UNIX系统编程手册(上、下册)(txt+pdf+epub+mobi电子书下载)

作者:(德)Michael Kerrisk 著

出版社:人民邮电出版社

格式: AZW3, DOCX, EPUB, MOBI, PDF, TXT

Linux/UNIX系统编程手册(上、下册)

Linux/UNIX系统编程手册(上、下册)试读:

前言

主题

本书将描述Linux编程接口:由UNIX操作系统的开源实现——Linux所提供的系统调用、库函数以及其他底层接口。运行于Linux之上的每一个程序都会直接或间接地使用这些接口。这些接口允许应用程序去执行诸多任务:文件I/O、创建/删除文件和目录、创建新进程、执行程序、设置定时器、在同一台计算机上发起进程或线程间通信,以及为联网计算机间的进程建立通信等等。有时,人们也将这一系列的底层接口称为系统编程接口。

尽管本书着眼于Linux,但对于标准和可移植性问题也倍加关注。对于Linux所特有的技术细节,以及已由POSIX和SUS标准化的UNIX普遍特性,本书会在论述中清晰地加以区分。因此,本书也提供了对UNIX/POSIX编程接口的全面描述。对于那些在其他UNIX系统环境中编程,或者编写跨平台可移植应用的程序员来说,本书同样具有实用价值。本书的读者

本书主要针对以下读者:● 为Linux系统、其他UNIX系统,或兼容于POSIX的操作系统编写

应用程序的程序员和软件设计人员。● 在Linux和其他UNIX实现之间,以及Linux和其他操作系统之间进

行应用程序移植的程序员。● 教/学Linux和UNIX系统编程的高校师生。● 意欲深入理解Linux/UNIX编程接口以及系统软件各模块实现细节

的系统管理人员和高级用户(power users)。

作者假定读者之前有些许编程经验,但不必是在系统编程领域。此外,作者还假定读者具备阅读C语言源码的能力,并了解如何使用shell和UNIX或Linux的常用命令。对于不熟悉UNIX和Linux的读者来说,阅读第2章中面向程序员对UNIX和Linux系统基本概念所做的回顾会有所帮助。提示:[Kernighan & Ritchie, 1988]是最具权威性的C语言参考书籍。[Harbison& Steele, 2002]一书对C语言的介绍则更为详细,并涵盖了由C99标准所带来的变化。[van der Linden, 1994]也是一本不错的C语言书籍,寓教于乐。[Peek et al., 2001]则对UNIX的使用做了简洁而完整的介绍。贯穿本书,会以这种缩进小字体的文字形式用于旁注,其内容包括基本原理、实现细节、背景信息、史上轶闻以及与正文相关的其他辅助主题。Linux和UNIX

其他UNIX实现的大多数特性同样见诸于Linux,反之亦然。有鉴于此,本书本可只关注于标准UNIX(即POSIX)的系统编程。编写可移植的应用程序固然是值得追求的目标,但描述Linux对标准UNIX编程接口的扩展也同样重要。Linux的广受欢迎只是原因之一,而有时出于性能方面的考虑,或是需要访问标准UNIX编程接口所不支持的功能时,使用非标准扩展(正因如此,所有UNIX实现都提供有非标准扩展)就显得至为重要,此为原因之二。

综上所述,在构思本书时,作者不但力图使其对在各种UNIX实现中编程的程序员有所帮助,还全面介绍了Linux专有的编程特性,如下所示。● epoll,获取文件I/O事件通知的一种机制。● inotify,监控文件和目录变化的一种机制。● capabilities,为进程赋予超级用户的部分权限的一种机制。● 扩展属性。● i-node标记。● clone()系统调用。● /proc文件系统。● 在文件I/O、信号、定时器、线程、共享库、进程间通信以及套

接字方面,Linux所专有的实现细节。本书的用途和组织结构

本书主要有以下两方面的用途:● 作为Linux/UNIX编程接口的入门教程,读者可循序阅读本书。后

续各章内容均构建于之前诸章素材的基础之上,伴之以尽可能简

短的前向引用。● 作为Linux/UNIX编程接口的参考大全,读者可以根据书后的详细

索引和频现于正文中的交叉引用,随机选择阅读主题。

本书各章可分为以下几个部分。

1.背景知识及概念:UNIX、C语言以及Linux的历史回顾,以及对UNIX标准的概述(第1章);以程序员为对象,对Linux和UNIX的概念进行介绍(第2章);Linux和UNIX系统编程的基本概念(第3章)。

2.系统编程接口的基本特性:文件I/O(第4章、第5章),进程(第6章),内存分配(第7章),用户和组(第8章),进程凭证(process credential)(第9章),时间(第10章),系统限制和选项(第11章),以及获取系统和进程信息(第12章)。

3.系统编程接口的高级特性:文件I/O缓冲(第13章),文件系统(第14章),文件属性(第15章),扩展属性(第16章),访问控制列表(第17章),目录和链接(第18章),监控文件事件(第19章),信号(signals)(第20~22章),以及定时器(第23章)。

4.进程、程序及线程:进程的创建、终止,监控子进程,执行程序(第24~28章),以及POSIX线程(第29~33章)。

5.进程及程序的高级主题:进程组、会话以及任务控制(第34章),进程优先级和进程调度(第35章),进程资源(第36章),守护进程(第37章),编写安全的特权程序(第38章),能力(capability)(第39章),登录记账(第40章),以及共享库(第41章和第42章)。

6.进程间通信(IPC):IPC概览(第43章),管道和FIFO(第44章),系统V IPC消息队列、信号量(semaphore)及共享内存(第45~48章),内存映射(第49章),虚拟内存操作(第50章),POSIX消息队列、信号量及共享内存(第51~54章),以及文件锁定(第55章)。

7.套接字和网络编程:使用套接字的IPC和网络编程(第56~61章)。

8.高级I/O主题:终端(第62章),其他I/O模型(第63章),以及伪终端(第64章)。程序示例

本书会以简短而完整的程序示例来描述大部分编程接口,以期读者通过命令行方便地体验这些程序,从而了解各种不同系统调用和库函数的运作方式。因此,本书包含了大量代码示例——约15 000行C语言代码和shell会话记录。

虽然阅读并执行上述示例代码是学习Linux编程接口的一个不错的起点,但巩固本书所述概念最为有效的方式还是动手编写代码——无论是修改示例程序以验证自己的编程思路,还是编写全新的程序。

书中所有源代码均可从本书网站上下载。网站所发布的源码中还包含了不少未见诸于本书的其他程序。这些程序的用途和详细信息在源码注释中均有描述。源码中还提供了Makefile,用来构建相应的程序,附带的README文件则提供了相应程序的具体细节。

在GNU Affero通用公共许可证(Affero GPL)版本3条款的约束下,可自行重新发布和修改本书源码,源码中也提供了一份GNU Affero GPL版本3的文件副本。习题

本书各章大都会在结尾处附有一组习题,其中一部分会利用书中的程序示例进行各种试验,另一些则与本章所讨论的概念相关,而其他习题则是引导读者亲自动手编程,意在巩固读者对所学内容的理解。附录F会有选择地给出部分习题的答案。标准和可移植性

本书自始至终都对可移植性问题予以了特殊关注。对相关标准的①引用在书中会反复出现,尤其是POSIX.1-2001和SUSv3的联合标准。此外,本书还包括了该标准最新版本(POSIX.1- 2008与SUSv4联合标准)的变更细节。(由于SUSv3较之于之前的版本做了大范围的修订,并且在写作本书之际,SUSv3依然是影响最为广泛的UNIX标准,故而本书对标准的讨论一般都以SUSv3为框架,并会注明其与SUSv4之间的差别。然而,对读者来说,除非另有说明,与SUSv3规范有关的论述同样适用于SUSv4。)

对于那些尚未标准化的特性,本书会列出与其他 UNIX 实现间的差异范围。此外,本书也会强调那些独具Linux实现特色的主要特性,以及Linux和其他UNIX实现之间在系统调用和库函数方面的细微差别。任何特性,凡未注明为Linux所专有,读者通常可将其视为大部分或所有UNIX实现的标准特性。

书中的编程示例(除了注明为Linux所专有的特性)大多已在Solaris、FreeBSD、Mac OS X、Tru64 UNIX以及HP-UX中的所有或部分系统上进行了测试。为了改进针对其中某些系统的可移植性,本书的Web站点还为特定编程示例提供了其他版本,此类代码就不再于本书中列出。Linux内核和C语言函数库版本

本书主要着眼于Linux 2.6.x,撰写本书之际,这一内核版本的使用也最为广泛。本书同样涵盖了Linux 2.4内核的详细信息,也会适时指明Linux 2.4和2.6内核间的特性差异。凡是见诸于Linux 2.6.x系列中的新特性,作者均会标出其(首度)出现的确切内核版本号(例如,2.6.34)。

至于C语言函数库,本书会重点关注GNU C语言库(glibc)版本2。本书也会适时指出glibc 2.x版本之间所存在的差异。

本书付梓之际,Linux内核版本2.6.35刚刚问世,不久又发布了glibc版本2.12。本书目前的论述涵盖了以上两种软件的这两个版本。本书出版后,Linux和glibc接口所发生的变化会在本书的Web站点上公布。在其他语言中调用编程接口

虽然本书的程序示例都是以C语言编写而成的,但读者也能使用其他编程语言来调用本书所描述的编程接口。这些语言既包括编译语言,例如:C++、Pascal、Modula、Ada、FORTRAN和D语言,也包括脚本语言,例如:Perl、Python和Ruby(如要使用Java,则需另辟蹊径,可参阅[Rochkind, 2004])。这需要运用不同的技术以获取必要的常量定义和函数申明(C++除外),而按C语言链接惯例所约定的方式来传递函数参数可能也需要额外的工作投入。虽然实现起来有差异,但基本原理却都相同,即便读者在使用其他语言进行编程,本书所含信息对他们也同样适用。关于作者

本人于1987年开始使用UNIX和C语言。当时,作者连续几个礼拜都泡在一台HP Bobcat工作站旁,陪伴我的只有Marc Rochkind所著Advanced UNIX Programming(第1版)一书,以及一本最终被翻得卷了边的C shell手册的印刷本。投入时间阅读文档(如果有的话),并编写一些小型的(规模可逐渐变大)测试程序进行试验,直至自己对软件的理解感到信心满满——这是作者当时所采用的编程学习方法,并一直沿用至今——作者也向任何试水新型软件技术的人们推荐这一做法。依作者拙见,从长远来看,这种自学方法能够大大节约时间。本书所载的许多编程示例正是在这一学习方法的激励之下设计而成。

作者的主要身份是软件工程师和设计师。然而,作者同样好为人师,并在学术或商业领域有过数年的教学经验。作者还开设过多门为期一周的 UNIX 系统编程课程,这一经验对本书的写作也颇有影响。

作者使用Linux的时间大约只有与UNIX打交道的时间一半长,在这段时间里,作者的兴趣也逐渐集中在了内核和用户空间的“分水岭”——Linux编程接口上。这一兴趣也使作者投身于一系列紧密相联的活动中。作者会时不时地对POSIX/SUS标准提出自己的意见并提供BUG报告;对新加入Linux内核中的用户空间接口进行测试和设计评审(还能帮助发现并修复那些接口中的诸多代码和设计缺陷);作者还经常在关于编程接口及其文档的主题会议上发言,并受邀多次出席Linux内核开发者年度峰会。将上述所有活动串接在一起的主线是作者对Linux领域最突出的贡献:作者为Linux man-pages项目(http://www.kernel.org/doc/man-pages/)所做的工作。

Linux手册页中的第2、3、4、5以及7部分都属于man-pages项目。这几部分也是手册页中描述编程接口的内容,这些编程接口由Linux内核及GNU C语言库提供,本书所要介绍的正是这方面的内容。作者参与man-pages项目已逾十载。自2004年起,作者成为了该项目的主要维护人,所承担的任务大致包括:撰写文档、阅读内核和C语言库源码,以及通过编程来验证文档细节(通过为接口撰写文档来发现相关接口中的BUG,效果颇为不俗)。此外,作者对man-pages项目的贡献也最多——在约900页的手册页中,作者独自编写了其中的140页,并与他人合著了另外的125页。因此,在购买本书之前,读者想必已经阅读过本人的工作成果了。作者希望这些成果能对读者有所帮助,希望本书更是如此。致谢

没有一干人等的支持,本书的质量绝不会如此之高。我要向他们致以最诚挚的谢意。

来自世界各地的多位技术审稿人都参与了本书初稿的阅读,找出错误,指出含糊不清的解释,对措辞、插图以及习题提出建议,测试程序,发现不为作者所知的Linux和其他UNIX实现间的行为差异,并不时为作者打气助威。在本书中,作者将许多审稿人无私奉献的真知灼见一并收纳,实则作者的知识并非如此渊博。当然,书中的任何错误都是作者一人之过。

无论以下技术审稿人(按姓氏字母排序)对本书手稿的审校巨细与否,篇幅多少,作者都要向他们致以由衷的谢意。● Christophe Blaesss是一名软件咨询工程师和培训专家,专长是

Linux在工业(实时和嵌入)方面的应用。Christophe是

Programmation système en C sous Linux一书的作者,这本法文

杰作涵盖了与本书相同的多项主题。他不吝审阅了本书的众多章

节。● David Butenhof(HP公司)是原POSIX线程工作组和SUS线程扩

展工作组的成员之一,也是Programming with POSIX Threads一

书的作者。他曾为开放软件基金会编写了最初的DCE线程参考实

现,并曾担任OpenVMS和Digital UNIX线程实现的首席架构师。

David审校了本书与线程相关的章节,提出了诸多改进意见,还

耐心地纠正了几处作者对POSIX线程API的理解错误。● Geoff Clare目前在为The Open Group开发UNIX一致性测试包,

从事UNIX标准化工作已逾20年,是Austin Group 的6位关键参与

者之一,该组的宗旨是开发出构成POSIX.1和Single UNIX

Specification基础卷的共同标准。Geoff仔细审校了手稿中与UNIX

编程接口相关的内容,耐心细致地提出了众多修正和改进意见,

发现了诸多潜藏于手稿中的错误,在突出标准对可移植编程的重

要性方面助益良多。● Loïc Domaigné(当时供职于德国空中交通管制中心[German Air

Traffic Control])是一名系统软件工程师,主要从事分布式、多

并发、容错型嵌入式系统的设计和开发,此类系统对实时性有着

严苛的要求。他针对 SUSv3 中与线程规范有关的内容发表过评

论和建议,在多个网上技术论坛中古道热肠,诲人不倦,无私地

分享自己的编程心得。Loïc细致地审校了本书与线程相关各章节,

以及多处其他内容。除了编写若干精巧的程序来验证Linux线程

实现的细节以外,他还倾注了巨大的热情并鼓励作者,提出了许

多建议以改进本书整体的表现形式。● Gert Döring mgetty和sendfax程序的开发者,这一“双子星座”

也是Linux/UNIX系统上使用最为广泛的开源传真软件包。最近,

他主要忙于搭建并维护基于 IPv4 和 IPv6的大型网络,其肩负的

主要任务是:与全欧洲的同事一起定义有效的网络策略,以确

保 Internet 基础设施顺畅运行。Gert 审校了本书与终端、登录记

账、进程组、会话以及任务控制相关各章节,并反馈了大量的有

用信息。● Wolfram Gloger是一名IT顾问,过去15年,他参与过许多自由和

开源软件项目(Free and Open Source Software,FOSS)。除此

之外,Wolfram还是GNU C语言库中malloc软件包的实现者。目

前,他主要从事于Web服务的开发,尤其专注于网上教学,当然,

在内核和系统库方面,他仍会偶露峥嵘。Wolfram审校了本书诸

多章节,尤其是侧重于内存方面的内容。● Fernando Gont是阿根廷国家科技大学(Universidad Tecnológica

Nacional, Argentina)电子信息中心(Centro de Estudios de

Informática,CEDI)成员。Internet工程技术(Internet

engineering)是其兴趣所在,在Internet工程任务组(IETF)也

能见到其活跃的身影,他还是多个RFC文档的作者。此外,

Fernando还为英国CPNI(国家基础设施保护机构)中心效力,

以提供对通信协议安全方面的评估,而首个完整的TCP和IP协议

安全评估报告也正是由他提出的。Fernando仔细审校了本书涉

及网络编程的相关章节,不厌其烦地向作者解释了TCP/IP协议

的诸多细节,并对相关内容提出了不少改进意见。● Andreas Grünbacher(SUSE实验室)是位内核高手,还是Linux

扩展属性和POSIX访问控制列表的实现者。Andreas 除了仔细审

校了本书多章内容以外,还对作者勉励有加,有时,他的只言片

语便极有可能改变这部书的整体结构。● Christoph Hellwig 是Linux存储和文件系统咨询师,也是内核方面

公认的行家,参与过Linux内核中多个部分的开发工作。在忙于

编写及审查Linux内核补丁代码之余,Christoph抽空审校了本书

若干章节,并提出了诸多有益的改进和修正意见。● Andreas Jaeger曾领导过Linux向x86-64架构的移植开发工作。身

为GNU C语言库的开发者,他不但将该库移植到了 x86-64 平台,

而且还促成该库符合多个领域的标准,尤其是在数学库方面。他

当前效力于Novell公司,是openSUSE的程序经理。Andreas审校

的章节之多,超乎作者预期。在本书的写作过程中,他除了提出

诸多改进意见之外,也给予作者热情的鼓励。● Rick Jones绰号“Mr. Netperf”(HP公司联网系统的性能偏执

狂),对本书的网络编程相关章节提出了宝贵意见。● Andi Kleen(当时效力于SUSE实验室)长期以来,一直是内核

方面公认的行家里手,对Linux内核诸多不同领域贡献颇多,包

括:网络、错误处理以及底层架构代码等方面。Andi对网络编程

相关内容做了全面审校,使作者在Linux TCP/IP实现方面大开眼

界,此外,他还提供了许多建议,用以改善本书主题的展现形式。● Martin Landers(Google)在我有幸与他共事时,他还是一名学

生。其后,他在短期内便集诸多技能于一身,且形象百变——

软件架构师、IT 培训师以及职业黑客。劳Martin大驾审校本书,

实为作者之幸。他对本书的评论和更正往往一针见血,对多章内

容质量的改进功莫大焉。● Jamie Lokier是公认的内核高手,投身于Linux开发已达15年之久。

如今,他自封为“专家,长于解决潜伏于Linux系统中的疑难杂

症”。Jamie极其全面地审校了本书涉及内存映射、POSIX共享

内存以及虚拟内存操作等方面的章节。他的审校工作不但纠正了

作者对相关主题细节方面的许多误解,相应各章的结构也得以大

为改观。● Barry Margolin在其25年职业生涯中,从事过系统程序员、系统

管理员以及技术支持工程师。当前,他作为一名系统性能工程师,

供职于Akamai技术公司。在各种讨论UNIX和Internet技术主题的

网上论坛中,他频频现身,威名素著。他还是多本相关技术主题

书籍的技术审稿人。Barry审校了本书若干章节,并提出了诸多

改进意见。● Paul Pluzhnikov(Google)之前曾是Insure++内存调试工具的技

术带头人和主要开发者。有时,他也会以GDB黑客的身份现

身,在网上论坛里积极地回复有关调试、内存分配、共享库以及

运行时环境方面的问题。Paul审校了本书多章内容,提出了许多

宝贵意见。● John Reiser(与Tom London)实现了UNIX向32位架构移植的早

期版本之一VAX- 11/780。他还是mmap()系统调用的编写者。

John审校了本书多章内容,自然也包括mmap()所在的章节。他

所提供的大量历史洞见,及其对技术透彻地阐释为本书增色不

少。● Anthony Robins(新西兰Otago大学计算机科学副教授)笔者30

年的密友,本书某些章节的第一个读者,也是最早提出宝贵意见

的技术审校者,在本书的写作过程中,一直给予作者以激励。● Michael Schröder (Novell) GNU screen程序的主要开发者之一,

这项编程工作已令Michael在终端驱动程序的实现方面达到了“巨细靡遗,了如指掌”的境界。Michael除了审校本书与终端和

伪终端相关的章节以外,还针对进程组、会话以及任务控制等章

节反馈了极为有益的意见。● Manfred Spraul曾从事过Linux内核中(包括但不限于)IPC的开

发工作,不吝审校了本书与IPC相关的若干章节,并提出了许多

改进意见。● Tom Swigg,作者在DEC从事培训工作时曾与他共事,作为本书

最早的技术审校者之一,他对许多章节都反馈了极其重要的意

见。Tom从事软件工程师和IT培训师的工作已逾25年,目前就职

于伦敦南岸大学(London South Bank University),在Vmware环

境下从事Linux编程和技术支持工作。● Jens Thoms Törring继承了物理学家改学编程的优良传统,大批

开源的设备驱动程序和其他软件都出自他手。Jens审校的章节之

多,在技术方面跨度之大,着实令人瞠目,他对各章内容的改进

都提出了独特而又弥足珍贵的见解。

还有许多其他技术审稿人也审校了本书的不同内容,并提出了诸多宝贵意见。在此,作者向以下一干技术审稿人表示感谢(以姓氏字母顺序排列):George Anzinger(MontaVista Software)、Stefan Becher、Krzysztof Benedyczak、Daniel Brahneborg、Andries Brouwer、Annabel Church、Dragan Cvetkovic、Floyd L. Davidson、Stuart Davidson(Hewlett-Packard Consulting)、Kasper Dupont、Peter Fellinger(jambit GmbH)、Mel Gorman(IBM)、Niels Göllesch、Claus Gratzl、Serge Hallyn(IBM)、Markus Hartinger(jambit GmbH)、Richard Henderson(Red Hat)、Andrew Josey(The Open Group)、Dan Kegel(Google)、Davide Libenzi、Robert Love(Google)、H.J. Lu(Intel Corporation)、Paul Marshall、Chris Mason、Michael Matz(SUSE)、Trond Myklebust、James Peach、Mark Phillips(Automated Test Systems)、Nick Piggin(Novell SUSE实验室)、Kay Johannes Potthoff、Florian Rampp、Stephen Rothwell(IBM Linux技术中心)、Markus Schwaiger、Stephen Tweedie(Red Hat)、Britta Vargas、Chris Wright、Michal Wronski以及 Umberto Zamuner。

除了技术审稿人之外,作者还得到了各界人士及组织在其他方面的帮助。

我要感谢以下人等为我解答技术难题,他们是:Jan Kara、Dave Kleikamp和Jon Snader。我要感谢Claus Gratzl和Paul Marshall在系统管理方面对我的帮助。

我要感谢Linux基金会(LF)。2008年间,LF资助我作为一名全职研究人员参与man-pages项目,并从事Linux编程接口的测试和设计评审工作。虽然LF全职研究员的身份不能为本书的写作提供直接的资金支持,但却使作者得以养家糊口,这一助力本意在于令我全身心投入对Linux编程接口的测试以及对文档的编纂工作,却也惠及作者的“私活”。抛开公事不谈,我要感谢Jim Zemlin——我在LF的“接口”人,还要感谢LF技术咨询委员会的一干专家,感谢他们对我的聘任。感谢Alejandro Forero Cuervo对本书书名的建议!

25年前,在我为第一个学位拼搏之时,Robert Biddle激起了我对UNIX、C以及Ratfor的兴趣,谢谢你,老兄。虽然以下诸君与本书并无直接干系,但当我在新西兰坎特伯雷大学攻读第二学位时,他们就鼓励我在写作道路上坚持下去,在此,我要向他们表示感谢,他们是Michael Howard、Jonathan Mane-Wheoki、Ken Strongman、Garth Fletcher、Jim Pollard,以及Brian Haig。

由Richard Stevens所著的几部关于UNIX编程和TCP/IP方面的杰作,数年来一直被我辈程序员奉为圭臬,只可惜先贤已逝。凡是读过上述书籍的读者势必会注意到,本书与Richard Stevens的那几本巨著看起来有些相似。这并非偶然。在构思本书时,作者曾从较为宏观的角度就书籍设计反复斟酌,可最终发现Richard Stevens所采用的方法才是正解,正因如此,本书采用了与其相同的展示方式。

感谢下列人士和组织为我提供UNIX系统,使我得以运行测试程序,并验证其他UNIX实现的细节,感谢Anthony Robins和Cathy Chandra在新西兰Otago大学所提供的多种UNIX测试系统,感谢Martin Landers、Ralf Ebner和Klaus Tilk在德国慕尼黑技术大学(Technische Universität)所提供的多种UNIX测试系统,感谢HP公司在Internet上免费开放他们的testdrive系统,感谢Paul de Weerd使我得以访问OpenBSD系统。

要衷心感谢两家慕尼黑公司及其老板,这两家公司除了为我提供了工作机会(还是弹性工作制)和热情的同事,还格外开恩,允许我在写作本书时使用他们的办公室。感谢exolution有限公司的Thomas Kahabka和Thomas Gmelch,特别要感谢jambit 有限公司的Peter Fellinger和Markus Hartinger。

感谢下列人士对我提供的各种帮助,他们是Dan Randow、Karen Korrel、Claudio Scalmazzi、Michael Schüpbach和Liz Wright。感谢Rob Suisted和Lynley Cook为封面和封底所提供的照片。

感谢下列人士以不同方式给作者以鼓励和支持,他们是Deborah Church、Doris Church和Annie Currie。

感谢No Starch出版社大队人马为这一庞大创作项目所提供的各种帮助。Bill Pollock从项目之初就一直秉持直言不讳的风格,始终对本书的完成充满信心,并耐心地关注着项目的进展,我要对他表示感谢。感谢本书最初的责任编辑Megan Dunchak。感谢本书的文字编辑Marilyn Smith,无论我如何殚精竭虑以求文字的清晰与一致,此君总能从鸡蛋里挑出骨头。本书的版面和设计由Riley Hoffman全面负责,在“上了同一条船”后又挑起了制作编辑的重担。Riley总是不厌其烦地满足我的请求,以求本书的排版无误——最终结果堪称完美。谢谢你。

现在,我才体味出下面这句老话的真正含义:一人写作,全家受累。感谢Britta和Cecilia对我的支持,感谢你们能容忍我因写作本书而长时间地不着家。许可

承蒙IEEE(美国电气电子工程师学会)和The Open Group惠允,本书得以引用IEEE Std 1003.1,2004版以及The Open Group基础规范第6号(Issue 6)中POSIX(可移植性操作系统接口)——信息技术标准的部分文字。可通过http://www.unix.org/version3/online.html在线查阅规范的完整版本。Web站点和程序示例的源码

读者可在http://man7.org/tlpi上找到更多有关本书的信息,包括本书的勘误表和程序示例源码。反馈

欢迎读者提供BUG报告、对代码的改进建议,以及为进一步提高代码可移植性而提出的修订意见。同样欢迎读者提供针对本书内容的缺陷报告和改进叙述方式的一般性建议。当前的勘误列表可参见http://man7.org/tlpi/errata/。由于Linux编程接口变化无常、且变更有时极为频繁,仅凭作者一己之力很难“与时俱进”,因此读者就全新或已变更的Linux编程接口特性所提供的反馈信息,作者也将乐于收到,并会纳入本书的下一版中。Michael Timothy Kerrisk于德国慕尼黑和新西兰克赖斯特彻奇2010年8月mtk@man7.org①译者注:大致可视为一套标准的两种称谓。第1章 历史和标准

Linux是UNIX操作系统家族中的一员。就计算机的发展而言,UNIX历史悠久。本章的第一部分会简要介绍UNIX的历史——以对UNIX系统和C编程语言起源的回顾拉开序幕,接着会述及成就今日Linux系统的两大关键因素:GNU项目和Linux内核的开发。

UNIX系统最引人关注的特征之一,是其开发不受控于某一厂商或组织。相反,许多团体——既有商业团体,也有非商业团体——都曾为UNIX的演进做出过贡献。这一渊源使UNIX集多种开创性的特性于一身,但同时也带来了负面影响——随着时间的推移,UNIX的实现渐趋分裂。因此,要编写出能够运行于所有UNIX实现之上的应用程序愈发困难。这又导致了人们对UNIX实现的标准化呼声越来越高,本章的第二部分将讨论这一问题。对UNIX的定义通常有两种。其一是指通过SUS所规范的官方一致性测试,且由OPEN GROUP(UNIX商标的持有者)正式授权冠以“UNIX”的操作系统。在写作本书之际,尚无开源的UNIX实现(比如,Linux和FreeBSD)获得了“UNIX”冠名。在第二种定义中,UNIX是指那种运作方式类似于经典UNIX系统(比如,最初的Bell实验室UNIX系统,及其后来的主要分支System V和BSD)的操作系统。根据这一定义,一般将Linux视为UNIX系统(如同现代BSD系统一样)。尽管本书会密切关注SUS,但也会遵循对UNIX的第二种定义,因此诸如“Linux,像其他UNIX实现一样……”这样的说法,会在书中频繁出现。1.1 UNIX和C语言简史

1969年,在AT&T电话公司下辖的bell实验室中,Ken Thompson开发出了首个UNIX实现。该实现是使用Digital PDP-7小型机的汇编语言开发而成的。其名称UNIX是“MULTICS(多信息及计算服务,Multiplexed Information and Computing Service)”一词的双关语,而MULTICS之名则出自一个早期的操作系统开发项目,该项目由AT&T、MIT(麻省理工学院)以及通用电器公司联合开发。(因为未能开发出一款经济实用的操作系统,该项目首战失利。沮丧之余,AT&T随即退出这一项目中。)Thompson设计新操作系统的某些灵感正源于MULTICS,其中包括:树形结构的文件系统、设立单独的程序用于解释命令(shell),以及将文件作为无结构字节流看待的概念。

1970年,AT&T的工程师们又在刚购进的Digital PDP-11小型机上,以汇编语言重写了UNIX,当时,Digital PDP-11算得上是最新颖、功能也最为强劲的计算机了。从大多数UNIX实现(包括Linux)沿用至今的各种名称上,仍能发现这一PDP-11实现所残留的历史遗迹。

未过多久,Dennis Ritchie(Thompson在bell实验室的同事,UNIX开发的早期合作者)设计并实现出了C编程语言。这里有一个演变过程:C语言传承自早期的解释型语言——B语言;B语言最初由Thompson实现,但其所包含的许多理念却来自于更早期的编程语言——BCPL。到了1973年,C语言步入了成熟期,人们能够使用这一新语言重写几乎整个UNIX内核。UNIX因此也一变而为最早以高级语言开发而成的操作系统之一,这也促成了UNIX系统后续向其他硬件架构的移植。

从C语言的起源不难看出为什么C语言及其“后裔”C++是当今使用最为广泛的系统编程语言。早期流行的编程语言其设计初衷并不在于此,例如:FORTRAN语言意在帮助工程师和科研工作者们进行数学计算,COBOL语言则是在商业系统中用来处理面向记录的数据流。C语言的出现,填补了当时系统编程方面的语言空白。与FORTRAN和COBOL不同(这两种编程语言均由大型组织设计开发),C语言的设计理念和设计需求出自于几位程序员的构思,他们的目标很单纯:为实现UNIX内核及其相关软件而开发一种高层语言。像UNIX操作系统本身一样,C语言由专业程序员设计而为己用。其最终结果堪称完美:C语言的设计前后连贯,且支持模块化设计,成为短小精干、高效实用、功能强大的编程语言。UNIX的第一版到第六版

1969~1979年间,UNIX历经了多次发布,也称为版本(edition)。实质上,这些发布是AT&T对UNIX进行演进开发时的一系列版本快照。[Salus,1994]记录了UNIX前六版的发布日期如下。● 1971年11月发布的第一版:当时,UNIX还运行在PDP-11上,但

已附带了FORTRAN编译器,许多被沿用至今的程序都已有了雏

形,这包括:ar、cat、chmod、chown、cp、dc、ed、find、ln、

ls、mail、mkdir、mv、rm、sh、su以及who。● 1972年6月发布的第二版:当时,AT&T内有10台计算机安装了

UNIX。● 1973年2月发布的第三版:该版本包括了C编译器,以及管道的

首个实现。● 1973年11月发布的第四版:这也是几乎完全以C语言重写的首个

UNIX版本。● 1974年6月发布的第五版:当时,UNIX的装机数已经超过了50台。● 1975年3月发布的第六版:这也是在AT&T之外广泛使用的首个

UNIX版本。

在此期间,UNIX使用范围从AT&T自内而外逐步扩展,声名也随之远播。读者甚众的《ACM通信》杂志刊载了一篇关于UNIX的论文([Ritchie & Thompson, 1974]),这对UNIX知名度的提升功莫大焉。

当时,在美国政府的授权下,AT&T垄断着全美电信市场。AT&T与美国政府达成的协议条款禁止AT&T涉足软件销售行业——这意味着,AT&T不能将UNIX作为产品销售。相反,从1974年的UNIX第五版开始,AT&T准许高校在支付象征性的发布费用后使用UNIX系统——这一现象尤以第六版为烈。UNIX系统的高校发布版包括了相关文档及内核源码(当时,内核源码约为10 000行左右)。

AT&T对高校发布的UNIX极大促进了这一操作系统的普及和使用。时至1977年,UNIX已经在约 500 个站点中运行,其中包括了全美及其他国家的 125 所大学。当时的商业操作系统非常昂贵,UNIX则为高校提供了一种交互式多用户操作系统,可谓物美价廉。此外,各校的计算机系还籍此获得了“鲜活”的操作系统源码,可以对源码进行修改,还可供学生们学习、实验之用。一些以UNIX知识为武装的学生后来成为UNIX“传教士”。另外一些学生则组建或加盟了大量新兴公司,其业务主要是销售廉价的计算机工作站,而运行于其上的正是易于移植的UNIX操作系统。BSD和System V的诞生

发布于1979年1月的UNIX第七版改善了系统的可靠性,配备了增强型的文件系统。该版本还附带了不少新的工具软件,其中包括:awk、make、sed、tar、uucp、Bourne shell以及FORTRAN 77编译器。第七版UNIX发布的重要意义还在于,从该版本起,UNIX分裂为了两大分支:BSD和System V。接下来会简要描述二者的由来。

受母校加州大学伯克利分校之邀,Thompson于1975/1976学年曾担任该校的客座教授。在此期间,他与研究生们一起为UNIX开发了许多新特性。(他的学生之一,Bill Joy,后来与人共同组建了SUN微系统公司——一家最早涉足UNIX工作站市场的公司。)光阴荏苒,许多UNIX的新工具和新特性又陆续在伯克利分校问世,这包括:C shell、vi编辑器、一种改进型的文件系统(伯克利快速文件系统)、sendmail、Pascal语言编译器,以及用于新型Digital VAX架构的虚拟内存管理机制。

这一命名为BSD(伯克利软件发布,Berkeley Software Distribution)的UNIX版本(包括源码在内)分发颇广。1979年12月,诞生了首个完整的UNIX发布版3BSD。(之前发布的Berkeley-BSD和2BSD并非完整的UNIX发布版,仅含由伯克利分校开发的新工具。)

1983年,加州大学伯克利分校的计算机系统研究组(Computer Systems Research Group)发布了4.2BSD。该版本的发布意义深远,因为其包含了完整的TCP/IP实现,其中包括套接字应用编程接口(API)以及各种网络工具。4.2BSD及其前身4.1BSD在世界上多所大学开始广为流传。以这两者为基础,还形成了SunOS操作系统(首发于1983年)——这一由SUN公司销售的UNIX变种。其他重要的BSD版本还有发布于1986年的4.3BSD,以及发布于1993年的最终版本4.4BSD。首批UNIX向非PDP-11硬件机型的移植发生在1977年和1978年,当时,Dennis Ritchie和Steve Johnson将UNIX移植到了Interdata 8/32上,与此同时,澳大利亚Wollongong大学的Richard Miller也将其移植到了Interdata 7/32上。伯克利分校针对Digital Vax架构的移植——也称为32V,则基于John Reiser和Tom Lodon较早前(1978年)的工作成果。该移植本质上与PDP-11上的UNIX第七版相同,只是支持的地址空间更大、数据类型更宽罢了。

与此同时,美国的反托拉斯法案强制对 AT&T 进行拆分(于20世纪70年代中期开始立案,到1982年AT&T正式解体)。随着其在电话系统市场垄断地位的丧失,AT&T 也因而获准销售UNIX。这也催生了1981年System III(3)的发布。System III由AT&T所属的UNIX支撑团队(UNIX Support Group,USG)研发,该团队雇佣了数以百计的研发人员来从事UNIX系统的增强以及应用开发(尤其针对文档预备软件包和软件开发工具)。1983年,System V的首个发布版又接踵而至,在经过一系列发布后,USG最终于1989年推出了System V Release 4(SVR4),此时的System V纳入了BSD的诸多特性,包含联网能力。AT&T将System V授权给不同厂商,这些厂商又将其作为自身UNIX实现的基础。

因此,除了遍布于学术界的各种BSD发布版外,到20世纪80年代末,商业性质的UNIX实现在各种硬件架构上都有了广泛应用。这包括:SUN公司的SunOS,以及后来的Solaris;Digital公司的Ultrix和OSF/1(在历经一系列更名和收购后,现称为HP Tru64 UNIX);IBM公司的AIX;HP公司的HP-UX;NeXT公司的NeXTStep;在Apple Macintosh机上的A/UX;以及Microsoft和SCO公司联合为Intel x86-32架构开发的XENIX。(贯穿本书,我们将x86-32架构上的Linux实现称为Linux/x86-32。)这一局面与当时典型的专有硬件搭配专有操作系统的模式形成了鲜明对照,那时,每个厂商只生产一种或至多几种专有的计算机芯片架构,然后再销售运行于该硬件架构之上的专有操作系统。大多数厂商系统的这种专有性,意味着消费者只能在一棵树上“吊死”。转换到另一专有操作系统和硬件平台,其代价十分高昂,不但需要移植现有应用,还需要对操作人员进行重新培训。从商业角度来看,考虑到上述因素,加之各厂商纷纷推出了廉价的单用户UNIX工作站,具备可移植性的UNIX系统魅力逐渐开始“凸显”。1.2 Linux简史

术语Linux通常用来指代完整的类UNIX(UNIX-like)操作系统,Linux内核只是其中的一部分。这么定义多少有些措辞不当,因为一般商业Linux发布版中所含的诸多关键组件实际上发源于另一项目,早在Linux问世前几年就已经启动了。1.2.1 GNU项目

1984年,Richard Stallman之前一直供职于MIT的一位天赋异禀的程序员,开始着手创建一个“自由的(free)”UNIX实现。Stallman的观点属于道德层面,而对“free”一词的定义则属于法律范畴而非经济范畴(请参见http://www.gnu.org/philosophy/free-sw.html)。然而,Stallman所描述的这一法律意义上的“自由(freedom)”却蕴含着言外之意:应可免费或以低价获得诸如操作系统之类的软件。

对于那些在专有操作系统上强加限制条款的计算机厂商来说,Stallman 的这一举动无疑妨害了他们。所谓的限制条款是指:在一般情况下,计算机软件的消费者不但无权阅读自己所购软件的源码,而且还不能复制、更改及重新发行所购软件。Stallman指出,在这种体制之下,只会造成程序员之间勾心斗角、敝帚自珍的局面,无法实现工作协同和成果共享。

与之针锋相对,为开发出一套完整而又可自由获取,包含内核以及所有相关软件包的类UNIX系统,Stallman发起了GNU项目(“GNU’s not UNIX”的递归缩写形式),并积极邀请有志之士加盟。1985年,Stallman创立了非盈利机构——自由软件基金会(FSF),以支持GNU项目和广义意义上的自由软件开发。GNU项目启动之时,BSD还不具备Stallman所指的那种“free”属性。使用BSD不但仍需获得AT&T的许可,而且用户不得随意修改并重新发布BSD中AT&T拥有产权的代码部分。

GNU项目的重要成果之一是制定了GNU GPL(通用公共许可协议),这也是Stallman倡导的自由(free)软件概念在法律上的体现。Linux发布版中的大多数软件,包括Linux内核,都是以GPL或与之类似的许可协议发布的。以GPL许可协议发布的软件不但必须开放源码,

试读结束[说明:试读内容隐藏了图片]

下载完整电子书

若在网站上没有找合适的书籍,可联系网站客服获取,各类电子版图书资料皆有。

客服微信:xzh432

登入/注册
卧槽~你还有脸回来
没有账号? 忘记密码?