perror实现分析(2.0: 具体实现)

需要用到的结构(错误号,及对应的详细信息)

struct Pair {
  int code;
  const char* msg;
};

生成错误信息数组:

struct Pair _sys_error_strings[] = {
#define  __BIONIC_ERRDEF(x,y,z)  { x, z },
#include "./_errdefs.h"
  { 0, NULL }
};

_errdefs.h 的大概内容如下:

__BIONIC_ERRDEF( 0              ,   0, "Success" )
__BIONIC_ERRDEF( EPERM          ,   1, "Operation not permitted" )
__BIONIC_ERRDEF( ENOENT         ,   2, "No such file or directory" )
__BIONIC_ERRDEF( ESRCH          ,   3, "No such process" )

const char* __strerror_lookup(int error_number) {
  return __code_string_lookup(_sys_error_strings, error_number);
}

根据错误号查找对应的详细信息:

int strerror_r(int error_number, char* buf, size_t buf_len) {
  int saved_errno = errno;
  size_t length;

  const char* error_name = __strerror_lookup(error_number);
  if (error_name != NULL) {
    length = snprintf(buf, buf_len, "%s", error_name);
  } else {
    length = snprintf(buf, buf_len, "Unknown error %u", error_number);
  }
  if (length >= buf_len) {
    errno = ERANGE;
    return -1;
  }

  errno = saved_errno;
  return 0;
}


函数原型,为了编译的时候不出错函数名修改为 myperror ,

void myperror(const char *prefix)
{
    char   buff[256]={0x00};

    mystrerror_r( errno, buff, sizeof(buff) );
    printf("buff is %s",buff);
    if (prefix) {
        write( 2, prefix, strlen(prefix) );
        write( 2, ": ", 2 );
    }
    write( 2, buff, strlen(buff) );
    write( 2, "\n", 1 );
}

在看看具体的应用实例:

#include <errno.h>
#include <unistd.h>
#include <fcntl.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <stdlib.h>
#include <string.h>
int main()
{
   int fd;
   fd = open("/dev/really_no_exists", O_RDWR);
   if(fd<0)
   {
   	 perror("perror");
   	 myperror("myperror "); 
   }
}

输出:

myperror : No such file or directory
perror : No such file or directory

与ubuntu系统实现的效果一致:

参考:

bionic/libc/bionic/strerror_r.cpp

bionic/libc/include/sys/_errdefs.h

你可能感兴趣的:(linux,perror)