Linux Programming By Example 这本书断断续续地终于差不多全看完了,真是惭愧,买了一年了才看完……(不过中间还是看了不少其他的书的,SICP 就是其中之一)
总的来说这本书很不错,用来入门是非常好的。我感觉最出色的地方在于书里面用 production code 来讲解系统 API 的使用,由此可以看到健壮的代码是什么样的,而且可以学到不少编程技巧,同时还可以锻炼一下读代码的能力。(以前想看 Code Reading,不过感觉比较吃力,现在也许会好些了) 书里面的 production code 有来自 V7 Unix, GLIBC, GNU coreutils, GNU make, gawk (作者 Arnold Robbins 是 gawk 的维护者)。虽然书名是 Linux Programming,不过实际上不是专门针对 Linux 的,也覆盖了其他的 UNIX 系统,包括 BSD, Solaris 等,对 API 都标注上是 ISO C, POSIX, XSI, 具体某个特定的 UNIX 还是 GLIBC 提供的,而且提供了不少编写 portable code 的建议。大多数的章节都写的不错,只是觉得讲 Signal 的那章太罗嗦了。这个话题本来是比较复杂,作者用了三个 episode 一步一步从最古老容易产生 race condition 的 signal handling API 讲到最新最 powerful 最安全的 API,虽然内容全了,但是我头也大了。
可惜书看的时间太长了,也没有把精彩的地方记下来,遗憾啊。就写下现在记得的一些吧。
第三章中的从 CNU make 3.8 中抽出的 readline 函数代码,这个其实很实用,GLIBC 中有现成的函数可以使用,getline。看一下 readline 的实现,在没有 GLIBC 的系统上需要时自己实现一个好了。
第四章中 V7 cat 的源代码。这个 cat 检查了输入文件和输出文件为同一个文件的情况 (重定向带来的),这个如果我自己写 cat 时不会想到的。
第五章讲 UNIX 文件系统的一些概念讲的很不错。这一章最后有的习题要自己实现 getcwd 的功能,这个问题我是做错的,在处理根目录的时候。问题在于 /home 这样的目录我是用单独的分区挂载到根目录的,直接利用 .. 不停的向上一级目录走到最后是没有办法得到 /home 这个目录名的。看了第八章以后再做这个问题可能会比较好。coreutils 中的 pwc 其实就自己实现了一个 getcwd,看看人家是怎么实现的吧。
十三章讲国际化(终于知道 i18n 中的 18 是什么意思了,居然 internationalization 在起始的 i 和结束的 n 之间有 18 个字母,汗,老外不知道是怎么想的,还有 l10n 之类的都是这个意思),主要讲 locales 和 C library 的关系, gettext 简单使用,终于搞明白了那么多的 locales 环境变量究竟是做什么用的 (如果作为一个普通用户的话这些恐怕是很难弄清楚的了,当然普通用户需要知道的越少越好,可有时候不知道又不行,这方面 GNU/Linux 对普通用户确实不太友好) 还有一些关于 multibyte character encoding 的信息,内容少了点,不过还是澄清了 character set, character set encoding 和 language 这三个概念。以前就看过关于 Unicode 的文章,所以关于 multibyte character 的内容对我帮助不大。
第十五章 Debugging 很不错,学到了不少技巧。比如用 C99 中的 variadic macro 来定义一些调试打印语句,如
#ifdef MYAPPDEBUG #define DPRINT(mesg, …) fprintf(stderr, mesg, __VA_ARGS__) #else #define DPRINT(mesg, …) #endif
这样是解决了多个参数的问题,不过如果只有一个参数的话这个宏就又不能使用了。另外还介绍了一些调试工具和库,如 gdb, dbug, dmalloc, valgrind 等等。
之前都是把 APUE 当参考,接下来正式看了,不过为了避免重复就挑感兴趣和没有接触过的看了。