这很简单:它声明所需变量,然后用变量 ac、av 和 &sa 调用函数 process_args()。ac 代表“参数计数”,它包含命令行参数的数目,包括命令名本身;av 代表“参数向量”,它是字符指针的指针;它以字符串数组的形式包含所有的命令行参数。&sa 是指向类型为 sp_args 的结构的指针。process_args() 返回后,已解析的参数值在 sa 结构中;我们将该变量传递至函数 process_input(),该函数选择所需的页并将其写至指定的目的地。
如果代码中任何一处出现了使处理不能继续进行之类的错误,那么我们会检索系统错误消息(如果有的话),然后将它与我们自己的消息一起显示。随后我们用错误码调用 exit() 函数;对于本实用程序,我们已经选择了对每个不同错误条件返回不同数字。不过这不是必须的;有些实用程序对任何错误条件都简单地返回 1,若成功则返回 0,而其它实用程序则将错误分类,并根据类别返回较小范围代码(比如 1、2 或 3)中的一个。规定的唯一约定是返回 0 应该表示成功而返回非零值表示失败。有关系统调用中出现错误的更多信息,请参阅系统调用错误一节。
既然所有错误都会导致退出,那么如果我们从 process_input() 函数返回,则意味着没有错误,因此我们从 main() 返回 0。
系统调用错误
当调用 Linux 系统调用(或 C 库函数)时,与调用您自己的函数时一样,有可能出现错误。按照对 C 函数的约定,在成功的情况下,函数的返回值通常要给出关于结果的一些信息,而在失败的情况下,返回值要给出关于失败原因的信息。对此有一个普遍遵守的约定。
在成功的函数或系统调用中,返回值的意义是由例程而定的;例如,read() 返回实际所读的字节数(与所要求的字节数相对,后者是 read() 的参数之一),而 fopen() 返回指向“struct FILE”的指针。
这里,我们主要讨论不成功调用的返回值。
大多数调用返回 -1、NULL 或 EOF 来表示错误。(正如我们在上面看到的,fgets() 返回 NULL 而 getc() 返回 EOF。)它们还设置名为 errno 的全局整数变量。这在 errno.h 中被声明为“extern int errno;”。该整数是对系统错误消息表的索引,这个表名为 sys_errlist(字符串数组),其最高元素的索引为 sys_nerr - 1。sys_errlist 和 sys_nerr 也都在 errno.h 中声明。
当系统调用中出现错误时,您至少可以用以下两种方式的一种来访问和显示与该错误对应的消息:通过使用 perror() 或 strerror() 函数。(这两种方式在 selpg 中都有演示。)
perror(请参阅“man perror”)接受单个字符串参数。它先将您的字符串参数写至标准错误(提供它用于定制消息),接下来写入一个冒号和一个空格,然后是系统错误消息,后面是新的一行。
strerror() 函数(请参阅“man strerror”)略有不同。它允许您将系统错误消息作为字符串进行访问。它需要整数参数 errno,该参数应该是全局 errno 变量的实际数值。您可以通过包括头文件 errno.h 来用该变量的实际名称访问它,所有使用系统调用的 C 程序(或调用系统调用的库函数)都应该包括头文件 errno.h。strerror() 将系统错误消息作为字符串返回。使用这些函数时要遵守一些条件。有关的详细信息,请参阅它们的手册页。
selpg 广泛利用这些函数以给予用户正确消息。我还提供了名为 showsyserr 的小实用程序(请参阅参考资料),它允许您查看系统错误消息。它能以两种方式之一运行,带单个命令行参数,该参数应该是 errno 值,或不带任何参数。如果向该程序传递一个参数,则它将只显示对应于该参数的消息。如果不给出参数,则它会显示所有定义的错误消息。