第1部分 起步 1
第1章 Linux的发展历史 2
1.1 自由Unix软件简史 2
1.2 Linux的发展 3
1.3 Unix系统的概念谱系 4
1.4 Linux谱系 6
第2章 许可证和版权 7
2.1 版权 7
2.2 许可 8
2.3.2 GNU库通用公共许可证 9
2.3.1 GNU通用公共许可证 9
2.3 自由软件许可证 9
2.3.3 MIT/X/BSD风格的许可证 10
2.3.4 旧BSD风格的许可证 10
2.3.5 艺术许可证 10
2.3.6 许可证的不兼容性 10
第3章 在线系统文档 11
3.1 man手册页 11
3.2 info手册页 12
3.3 其他文档 12
第2部分 开发工具和环境 13
第4章 开发工具 14
4.1.1 Emacs 15
4.1 编辑器 15
4.1.2 vi 16
4.2 Make 16
4.2.1 复杂命令行 18
4.2.2 变量 19
4.2.3 后缀规则 20
4.3 GNU的调试器 21
4.4 跟踪程序行为 24
第5章 gcc的选项和扩展 26
5.1 gcc选项 26
5.2.2 内联函数 28
5.2.3 其他可选择的扩展关键字 28
5.2.1 long long 28
5.2 头文件 28
5.2.4 属性 29
第6章 GNU的C语言库 30
6.1 特征选择 30
6.2 POSIX接口 32
6.2.1 POSIX要求的类型 32
6.2.2 查找运行时的权能 33
6.2.3 查找和设置基本系统信息 34
6.3 兼容性 35
第7章 内存调试工具 36
7.1 存在Bug的代码 36
7.2.1 发现内存堆的损坏 38
7.2 glibc的内存检查工具 38
7.2.2 使用mtrace()来跟踪分配情况 40
7.3 利用mpr找到内存泄露 42
7.4 利用valgrind发现内存错误 43
7.5 电网 48
7.5.1 使用电网 48
7.5.2 内存对齐 49
7.5.3 其他特性 50
7.5.4 局限性 50
7.5.5 资源消耗 51
8.2 共享库 52
8.1 静态库 52
第8章 创建和使用库 52
8.3 设计共享库 53
8.3.1 管理兼容性 54
8.3.2 不兼容的库 54
8.3.3 设计兼容的库 55
8.4 构造共享库 55
8.5 安装共享库 56
例子 56
8.6 使用共享库 57
8.6.1 使用无须安装的库 58
8.6.2 提前装载库 58
9.1 进程环境 59
第9章 Linux系统环境 59
9.2 理解系统调用 60
9.2.1 系统调用的限制 60
9.2.2 系统调用的返回码 61
9.2.3 使用系统调用 62
9.2.4 通用错误返回码 63
9.3 查找头文件和库文件 67
第3部分 系统编程 69
第10章 进程模型 70
10.1 定义进程 70
10.1.1 使用线程的复杂性 70
10.1.2 Linux的方式 70
10.2.2 信用状 71
10.2 进程属性 71
10.2.1 pid及其生成 71
10.2.3 文件系统用户标识符 74
10.2.4 关于uid和gid的总结 75
10.3 进程信息 76
10.3.1 程序参数 76
10.3.2 资源的使用 78
10.3.3 建立使用限制 79
10.4 进程基本元素 80
10.4.1 创建子进程 80
10.4.2 等待子进程结束 81
10.4.3 运行新程序 82
10.4.6 终止其他进程 84
10.4.5 自我终止 84
10.4.4 用vfork()更快速地创建进程 84
10.4.7 转储内核文件信息 85
10.5 简单子进程 86
10.5.1 用system()运行和等待 86
10.5.2 从进程读或写 87
10.6 会话和进程组 88
10.6.1 会话 88
10.6.2 控制终端 89
10.6.3 进程组 89
10.6.4 孤儿进程组 90
用ladsh运行外部程序 91
10.7 介绍ladsh 91
10.8 创建克隆 103
第11章 简单的文件管理 104
11.1 文件模式 106
11.1.1 文件访问权限 106
11.1.2 文件权限修饰符 107
11.1.3 文件类型 109
11.1.4 进程的umask 109
11.2 基本的文件操作 110
11.2.1 文件描述符 110
11.2.2 关闭文件 111
11.2.3 在文件系统中打开文件 111
11.2.4 文件的读、写以及位置指针的移动 112
11.2.5 局部读和写 116
11.2.6 缩短文件 117
11.2.7 同步文件 118
11.2.8 其他操作 118
11.3 查询和修改Inode信息 119
11.3.1 查找Inode信息 119
11.3.2 一个使用stat()的简单示例 120
11.3.3 轻松确定访问权限 122
11.3.4 改变文件的访问权限 122
11.3.5 改变文件的所有者和组 123
11.3.6 改变文件的时间戳 123
11.3.7 Ext3扩展属性 124
11.4.1 创建设备文件以及命名管道的目录项 128
11.4 操作目录项 128
11.4.2 创建硬链接 130
11.4.3 使用符号链接 131
11.4.4 删除文件 132
11.4.5 重命名文件 132
11.5 操作文件描述符 132
11.5.1 改变打开文件的访问模式 133
11.5.2 修改close-on-exec标志 133
11.5.3 复制文件描述符 133
11.6 创建无名管道 134
11.7 对ladsh添加重定向 134
11.7.1 数据结构 135
11.7.2 修改代码 136
第12章 信号处理 138
12.1 信号的概念 138
12.1.1 信号的生命周期 138
12.1.2 简单信号 139
12.1.3 可靠信号 140
12.1.4 信号和系统调用 141
12.2 Linux(和POSIX)信号系统的API 142
12.2.1 发送信号 142
12.2.2 使用sigset_t 142
12.2.3 捕捉信号 143
12.2.4 操作一个进程的信号掩码 144
12.2.5 找到等待信号的集合 145
12.2.6 等待信号 146
12.3 有效信号 146
描述信号 150
12.4 编写信号处理程序 151
12.5 重新打开日志文件 152
12.6 实时信号 155
信号队列和排序 155
12.7 获取信号的信息 157
12.7.1 得到一个信号的上下文 157
12.7.2 使用信号发送数据 162
第13章 高级文件操作 165
13.1 多路输入输出 165
13.1.1 非阻塞I/O 167
13.1.2 用poll()实现多路传输 168
13.1.3 使用select()的多路传输 171
13.1.4 比较poll()和select() 175
13.1.5 使用epoll进行多路传输 177
13.1.6 比较poll()和epoll 182
13.2 内存映射 185
13.2.1 页对齐 186
13.2.2 建立内存映射 186
13.2.3 撤销映射区域 190
13.2.4 同步内存区域到磁盘 190
13.2.5 锁定内存区域 191
13.3.1 文件锁 192
13.3 文件锁定 192
13.3.2 记录锁 194
13.3.3 强制锁 198
13.3.4 租赁文件 199
13.4 read()和write()的替代方法 202
13.4.1 分散/聚集的读和写 202
13.4.2 忽略文件指针 203
第14章 目录操作 205
14.1 当前工作目录 205
14.1.1 查找当前工作目录 205
14.1.2 特殊文件“.”和“..” 206
14.3.1 创建新目录 207
14.3 创建和删除目录 207
14.1.3 当前目录 207
14.2 改变根目录 207
14.3.2 删除目录 208
14.4 读取目录的内容 208
再次读取目录内容 209
14.5 文件名匹配搜索 210
14.5.1 使用子进程 210
14.5.2 内在匹配搜索 211
14.6 为ladsh增加目录和匹配功能 215
14.6.1 增加cd和pwd 215
14.6.2 增加文件名匹配查询 216
14.7.1 使用ftw() 219
14.7 遍历文件系统的树结构 219
14.7.2 用nftw()函数进行文件树遍历 220
14.7.3 实现find功能 221
14.8 目录变更提示 224
第15章 作业控制 231
15.1 作业控制基础 231
15.1.1 重新启动进程 231
15.1.2 停止进程 231
15.1.3 处理作业控制信号 232
15.2 ladsh中的作业控制 233
第16章 终端与伪终端 238
16.1.2 控制终端 239
16.1.1 终端实用函数 239
16.1 tty操作 239
16.1.3 终端所有权 240
16.1.4 用utemper工具进行记录 241
16.1.5 手工记录 241
16.2 termios概述 250
16.3 termios实例 251
16.3.1 密码 251
16.3.2 串行通信 253
16.4 termios调试 265
16.5 termios参考 266
16.5.1 函数 267
16.5.2 窗口大小 269
16.5.4 输入模式标记 270
16.5.3 标志位 270
16.5.5 输出模式标记 272
16.5.6 控制模式标记 273
16.5.7 控制模式字符 274
16.5.8 本地模式标记 276
16.5.9 控制read() 277
16.6 伪终端 278
16.6.1 打开伪终端 278
16.6.2 打开伪终端的简单方法 279
16.6.3 打开伪终端的复杂方法 280
16.6.4 伪终端范例 284
17.1.1 理想的网络 293
第17章 socket网络 293
17.1 协议支持 293
17.1.2 实际的网络 294
17.1.3 让实际的网络变得理想 294
17.1.4 地址 295
17.2 实用函数 295
17.3 基本套接字操作 296
17.3.1 建立一个套接字 296
17.3.2 建立连接 297
17.3.3 将地址绑定到套接字 298
17.3.4 等待连接 298
17.3.5 连接到一个服务器 299
17.4.1 Unix域地址 300
17.3.6 找到连接地址 300
17.4 Unix域套接字 300
17.4.2 等待一个连接 301
17.4.3 连接到一个服务器 303
17.4.4 运行Unix域的示例 304
17.4.5 未命名的Unix域套接字 304
17.4.6 传递文件描述符 304
17.5 基于TCP/IP协议的联网机器 309
17.5.1 字节存储顺序 309
17.5.2 IPv4地址 310
17.5.3 IPv6地址 311
17.5.4 IP地址的操作 313
17.5.5 转换名称到地址 315
17.5.6 转换地址到名称 324
17.5.7 监听TCP连接 329
17.5.8 TCP客户端应用程序 331
17.6 使用UDP数据报 333
17.6.1 创建一个UDP套接字 334
17.6.2 发送和接收数据报 334
17.6.3 一个简单的tftp服务器 335
17.7 套接字错误 341
17.8 旧的网络函数 342
17.8.1 IPv4地址操作 342
17.8.2 主机域名解析 343
17.8.3 旧的主机信息查找范例 344
17.8.4 查找端口号 346
第18章 时间 349
18.1 获取时间和日期 349
18.1.1 时间和日期的表示 349
18.1.2 时间的转换,格式化和解析 351
18.1.3 时间的限制 354
18.2 使用计时器 355
18.2.1 休眠 355
18.2.2 间隔计时器 356
第19章 随机数 359
19.1 伪随机数 359
19.2 密码系统和随机数 360
第20章 虚拟控制台编程 362
20.1 起步 363
20.2 发出蜂鸣声 364
20.3 判断终端是否为虚拟控制台 365
20.4 查找当前虚拟控制台 365
20.5 管理虚拟控制台的切换 366
20.6 范例:open命令 368
第21章 Linux控制台 370
21.1 权能数据库 370
21.2 图标、字符和映射 372
21.3 Linux控制台权能 372
21.3.1 控制字符 373
21.3.2 转义字符序列 374
21.3.3 测试序列 375
21.3.4 复杂转义字符序列 375
21.4 直接写屏幕 380
第22章 编写安全程序 382
22.1 安全何时重要 382
安全何时失效 383
22.2 最小化攻击时机 383
22.2.1 放弃权限 384
22.2.2 采用辅助手段 384
22.2.3 限制文件系统的访问 385
22.3 常见的安全漏洞 385
22.3.1 缓冲区溢出 386
22.3.3 环境变量 390
22.3.2 解析文件名 390
22.3.4 运行Shell 391
22.3.5 创建临时文件 391
22.3.6 竞争状态和信号处理 392
22.3.7 关闭文件描述符 393
22.4 作为守护进程运行 394
第4部 分开发库 395
第23章 字符串的匹配 396
23.1 匹配任意字符串 396
23.2.1 Linux正则表达式 397
23.2.2 正则表达式的匹配 397
23.2 正则表达式 397
23.2.3 一个简单的grep示例 401
第24章 用S-Lang来处理终端 407
24.1 输人处理 407
24.1.1 初始化S-Lang的输入处理 408
24.1.2 恢复终端状态 409
24.1.3 从终端读取字符 409
24.1.4 检查未决的输入 409
24.2 输出处理 409
24.2.1 初始化屏幕管理 410
24.2.2 更新显示 410
24.2.3 移动光标 410
24.2.5 屏幕管理的框架程序 411
24.2.4 结束屏幕管理 411
24.2.7 输出到屏幕 412
24.2.6 切换字符集 412
24.2.8 画线和画矩形 413
24.2.9 使用颜色 416
第25章 基于散列的数据库函数库 417
25.1 概述 417
25.2 基本操作 418
25.2.1 打开qdbm文件 418
25.2.2 关闭数据库 418
25.2.3 获得文件描述符 419
25.2.4 同步数据库 419
25.3.2 顺序读取记录 420
25.3 读取记录 420
25.3.1 读取特定的记录 420
25.4 修改数据库 421
25.4.1 增加记录 421
25.4.2 删除记录 421
25.5 实例 421
第26章 解析命令行选项 428
26.1 选项表 429
26.1.1 定义选项 429
26.1.2 嵌套选项表 431
26.2 使用选项表 431
26.2.1 创建上下文 431
26.2.2 解析命令行 432
26.2.3 剩余的参数 433
26.2.4 自动帮助信息 434
26.3 使用回调(callback) 435
26.4 错误处理 439
26.5 选项别名 440
26.5.1 指定别名 440
26.5.2 使别名生效 441
26.6 解析参数字符串 441
26.7 处理额外参数 442
26.8 立用程序示例 442
第27章 运行时动态加载 443
动态加载(dl)接口 444
示例 445
第28章 用户识别和认证 447
28.1 ID到名字的转换 447
示例:id命令 449
28.2 可挂接的认证模块 452
28.2.1 PAM会话 453
28.2.2 PAM操作 454
附录 461
附录A 头文件 462
附录B Iadsh源文件 463
词汇表 481
参考文献 487