标题：Unix/Linux编程实践教程
基本信息
原书名： Understanding Unix/Linux Programming A Guide to Theory and Practice
原出版社： Pearson Education  作者： （美）Bruce Molay   
译者： 杨宗源 黄海涛
丛书名： 国外经典教材·计算机科学与技术
出版社：清华大学出版社
ISBN：7302096139
上架时间：2005-3-3
出版日期：2004 年10月
开本：16开
页码：495
版次：1-1
内容简介
操作系统是计算机最重要的系统软件。Unix操作系统历经了几十年，至今仍是主流的操作系统。本书通过解释Unix的工作原理，循序渐进地讲解实现 Unix中系统命令的方法，让读者理解并逐步精通Unix系统编程，进而具有编制Unix应用程序的能力。书中采用启发式、举一反三、图示讲解等多种方法讲授，语言生动、结构合理、易于理解。每一章后均附有大量的习题和编程练习，以供参考。
本书适合作为高等院校计算机及相关专业的教材和教学参考书，亦可作为有一定系统编程基础的开发人员的自学教材和参考手册。
作者简介
Bruce Molay，哈佛大学著名教授，从事Unix系统编程和教学十余年之久，本书就是在哈佛继续教育学院的Unix systim Programming课程的基础上，结合作者的实践、教学经验编写而成。
目录
第1章 unix系统编程概述 
1.1 介绍 
1.2 什么是系统编程 
1.2.1 简单的程序模型 
1.2.2 系统模型 
1.2.3 操作系统的职责 
1.2.4 为程序提供服务 
1.3 理解系统编程 
1.3.1 系统资源 
1.3.2 目标：理解系统编程 
1.3.3 方法：通过三个问题来理解 
1.4 从用户的角度来理解unix 
1.4.1 unix能做些什么 
1.4.2 登录--运行程序--注销 
1.4.3 目录操作 
1.4.4 文件操作 
1.5 从系统的角度来看unix 
1.5.1 用户和程序之间的连接方式 
1.5.2 网络桥牌 
1.5.3 bc：unix的计算器 
.1.5.4 从bc/dc到web 
1.6 动手实践 
1.7 工作步骤与概要图 
1.7.1 接下来的工作步骤 
1.7.2 unix的概要图 
1.7.3 unix的发展历程 
小结 
第2章 用户、文件操作与联机帮助：编写who命令 
2.1 介绍 
2.2 关于命令who 
2.3 问题1：who命令能做些什么 
2.4 问题2：who命令是如何工作的 
2.5 问题3：如何编写who 
2.5.1 问题：如何从文件中读取数据结构 
2.5.2 答案：使用open、read和close 
2.5.3 编写wh01.c 
2.5.4 显示登录信息 
2.5.5 编写wh02.c 
2.5.6 回顾与展望 
2.6 编写cp(读和写) 
2.6.1 问题1：cp命令能做些什么 
2.6.2 问题2：cp命令是如何创建/重写文件的 
2.6.3 问题3：如何编写cp 
2.6.4 unix编程看起来好像很简单 
2.7 提高文件i/o效率的方法：使用缓冲 
2.7.1 缓冲区的大小对性能的影响 
2.7.2 为什么系统调用需要很多时间 
2.7.3 低效率的wh02.c 
2.7.4 在wh02.c中运用缓冲技术 
2.8 内核缓冲技术 
2.9 文件读写 
2.9.1 注销过程：做了些什么 
2.9.2 注销过程：如何工作的 
2.9.3 改变文件的当前位置 
2.9.4 编写终端注销的代码 
2.10 处理系统调用中的错误 
小结 
第3章 目录与文件属性：编写ls 
3.1 介绍 
3.2 问题1：1s命令能做什么 
3.2.1 1s可以列出文件名和文件的属性 
3.2.2 列出指定目录或文件的信息 
3.2.3 经常用到的命令行选项 
3.2.4 问题1的答案 
3.3 文件树 
3.4 问题2：1s是如何工作的 
3.4.1 什么是目录 
3.4.2 是否可以用open、read和close来操作目录 
3.4.3 如何读目录的内容 
3.5 问题3：如何编写ls 
3.6 编写ls-1 
3.6.1 问题1：ls-1能做些什么 
3.6.2 问题2：ls-1是如何工作的 
3.6.3 用stat得到文件信息 
3.6.4 stat提供的其他信息 
3.6.5 如何实现 
3.6.6 将模式字段转换成字符 
3.6.7 将用户/组id转换成字符串 
3.6.8 编写ls2.c 
3.7 三个特殊的位 
3.7.1 set-user-id位 
3.7.2 set-group-id位 
3.7.3 sticky位 
3.7.4 用ls-1看到的特殊属性 
3.8 ls小结 
3.9 设置和修改文件的属性 
3.9.1 文件类型 
3.9.2 许可位与特殊属性位 
3.9.3 文件的链接数 
3.9.4 文件所有者与组 
3.9.5 文件大小 
3.9.6 时间 
3.9.7 文件名 
小结 
第4章 文件系统：编写pwd 
4.1 介绍 
4.2 从用户的角度看文件系统 
4.2.1 目录和文件 
4.2.2 目录命令 
4.2.3 文件操作命令 
4.2.4 针对目录树的命令 
4.2.5 目录树的深度几乎没有限制 
4.2.6 unix文件系统小结 
4.3 unix文件系统的内部结构 
4.3.1 第一层抽象：从磁盘到分区 
4.3.2 第二层抽象：从磁盘到块序列 
4.3.3 第三层抽象：从块序列到三个区域的划分 
4.3.4 文件系统的实现：创建一个文件的过程 
4.3.5 文件系统的实现：目录的工作过程 
4.3.6 文件系统的实现：cat命令的工作原理 
4.3.7 i-节点和大文件 
4.3.8 unix文件系统的改进 
4.4 理解目录 
4.4.1 理解目录结构 
4.4.2 与目录树相关的命令和系统调用 
4.5 编写pwd 
4.5.1 pwd的工作过程 
4.5.2 pwd的一种版本 
4.6 多个文件系统的组合：由多棵树构成的树 
4.6.1 装载点 
4.6.2 多重i-节点号和设备交叉链接 
4.6.3 符号链接 
小结 
第5章 连接控制：学习stty 
5.1 为设备编程 
5.2 设备就像文件 
5.2.1 设备具有文件名 
5.2.2 设备和系统调用 
5.2.3 例子：终端就像文件 
5.2.4 设备文件的属性 
5.2.5 编写write程序 
5.2.6 设备文件和i-节点 
5.3 设备与文件的不同之处 
5.4 磁盘连接的属性 
5.4.1 属性1：缓冲 
5.4.2 属性2：自动添加模式 
5.4.3 用open控制文件描述符 
5.4.4 磁盘连接小结 
5.5 终端连接的属性 
5.5.1 终端的i/o并不如此简单 
5.5.2 终端驱动程序 
5.5.3 stty命令 
5.5.4 编写终端驱动程序：关于设置 
5.5.5 编写终端驱动程序：关tx数 
5.5.6 编写终端驱动程序：关于位 
5.5.7 编写终端驱动程序：几个程序例子 
5.5.8 终端连接小结 
5.6 其他设备编程：ioctl 
5.7 文件、设备和流 
小结 
第6章 为用户编程：终端控制和信号 
6.1 软件工具与针对特定设备编写的程序 
6.2 终端驱动程序的模式 
6.2.1 规范模式：缓冲和编辑 
6.2.2 非规范处理 
6.2.3 终端模式小结 
6.3 编写一个用户程序：play_again.c 
6.4 信号 
6.4.1 ctrl-c做什么 
6.4.2 信号是什么 
6.4.3 进程该如何处理信号 
6.4.4 信号处理的例子 
6.5 为处理信号做准备：play_again4.c 
6.6 进程终止 
6.7 为设备编程 
小结 
第7章 事件驱动编程：编写一个视频游戏 
7.1 视频游戏和操作系统 
7.2 任务：单人弹球游戏(pong) 
7.3 屏幕编程：curses库 
7.3.1 介绍curses 
7.3.2 curses内部：虚拟和实际屏幕 
7.4 时间编程：sleep 
7.5 时钟编程1：alarms 
7.5.1 添加时延：sleep 
7.5.2 sleep()是如何工作的：使用unix中的alarms 
7.5.3 调度将要发生的动作 
7.6 时间编程2：间隔计时器 
7.6.1 添加精度更高的时延：usleep 
7.6.2 三种计时器：真实、进程和实用 
7.6.3 两种间隔：初始和重复 
7.6.4 用间隔计时器编程 
7.6.5 计算机有几个时钟 
7.6.6 计时器小结 
7.7 信号处理1：使用signal 
7.7.1 早期的信号处理机制 
7.7.2 处理多个信号 
7.7.3 测试多个信号 
7.7.4 信号机制其他的弱点 
7.8 信号处理2：sigaction 
7.8.1 处理多个信号：sigaction 
7.8.2 信号小结 
7.9 防止数据损毁(datacorruption) 
7.9.1 数据损毁的例子 
7.9.2 临界(criticalsections) 
7.9.3 阻塞信号：sigprocmask和sigsetops 
7.9.4 重入代码(reentrantcode)：递归调用的危险 
7.9.5 视频游戏中的临界区 
7.10 kill：从另--个进程发送的信号 
7.11 使用计时器和信号：视频游戏 
7.11.1 bounceld.c：在一条线上控制动画 
7.11.2 bounce2d.c：两维动画 
7.11.3 完成游戏 
7.12 输入信号，异步i/o 
7.12.1 使用异步i/o 
7.12.2 方法1：使用oasync 
7.12.3 方法2：使用aio..read 
7.12.4 弹球程序中需要异步读人吗 
7.12.5 异步输入、视频游戏和操作系统 
小结 
第8章 进程和程序：编写命令解释器sh 
8.1 进程=运行中的程序 
8.2 通过命令ps学习进程 
8.2.1 系统进程 
8.2.2 进程管理和文件管理 
8.2.3 内存和程序 
8.3 shell：进程控制和程序控制的--个工具 
8.4 shell是如何运行程序的 
8.4.1 shell的主循环 
8.4.2 问题1：一个程序如何运行另一个程序 
8.4.3 问题2：女口何建立新的进程 
8.4.4 问题3：父进程如何等待子进程的退出 
8.4.5 小结：shell如何运行程序 
8.5 实现一个shell：psh2.c 
8.6 思考：用进程编程 
8.7 exit和exec的其他细节 
8.7.1 进程死亡：exit和_exit 
8.7.2 exec家族 
小结 
第9章 可编程的shell、shell变量和环境：编写自己的shell 
9.1 shell编程 
9.2 什么是以及为什么要使用shell脚本语言 
9.3 smshl--命令行解析 
9.4 shell中的流程控制 
9.4.1 if语句做些什么 
9.4.2 if是女口何工作的 
9.4.3 在stash中增加if 
9.4.4 smsh2.c：修改后的代码 
9.5 shell变量：局部和全局 
9.5.1 使用shell变量 
9.5.2 变量的存储 
9.5.3 增加变量命令：built-ins 
9.5.4 效果如何 
9.6 环境：个性化设置 
9.6.1 使用环境 
9.6.2 什么是环境以及它是如何工作的 
9.6.3 在smsh中增加环境处理 
9.6.4 varlib.c的代码 
9.7 已实现的shell的功能 
小结 
第10章 i/o重定向和管道 
10.1 shell编程 
10.2 一个shell应用程序：监视系统用户 
10.3 标准i/o与重定向的若干概念 
10.3.1 概念1：3个标准文件描述符 
10.3.2 默认的连接：tty 
10.3.3 程序都输出到stdout 
10.3.4 重定向i/o的是shell而不是程序 
10.3.5 理解i/o重定向 
10.3.6 概念2：“最低可用文件描述符(lowest-available-fd)”原则 
10.3.7 两个概念的结合 
10.4 如何将stdin定向到文件 
10.4.1 方法1：closethenopen 
10.4.2 方法2：open..close..dup..close 
10.4.3 系统调用dup小结 
10.4.4 方法3：open..dup2..close 
10.4.5 shell为其他程序重定向stdin 
10.5 为其他程序重定向i/o：who]userlist 
10.6 管道编程 
10.6.1 创建管道 
10.6.2 使用fork来共享管道 
10.6.3 使用pipe、fork以及exec 
10.6.4 技术细节：管道并非文件 
小结 
第11章 连接到近端或远端的进程：服务器与socket(套接宇) 
11.1 产品和服务 
11.2 一个简单的比喻：饮料机接口 
11.3 bc：unix中使用的计算器 
11.3.1 编写bc：pipe、fork、dup、exec 
11.3.2 对协同进程的讨论 
11.3.3 fdopen：让文件描述符像文件--样使用 
11.4 popen-让进程看似文件 
11.4.1 popen的功能 
11.4.2 实现popen：使用fdopen命令 
11.4.3 访问数据：文件、应用程序接el(apl)和服务器 
11.5 socket：与远端进程相连 
11.5.1 类比：“电话中传来声音：现在时间是…” 
11.5.2 因特网时间、dap和天气服务器 
11.5.3 服务列表：众所周知的端口 
11.5.4 编写timeserv . cc时间服务器 
11.5.5 测试timeserv.c 
11.5.6 编写timecint.c：时间服务客户端 
11.5.7 测试timecint.c 
11.5.8 另一种服务器：远程的ls 
11.6 软件精灵 
小结 
第12章 连接和协议：编写web服务器 
12.1 服务器设计重点 
12.2 三个主要操作 
12.3 操作1和操作2：建立连接 
12.3.1 操作1：建立服务器端socket 
12.3.2 操作2：建立到服务器的连接 
12.3.3 socklib.c 
12.4 操作3：客户/服器的会话 
12.4.1 使用socklib.c的timeserv/timecint 
12.4.2 第2版的服务器：使用fork 
12.4.3 服务器的设计问题：diy或代理 
12.5 编写web服务器 
12.5.1 web服务器功能 
12.5.2 设计web服务器 
12.5.3 web服务器协议 
12.5.4 编写web服务器 
12.5.5 运行web服务器 
12.5.6 webserv的源程序 
12.5.7 比较web服务器 
小结 
第13章 基于数据报(datagram)的编程：编写许可证服务器 
13.1 软件控制 
13.2 许可证控制简史 
13.3 一个非计算机系统实例：轿车管理系统 
13.3.1 轿车钥匙管理描述 
13.3.2 用客户/服务器方式管理轿车 
13.4 许可证管理 
13.4.1 许可证服务系统：它做些什么 
13.4.2 许可证服务系统：如何工作 
13.4.3 一个通信系统的例子 
13.5 数据报socket 
13.5.1 流与数据报的比较 
13.5.2 数据报编程 
13.5.3 sendto和recvfrom的小结 
13.5.4 数据报应答 
13.5.5 数据报小结 
13.6 许可证服务器版本1.0 
13.6.1 客户端版本1 
13.6.2 服务器端版本1 
13.6.3 测试版本1 
13.6.4 进一步的工作 
13.7 处理现实的问题 
13.7.1 处理客户端崩溃 
13.7.2 处理服务器崩溃 
13.7.3 测试版本2 
13.8 分布式许可证服务器 
13.9 unix域socket 
13.9.1 文件名作为socket地址 
13.9.2 使用unix域socket编程 
13.10 小结；socket和服务器 
小结 
第14章 线程机制：并发函数的使用 
14.1 同一时刻完成多项任务 
14.2 函数的执行路线 
14.2.1 一个单线程程序 
14.2.2 一个多线程程序 
14.2.3 相关函数小结 
14.3 线程间的分工合作 
14.3.1 例1：incrprint.c 
14.3.2 例2：twordcount.c 
14.3.3 线程内部的分工合作：小结 
14.4 线程与进程 
14.5 线程间互通消息 
14.5.1 通知选举中心 
14.5.2 使用条件变量编写程序 
14.5.3 使用条件变量的函数 
14.5.4 回到web服务器的例子 
14.6 多线程的web服务器 
14.6.1 web服务器程序的改进 
14.6.2 多线程版本允许一个新的功能 
14.6.3 防止僵尸线程(zombiethreads)：独立线程 
14.6.4 web服务器代码 
14.7 线程和动画 
14.7.1 使用线程的优点 
14.7.2 多线程版本的bouneeld.c 
14.7.3 基于多线程机制的多重动画：tanimate.c 
14.7.4 tanimate.c中的互斥量 
14.7.5 屏幕控制线程 
小结 
第15章 进程间通信(1pc) 
15.1 编程方式的选择 
15.2 talk命令：从多个数据源读取数据 
15.2.1 同时从两个文件描述符读取数据 
15.2.2 select系统调用 
15.2.3 select与talk 
15.2.4 select与poll 
15.3 通信的选择 
15.3.1 一个问题的三种解决方案 
15.3.2 通过文件的进程间通信 
15.3.3 命名管道 
15.3.4 共享内存 
15.3.5 各种进程间通信方法的比较 
15.4 进程之间的分工合作 
15.4.1 文件锁 
15.4.2 信号量(semaphores) 
15.4.3 socket及fifo与共享的存储 
15.5 打印池 
15.5.1 多个写者、一个读者 
15.5.2 客户/服务器模型 
15.6 纵观ipc 
15.7 连接与游戏 
小结