05 读书笔记:第1章 UNIX基础知识 (4)

1 出错处理

        当UNIX函数出错时,常常返回一个负值,而且整型变量errno通常被设置为含有附加信息的一个值。某些函数并不返回负值,而是使用另一种约定,例如,返回一个指向对象指针的大多数函数,在出错时,将返回一个null指针。

        文件<errno.h>中定义了符号errno以及可以赋予它的各种常量,这些常量都以字符E开头。

        在linux中查看出错常量,可以执行如下命令:

$ man 3 errno

        在支持线程的环境中,多个线程共享进程地址空间,每个线程都有属于它自己的局部errno以避免一个线程干扰另一个线程。

        对于errno应当知道两条规则。

                (1) 如果没有出错,则其值不会被一个例程清除。因此,仅当函数的返回值指明出错时,才检验其值。

                (2) 任一函数都不会将errno设置为0,在<errno.h>中定义的所有常量都不为0。

        《UNIX环境高级编程》P11:程序清单1-6  例示strerror 和perror(有改动)

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <errno.h>

int main(int argc, char *argv[])
{
    fprintf(stderr, "EACCES: %s\n", strerror(EACCES));
    errno = ENOENT;
    perror(argv[0]);
    exit(0);
}

        可将<errno.h>中定义的各种出错分成致命性的和非致命性的两类。对于致命性错误,无法执行恢复动作;而对于非致命性的出错,有时可以较妥善地进行处理。

PS:

        在作者的出错提示的代码中,用到了strerror函数,可以改写之前的一段代码:

#include <stdio.h>
#include <stdlib.h>
#include <dirent.h>
#include <string.h>
#include <errno.h>

int main(int argc, char *argv[])
{
    DIR             *dp;
    struct dirent   *dirp;

    if (argc != 2) {
        fprintf(stderr, "usage: ls directory_name\n");
        exit(1);
    }   

    if ( ( dp = opendir(argv[1])) == NULL) {
        fprintf(stderr, "can't open %s: %s\n", argv[1], strerror(errno));
        exit(1);
    }   

    while ( (dirp = readdir(dp)) != NULL)
        printf("%s\n", dirp->d_name);
    closedir(dp);

    exit(0);
}

        编译后的执行:

$ ./06_1 /var/spool/cron/crontabs/
can't open /var/spool/cron/crontabs/: Permission denied


你可能感兴趣的:(读书笔记,《UNIX环境高级编程》)