第1章 入门 1
1.1 UNIX、Linux和GNU简介 1
1.1.1 什么是UNIX 1
1.1.2 什么是Linux 2
1.1.3 GNU项目和自由软件基金会 3
1.1.4 Linux发行版 3
1.2 Linux程序设计 4
1.2.1 Linux程序 4
1.2.2 C语言编译器 5
1.2.3 开发系统导引 6
1.3 获得帮助 11
1.4 小结 13
第2章 shell程序设计 14
2.1 为什么使用shell编程 14
2.2 一点哲学 15
2.3 什么是shell 15
2.4 管道和重定向 17
2.4.1 重定向输出 17
2.4.2 重定向输入 18
2.4.3 管道 18
2.5 作为程序设计语言的shell 19
2.5.1 交互式程序 19
2.5.2 创建脚本 20
2.5.3 把脚本设置为可执行 21
2.6 shell的语法 22
2.6.1 变量 22
2.6.2 条件 26
2.6.3 控制结构 28
2.6.4 函数 39
2.6.5 命令 42
2.6.6 命令的执行 57
2.6.7 here文档 61
2.6.8 调试脚本程序 62
2.7 迈向图形化:dialog工具 63
2.8 综合应用 67
2.8.1 需求 67
2.8.2 设计 67
2.8.3 应用程序的说明 76
2.9 小结 76
第3章 文件操作 77
3.1 Linux文件结构 77
3.1.1 目录 78
3.1.2 文件和设备 78
3.2 系统调用和设备驱动程序 79
3.3 库函数 80
3.4 底层文件访问 81
3.4.1 write系统调用 81
3.4.2 read系统调用 82
3.4.3 open系统调用 83
3.4.4 访问权限的初始值 84
3.4.5 其他与文件管理有关的系统调用 87
3.5 标准I/O库 89
3.5.1 fopen函数 90
3.5.2 fread函数 91
3.5.3 fwrite函数 91
3.5.4 fclose函数 91
3.5.5 fflush函数 92
3.5.6 fseek函数 92
3.5.7 fgetc、getc和getchar函数 92
3.5.8 fputc、putc和putchar函数 92
3.5.9 fgets和gets函数 93
3.6 格式化输入和输出 93
3.6.1 printf、fprintf和sprintf函数 93
3.6.2 scanf、fscanf和sscanf函数 95
3.6.3 其他流函数 97
3.6.4 文件流错误 98
3.6.5 文件流和文件描述符 98
3.7 文件和目录的维护 99
3.7.1 chmod系统调用 99
3.7.2 chown系统调用 99
3.7.3 unlink、link和symlink系统调用 99
3.7.4 mkdir和rmdir系统调用 100
3.7.5 chdir系统调用和getcwd函数 100
3.8 扫描目录 100
3.8.1 opendir函数 101
3.8.2 readdir函数 101
3.8.3 telldir函数 101
3.8.4 seekdir函数 102
3.8.5 closedir函数 102
3.9 错误处理 104
3.9.1 strerror函数 105
3.9.2 perror函数 105
3.10 /proc文件系统 105
3.11 高级主题:fcntl和mmap 109
3.11.1 fcntl系统调用 109
3.11.2 mmap函数 110
3.12 小结 112
第4章 Linux环境 113
4.1 程序参数 113
4.1.1 getopt 115
4.1.2 getopt_long 117
4.2 环境变量 119
4.2.1 环境变量的用途 120
4.2.2 environ变量 121
4.3 时间和日期 122
4.4 临时文件 128
4.5 用户信息 130
4.6 主机信息 132
4.7 日志 134
4.8 资源和限制 138
4.9 小结 142
第5章 终端 143
5.1 对终端进行读写 143
5.2 与终端进行对话 147
5.3 终端驱动程序和通用终端接口 149
5.3.1 概述 150
5.3.2 硬件模型 150
5.4 termios结构 151
5.4.1 输入模式 152
5.4.2 输出模式 152
5.4.3 控制模式 153
5.4.4 本地模式 154
5.4.5 特殊的控制字符 154
5.4.6 终端速度 157
5.4.7 其他函数 157
5.5 终端的输出 160
5.5.1 终端的类型 160
5.5.2 识别终端类型 161
5.5.3 使用terminfo功能标志 163
5.6 检测击键动作 168
5.7 虚拟控制台 170
5.8 伪终端 171
5.9 小结 171
第6章 使用curses函数库管理基于文本的屏幕 172
6.1 用curses函数库进行编译 172
6.2 基本概念 173
6.3 初始化和重置函数 175
6.4 输出到屏幕 176
6.5 从屏幕读取 176
6.6 清除屏幕 177
6.7 移动光标 177
6.8 字符属性 178
6.9 键盘 180
6.9.1 键盘的工作模式 180
6.9.2 键盘输入 181
6.10 窗口 182
6.10.1 WINDOW结构 182
6.10.2 通用函数 183
6.10.3 移动和更新屏幕 184
6.10.4 优化屏幕刷新 187
6.11 子窗口 187
6.12 keypad模式 190
6.13 彩色显示 192
6.14 pad 194
6.15 CD唱片应用程序 196
6.16 小结 210
第7章 数据管理 211
7.1 内存管理 211
7.1.1 简单的内存分配 211
7.1.2 分配大量的内存 212
7.1.3 内存的滥用 215
7.1.4 空指针 216
7.1.5 内存的释放 217
7.1.6 其他内存分配函数 218
7.2 文件锁定 219
7.2.1 创建锁文件 219
7.2.2 锁定区域 222
7.2.3 锁定状态下的读写操作 224
7.2.4 文件锁的竞争 229
7.2.5 其他锁命令 233
7.2.6 死锁 233
7.3 数据库 234
7.3.1 dbm数据库 234
7.3.2 dbm例程 235
7.3.3 dbm访问函数 236
7.3.4 其他dbm函数 239
7.4 CD唱片应用程序 241
7.4.1 更新设计 241
7.4.2 使用dbm数据库的CD唱片应用程序 242
7.5 小结 259
第8章 MySQL 260
8.1 安装 260
8.1.1 预编译软件包 261
8.1.2 安装后的配置 262
8.1.3 安装后的故障修复 265
8.2 MySQL管理 266
8.2.1 命令 266
8.2.2 创建用户并赋予权限 269
8.2.3 密码 271
8.2.4 创建数据库 271
8.2.5 数据类型 272
8.2.6 创建表格 273
8.2.7 图形化工具 275
8.3 使用C语言访问MySQL数据 277
8.3.1 连接例程 277
8.3.2 错误处理 281
8.3.3 执行SQL语句 282
8.3.4 更多的函数 295
8.4 CD数据库应用程序 295
8.4.1 创建表格 296
8.4.2 添加数据 298
8.4.3 使用C语言访问应用程序数据 300
8.5 小结 309
第9章 开发工具 311
9.1 多个源文件带来的问题 311
9.2 make命令和makefile文件 312
9.2.1 makefile的语法 312
9.2.2 make命令的选项和参数 312
9.2.3 makefile文件中的注释 315
9.2.4 makefile文件中的宏 315
9.2.5 多个目标 317
9.2.6 内置规则 319
9.2.7 后缀和模式规则 320
9.2.8 用make命令管理函数库 321
9.2.9 高级主题:makefile文件和子目录 322
9.2.10 GNU make和gcc 323
9.3 源代码控制 324
9.3.1 RCS 324
9.3.2 SCCS 329
9.3.3 RCS和SCCS的比较 329
9.3.4 CVS 330
9.3.5 gCVS 333
9.3.6 BitKeeper 334
9 4 编写使用手册 334
9.5 发行软件 337
9.5.1 patch程序 337
9.5.2 其他软件发行工具 339
9.6 RPM软件包 341
9.6.1 使用RPM软件包文件 341
9.6.2 安装RPM软件包 342
9 6.3 创建RPM软件包 342
9.7 其他软件包格式 350
9.8 开发环境 350
9.8.1 xwpe 351
9.8.2 C-Forge 352
9.8.3 KDevelop 352
9.8.4 其他开发环境 354
9.9 小结 354
第10章 调试 355
10.1 错误类型 355
10.2 常用调试技巧 356
10.2.1 有漏洞的程序 356
10.2.2 代码检查 358
10.2.3 取样法 359
10.2.4 无需重新编译的调试技巧 361
10.2.5 程序的受控执行 361
10.3 使用gdb进行调试 362
10.3.1 启动gdb 362
10.3.2 运行一个程序 363
10.3.3 栈跟踪 363
10.3.4 检查变量 364
10.3.5 列出程序源代码 364
10.3.6 设置断点 365
10.3.7 用调试器打补丁 368
10.3.8 深入学习gdb 369
10.4 其他调试工具 369
10.4.1 lint:清理程序中的“垃圾” 370
10.4.2 函数调用工具 371
10.4.3 用prof/gprof产生执行记录 373
10.5 断言 374
10.6 内存调试 375
10.6.1 ElectricFence函数库 376
10.6.2 valgrind 377
10.7 小结 379
第11章 进程和信号 380
11.1 什么是进程 380
11.2 进程的结构 380
11.2.1 进程表 382
11.2.2 查看进程 382
11.2.3 系统进程 383
11.2.4 进程调度 384
11.3 启动新进程 385
11.3.1 替换进程映像 387
11.3.2 复制进程映像 389
11.3.3 等待一个进程 391
11.3.4 僵尸进程 393
11.3.5 输入和输出重定向 394
11.3.6 线程 396
11.4 信号 396
11.4.1 发送信号 399
11.4.2 健壮的信号接口 401
11.4.3 信号集 403
11.5小结 407
第12章 POSIX线程 408
12.1 什么是线程 408
12.2 第一个线程程序 410
12.3 同时执行 413
12.4 同步 414
12.4.1 用信号量进行同步 415
12.4.2 用互斥量进行同步 419
12.5 线程的属性 423
12.6 取消一个线程 427
12.7 多线程 430
12.8 小结 432
第13章 进程间通信:管道 433
13.1 什么是管道 433
13.2 进程管道 434
13.3 将输出送往popen 435
13.3.1 传递更多的数据 436
13.3.2 如何实现popen 437
13.4 pipe调用 438
13.5 父进程和子进程 441
13.5.1 管道关闭后的读操作 443
13.5.2 把管道用作标准输入和标准输出 443
13.6 命名管道:FIFO 446
13.6.1 访问FIFO文件 447
13.6.2 高级主题:使用FIFO的客户/服务器应用程序 454
13.7 CD数据库应用程序 457
13.7.1 目标 458
13.7.2 实现 459
13.7.3 客户接口函数 461
13.7.4 服务器接口 467
13.7.5 管道 471
13.7.6 对CD数据库应用程序的总结 476
13.8 小结 476
第14章 信号量、共享内存和消息队列 477
14.1 信号量 477
14.1.1 信号量的定义 478
14.1.2 一个理论性的例子 478
14.1.3 Linux的信号量机制 479
14.1.4 使用信号量 481
14.2 共享内存 485
14.2.1 shmget函数 486
14.2.2 shmat函数 486
14.2.3 shmdt 487
14.2.4 shmctl 487
14.3 消息队列 491
14.3.1 msgget函数 491
14.3.2 msgsnd函数 492
14.3.3 msgrcv函数 492
14.3.4 msgctl函数 493
14.4 CD数据库应用程序 496
14.5 IPC状态命令 500
14.5.1 信号量 500
14.5.2 共享内存 500
14.5.3 消息队列 500
14.6 小结 501
第15章 套接字 502
15.1 什么是套接字 502
15.2 套接字连接 502
15.2.1 套接字属性 506
15.2.2 创建套接字 508
15.2.3 套接字地址 509
15.2.4 命名套接字 509
15.2.5 创建套接字队列 510
15.2.6 接受连接 510
15.2.7 请求连接 511
15.2.8 关闭套接字 511
15.2.9 套接字通信 512
15.2.10 主机字节序和网络字节序 514
15.3 网络信息 515
15.3.1 因特网守护进程 520
15.3.2 套接字选项 521
15.4 多客户 522
15.4.1 select系统调用 524
15.4.2 多客户 527
15.5 数据报 531
15.6 小结 533
第16章 用GTK+进行GNOME编程 534
16.1 X窗口系统简介 534
16.1.1 X服务器 534
16.1.2 X客户端 535
16.1.3 X协议 535
16.1.4 Xlib库 535
16.1.5 X工具包 535
16.1.6 窗口管理器 535
16.1.7 创建GUI的其他方法——平台无关的窗口API 536
16.2 GTK+简介 536
16.2.1 GLib类型系统 536
16.2.2 GTK+对象系统 537
16.2.3 GNOME简介 538
16.2.4 安装GNOME/GTK+开发库 539
16.3 事件、信号和回调函数 541
16.4 包装盒 543
16.5 GTK+窗口部件 546
16.5.1 GtkWindow 546
16.5.2 GtkEntry 547
16.5.3 GtkSpinButton 550
16.5.4 GtkButton 551
16.5.5 GtkTreeView 554
16.6 GNOME窗口部件 558
16.7 GNOME菜单 559
16.8 对话框 563
16.8.1 GtkDialog 563
16.8.2 模态对话框 564
16.8.3 非模态对话框 565
16.8.4 GtkMessageDialog 566
16.9 CD数据库应用程序 567
16.10 小结 578
第17章 用Qt进行KDE编程 579
17.1 KDE和Qt简介 579
17.2 安装Qt 580
17.3 信号和槽 582
17.4 Qt窗口部件 587
17.4.1 QLineEdit 587
17.4.2 Qt按钮 590
17.4.3 QComboBox 594
17.4.4 QListView 597
17.5 对话框 599
17.5.1 QDialog 599
17.5.2 QMessageBox 601
17.5.3 QInputDialog 602
17.5.4 使用qmake简化makefile文件的编写 603
17.6 菜单和工具栏 604
17.7 使用KDE/Qt编写CD数据库应用程序 607
17.8 小结 615
第18章 设备驱动程序 616
18.1 编写设备驱动程序 616
18.2 设备 617
18.2.1 设备类型 617
18.2.2 用户空间与内核空间 618
18.3 字符设备 623
18.4 字符设备驱动程序示例:schar 626
18.5 时间和jiffies 643
18.5.1 小的延时 644
18.5.2 定时器 645
18.5.3 让出处理器 647
18.5.4 任务队列 648
18.5.5 预定义任务队列 649
18.6 内存管理 650
18.6.1 虚拟内存区 650
18.6.2 地址空间 651
18.6.3 内存地址的类型 652
18.6.4 在设备驱动程序中申请内存 652
18.6.5 在用户空间和内核空间之间传递数据 654
18.6.6 移动更多的数据 655
18.6.7 简单的内存映射 656
18.6.8 I/O内存 657
18.6.9 Iomap中的设备分配 659
18.6.10 I/O内存的mmap操作 659
18.7 I/O端口 661
18.7.1 中断处理 662
18.7.2 IRQ处理函数 665
18.7.3 下半部 666
18.7.4 可重入性 666
18.7.5 禁止单个中断 667
18.7.6 原子操作 668
18.7.7 保护临界区 668
18.8 块设备 670
18.8.1 radimo:简单的RAM盘模块 670
18.8.2 介质的更换 673
18.8.3 块设备的ioctl操作 673
18.8.4 request函数 673
18.8.5 缓冲区缓存 675
18.8.6 进一步学习 677
18.9 调试 677
18.9.1 Oops回溯法 677
18.9.2 调试模块 679
18.9.3 魔术键 680
18.9.4 内核调试器——kdb 680
18.9.5 远程调试 681
18.9.6 调试中的注意事项 681
18.10 可移植性 681
18.10.1 数据类型 681
18.10.2 字节序 682
18.10.3 数据的对齐 682
18.11 内核源代码剖析 682
18.12 小结 684
第19章 Linux标准 685
19.1 C编程语言 686
19.1.1 发展历史简介 686
19.1.2 GNU编译器集合 686
19.1.3 gcc选项 687
19.2 接口和LSB 688
19.2.1 LSB标准函数库 689
19.2.2 LSB用户和组 690
19.2.3 LSB系统初始化 690
19.3 文件系统层次标准 691
19.4 进一步学习标准 693
19.5 小结 694