第十周

   

附录A

错误处理

包装函数被封装在一个源文件(csapp.c)中,这个文件被编译和链接到每个程序中。一个独立的头文件(csapp.h)中包含这些包装函数的函数原型。

Unix系统中的错误处理
  • Unix风格的错误处理 
    通常形式:
    if ((pid = wait(NULL))<0){
        fprintf(stderr,"wait error: %s\n",strerror(errno));
        exit(0);
    }

    strerror函数返回某个errno值的文本描述

  • Posix风格的错误处理
    1. 任何有用的结果都返回在通过引用传递进来的函数参数中
    2. 通常形式:
      if ((retcode = pthread_create(&tid,NULL,threadd,NULL))!=0){
          fprintf(stderr,"pthread_create error: %s\n",strerror(retcode));
          exit(0);
      }
  • DNS风格的错误处理
    1. gethostbyname和gethostbyaddr函数失败时返回NULL指针,并设置全局变量h_errno。
    2. 通常形式:
      if ((p = gethostbynae(name)) ==NULL)}
          fprintf(stderrr,"gethostbyname error: %s\n:",hstrerror(h_errno));
          exit(0);
      }
  • 错误报告函数
    #include "csapp.h"
    
    void unix_error(char *msg);
    void posix_error(int code,char *msg);
    void dns_error(char *msg);
    void app_error(char *msg);

    错误报告函数代码:

    void unix_error(char *msg)
    {
        fprintf(stderr,"%s:%s\n",msg,strerror(errno));
        exit(0);
    }
    
    void posix_error(int code,char *msg)
    {
        fprintf(stderr,"%s: %s\n",msg,strerror(code));
        exit(0);
    }
    
    void dns_error(char *msg)
    {
        fprintf(stderr,"%s: DNS error %d\n",msg,h_errno);
        exit(0);
    }
    
    void app_error(char *msg)
    {
        fprintf(stderr,"%s\n",msg);
        exit(0);
    }
错误处理包装函数
  • Unix风格的错误处理包装函数
    void Kill(pid_t pid,int signum)
    {
        int rc;
        if ((rc = kill(pid,signum))<0)
            unix_error("Kill error");
    }

    成功返回void,如果错误,打印一条消息然后退出。

  • Posix风格的错误处理包装函数
    void Pthread_detach(pthread_t tid){
        int rc;
        if ((rc = pthread_detach(tid)) != 0)
            posix_error(rc,"Pthread_detach error");
    }

    成功时返回void。

  • DNS风格的错误处理包装函数
    struct hostent *Gethostbyname(const char *name)
    {
        struct hostent *p;
    
        if ((p = gethostbyname(name)) == NULL)
            dns_error("Gethostbyname error");
        return p;
    }

你可能感兴趣的:(第十周)