凯利斯克 (Michael Kerrisk),全球顶尖的Linux内核黑客;具有20多年的UNIX系统使用和编程经验;自2004年起,开始维护手册页项目(该项目旨在生成描述Linux内核以及glibc编程API的手册页);撰写或合著了250多篇手册页;极参与对Linux内核/用户空间接口的测试和设计评审工作。第1章 历史和标准 11.1 UNIX和C语言简史 11.2 Linux简史 41.2.1 GNU项目 41.2.2 Linux内核 51.3 标准化 81.3.1 C编程语言 81.3.2 首个POSIX标准 91.3.3 X/Open公司和TheOpenGroup 101.3.4 SUSv3和POSIX.1—2001 101.3.5 SUSv4和POSIX.1—2008 121.3.6 UNIX标准时间表 121.3.7 实现标准 141.3.8 Linux、标准、Linux标准规范(LinuxStandardBase) 141.4 总结 15第2章 基本概念 172.1 操作系统的核心—内核 172.2 shell 192.3 用户和组 202.4 单根目录层级、目录、链接及文件 212.5 文件I/O模型 232.6 程序 242.7 进程 252.8 内存映射 272.9 静态库和共享库 282.10 进程间通信及同步 282.11 信号 292.12 线程 302.13 进程组和shell任务控制 302.14 会话、控制终端和控制进程 302.15 伪终端 312.16 日期和时间 312.17 客户端服务器架构 322.18 实时性 322.19 proc文件系统 332.20 总结 33第3章 系统编程概念 343.1 系统调用 343.2 库函数 363.3 标准C语言函数库;GNUC语言函数库(glibc) 373.4 处理来自系统调用和库函数的错误 383.5 关于本书示例程序的注意事项 403.5.1 命令行选项及参数 403.5.2 常用的函数及头文件 403.6 可移植性问题 493.6.1 特性测试宏 493.6.2 系统数据类型 513.6.3 其他的可移植性问题 533.7 总结 543.8 练习 55第4章 文件I/O:通用的I/O模型 564.1 概述 564.2 通用I/O 584.3 打开一个文件:open() 584.3.1 open()调用中的flags参数 604.3.2 open()函数的错误 634.3.3 creat()系统调用 644.4 读取文件内容:read() 644.5 数据写入文件:write() 654.6 关闭文件:close() 664.7 改变文件偏移量:lseek() 664.8 通用I/O模型以外的操作:ioctl() 704.9 总结 714.10 练习 71第5章 深入探究文件I/O 725.1 原子操作和竞争条件 725.2 文件控制操作:fcntl() 755.3 打开文件的状态标志 755.4 文件描述符和打开文件之间的关系 765.5 复制文件描述符 785.6 在文件特定偏移量处的I/O:pread()和pwrite() 805.7 分散输入和集中输出(Scatter—GatherI/O):readv()和writev() 815.8 截断文件:truncate()和ftruncate()系统调用 845.9 非阻塞I/O 845.10 大文件I/O 855.11 /dev/fd目录 885.12 创建临时文件 885.13 总结 905.14 练习 90第6章 进程 926.1 进程和程序 926.2 进程号和父进程号 936.3 进程内存布局 946.4 虚拟内存管理 976.5 栈和栈帧 996.6 命令行参数(argc,argv) 996.7 环境列表 1016.8 执行非局部跳转:setjmp()和longjmp() 1066.9 总结 1116.9 练习 112第7章 内存分配 1137.1 在堆上分配内存 1137.1.1 调整programbreak:brk()和sbrk() 1137.1.2 在堆上分配内存:malloc()和free() 1147.1.3 malloc()和free()的实现 1177.1.4 在堆上分配内存的其他方法 1207.2 在堆栈上分配内存:alloca() 1227.3 总结 1237.4 练习 123第8章 用户和组 1248.1 密码文件:/etc/passwd 1248.2 shadow密码文件:/etc/shadow 1258.3 组文件:/etc/group 1268.4 获取用户和组的信息 1278.5 密码加密和用户认证 1328.6 总结 1358.7 练习 135第9章 进程凭证 1369.1 实际用户ID和实际组ID 1369.2 有效用户ID和有效组ID 1369.3 Set—User—ID和Set—Group—ID程序 1379.4 保存set—user—ID和保存set—group—ID 1389.5 文件系统用户ID和组ID 1399.6 辅助组ID 1409.7 获取和修改进程凭证 1409.7.1 获取和修改实际、有效和保存设置标识 1409.7.2 获取和修改文件系统ID 1459.7.3 获取和修改辅助组ID 1459.7.4 修改进程凭证的系统调用总结 1469.7.5 示例:显示进程凭证 1489.8 总结 1499.9 习题 150第10章 时间 15110.1 日历时间(CalendarTime) 15110.2 时间转换函数 15310.2.1 将time_t转换为可打印格式 15310.2.2 time_t和分解时间之间的转换 15410.2.3 分解时间和打印格式之间的转换 15510.3 时区 16110.4 地区(Locale) 16310.5 更新系统时钟 16710.6 软件时钟(jiffies) 16810.7 进程时间 16810.8 总结 17110.9 练习 172第11章 系统限制和选项 17311.1 系统限制 17411.2 在运行时获取系统限制(和选项) 17611.3 运行时获取与文件相关的限制(和选项) 17811.4 不确定的限制 17911.5 系统选项 18011.6 总结 18111.7 练习 182第12章 系统和进程信息 18312.1 /proc文件系统 18312.1.1 获取与进程有关的信息:/proc/PID 18312.1.2 /proc目录下的系统信息 18512.1.3 访问/proc文件 18612.2 系统标识:uname() 18812.3 总结 19012.4 练习 190第13章 文件I/O缓冲 19113.1 文件I/O的内核缓冲:缓冲区高速缓存 19113.2 stdio库的缓冲 19413.3 控制文件I/O的内核缓冲 19613.4 I/O缓冲小结 20013.5 就I/O模式向内核提出建议 20113.6 绕过缓冲区高速缓存:直接I/O 20213.7 混合使用库函数和系统调用进行文件I/O 20413.8 总结 20513.9 练习 205第14章 系统编程概念 20714.1 设备专用文件(设备文件) 20714.2 磁盘和分区 20814.3 文件系统 20914.4 i节点 21114.5 虚拟文件系统(VFS) 21314.6 日志文件系统 21414.7 单根目录层级和挂载点 21514.8 文件系统的挂载和卸载 21614.8.1 挂载文件系统:mount() 21714.8.2 卸载文件系统:umount()和umount2() 22214.9 高级挂载特性 22314.9.1 在多个挂载点挂载文件系统 22414.9.2 多次挂载同一挂载点 22414.9.3 基于每次挂载的挂载标志 22514.9.4 绑定挂载 22514.9.5 递归绑定挂载 22614.10 虚拟内存文件系统:tmpfs 22714.11 获得与文件系统有关的信息:statvfs() 22814.12 总结 22914.13 练习 230第15章 文件属性 23115.1 获取文件信息:stat() 23115.2 文件时间戳 23615.2.1 使用utime()和utimes()来改变文件时间戳 23815.2.2 使用utimensat()和futimens()改变文件时间戳 23915.3 文件属主 24115.3.1 新建文件的属主 24115.3.2 改变文件属主:chown()、fchown()和lchown() 24115.4 文件权限 24415.4.1 普通文件的权限 24415.4.2 目录权限 24615.4.3 权限检查算法 24615.4.4 检查对文件的访问权限:access() 24815.4.5 Set—User—ID、Set—Group—ID和Sticky位 24915.4.6 进程的文件模式创建掩码:umask() 24915.4.7 更改文件权限:chmod()和fchmod() 25115.5 I节点标志(ext2扩展文件属性) 25215.6 总结 25615.7 练习 256第16章 扩展属性 25816.1 概述 25816.2 扩展属性的实现细节 26016.3 操控扩展属性的系统调用 26016.4 总结 26416.5 练习 264第17章 访问控制列表 26517.1 概述 26517.2 ACL权限检查算法 26717.3 ACL的长、短文本格式 26817.4 ACL_mask型ACE和ACL组分类 26917.5 getfacl和setfacl命令 27017.6 默认ACL与文件创建 27117.7 ACL在实现方面的限制 27217.8 ACLAPI 27317.9 总结 28017.10 练习 280第18章 目录与链接 28118.1 目录和(硬)链接 28118.2 符号(软)链接 28318.3 创建和移除(硬)链接:link()和unlink() 28618.4 更改文件名:rename() 28918.5 使用符号链接:symlink()和readlink() 29018.6 创建和移除目录:mkdir()和rmdir() 29118.7 移除一个文件或目录:remove() 29218.8 读目录:opendir()和readdir() 29218.9 文件树遍历:nftw() 29718.10 进程的当前工作目录 30118.11 针对目录文件描述符的相关操作 30318.12 改变进程的根目录:chroot() 30418.13 解析路径名:realpath() 30618.14 解析路径名字符串:dirname()和basename() 30718.15 总结 30918.16 练习 309第19章 监控文件事件 31119.1 概述 31119.2 inotifyAPI 31219.3 inotify事件 31319.4 读取inotify事件 31519.5 队列限制和/proc文件 31919.6 监控文件的旧有系统:dnotify 32019.7 总结 32019.8 练习 320第20章 信号:基本概念 32120.1 概念和概述 32120.2 信号类型和默认行为 32320.3 改变信号处置:signal() 32920.4 信号处理器简介 33020.5 发送信号:kill() 33320.6 检查进程的存在 33420.7 发送信号的其他方式:raise()和killpg() 33520.8 显示信号描述 33620.9 信号集 33720.10 信号掩码(阻塞信号传递) 33920.11 处于等待状态的信号 34120.12 不对信号进行排队处理 34120.13 改变信号处置:sigaction() 34520.14 等待信号:pause() 34620.15 总结 34720.16 练习 347第21章 信号:信号处理器函数 34821.1 设计信号处理器函数 34821.1.1 再论信号的非队列化处理 34821.1.2 可重入函数和异步信号安全函数 34921.1.3 全局变量和sig_atomic_t数据类型 35321.2 终止信号处理器函数的其他方法 35421.2.1 在信号处理器函数中执行非本地跳转 35421.2.2 异常终止进程:abort() 35821.3 在备选栈中处理信号:sigaltstack() 35821.4 SA_SIGINFO标志 36121.5 系统调用的中断和重启 36621.6 总结 36821.7 练习 369第22章 信号:高级特性 37022.1 核心转储文件 37022.2 传递、处置及处理的特殊情况 37222.3 可中断和不可中断的进程睡眠状态 37322.4 硬件产生的信号 37422.5 信号的同步生成和异步生成 37422.6 信号传递的时机与顺序 37522.7 signal()的实现及可移植性 37622.8 实时信号 37822.8.1 发送实时信号 37922.8.2 处理实时信号 38022.9 使用掩码来等待信号:sigsuspend() 38422.10 以同步方式等待信号 38722.11 通过文件描述符来获取信号 39022.12 利用信号进行进程间通信 39322.13 早期的信号API(SystemV和BSD) 39322.14 总结 39522.15 练习 396……第23章 定时器与休眠 397第24章 进程的创建 425第25章 进程的终止 440第26章 监控子进程 447第27章 程序的执行 465第28章 详述进程创建和程序执行 487第29章 线程:介绍 509第30章 线程:线程同步 521第31章 线程:线程安全和每线程存储 539第32章 线程:线程取消 552第33章 线程:更多细节 561……