以注释“now handle optional args”开始的行
这里,如果还有余下的参数,我们将处理它们。请注意这里使用的编码术语,因为这是 Linux 中使用的典型风格。我们所做的是,用一个循环遍历参数列表检查每个参数来看它是否为选项。如果是的话,则 switch 语句会找出它是哪个选项。如果是有效选项,则在结构中设置标志。我们还设置变量以记住与该选项相关联的所有数据的值,例如,有“-l”选项时记下页长,有 “-f”时则记下打印目的地。如果选项无效,则给出错误消息并退出。
以注释“there is one more arg”开始的行
处理完所有以“-”为前缀的参数后,应检查是否还有剩余的参数。对于 selpg,最多有一个这样的参数,它被用作输入的文件名。我们调用 access() 函数两次来检查该参数是否存在以及是否可读。这确实有些多余,因为第二次调用也检查存在性(文件不存在就不可读),但我要说明的是人们也可以只检查存在性。
以注释“check some post-conditions”开始的行
这里,我们利用 C“断言”。这是 C 语言而不是 Linux 的特性,我演示它因为它是产生可靠代码的有用工具。
可通过 make 实用程序将调试版本和发行版本的制作自动化。有关这一点的简单示例,请参阅随附的 makefile(在本文后面的参考资料中)。make 是将从一个或多个文件构建应用程序的过程自动化的实用程序。它可以处理相关性,例如有这样的规则:如果源文件被修改,那么必须通过重新编译该源文件来重新生成其对应的目标文件。它还可以做许多其它的事情。
系统调用与库函数比较 — 以及一点历史知识
Linux 系统调用与 C 库函数有何不同?下面是一些介绍:
首先,就其在 C 中的最初字面意义而言,两者都是“函数”,即:一段单独定义的代码,只定义该代码一次,并可以通过名称(在其作用域内的代码中任何地方以任何次数)调用它,可以向它传递参数,而且它可以返回数值。
有趣的历史注解:Linux 操作系统的大部分都是用 C 编写,而且 C 是 Linux 的“母语”,对于操作系统层次编程(如编写内核与设备驱动程序)以及关于编写利用系统调用的应用程序(如 RDBMS、网络工具或定制的商业应用程序)的 Linux 系统编程都是如此。
这就是为什么 Linux 是非常强大的操作系统和开发环境的原因之一。作为开发人员,您可以免费并且以透明的方式获得大量操作系统的功能 — 内存管理、进程管理、文件和目录管理、设备管理、联网和线程等等。所有您要做的就是:包括那些声明您希望使用的调用的头文件并(在某些情况下)将您的代码与实现调用的库链接。
这部分上是由于历史偶然,因为 UNIX 和 C 最初基本上由 Bell Labs 同一组人员开发。事实上,C 是作为系统编程的高级语言开发的,尤其是用于编写操作系统。那以前的大多数操作系统都是用汇编语言编写,而 UNIX 自(大约)第二版以来就大部分用 C 编写,只有极少数与硬件相关的代码必须用目标平台的汇编语言编写。