errno

说明

  • Newlib中,标准头文件 <errno.h>errno 是一个宏:
/* <errno.h> */

#define errno (*__errno())
extern int *__errno (void);

int * __errno()
{
  return &_REENT->_errno;
}
  • Newlib的底层代码对errno的处理非常奇怪,会将errno undef掉,然后重新定义成一个 变量 , 并要求libgloss中提供 变量 定义:
/* <newlib/libc/reent/readr.c> */

#undef errno
extern int errno;

_ssize_t
_read_r (struct _reent *ptr,
     int fd,
     void *buf,
     size_t cnt)
{
  _ssize_t ret;

  errno = 0;
  if ((ret = (_ssize_t)_read (fd, buf, cnt)) == -1 && errno != 0)
    ptr->_errno = errno;
  return ret;
}
/* <libgloss/libnosys/read.c> */

#undef errno
extern int errno;

int
_read (int   file,
        char *ptr,
        int   len)
{
  errno = ENOSYS;
  return -1;
}
  • libgloss提供与平台相关的启动代码、I/O支持、系统函数等,其中libnosys是一个空实现;

移植方法

  • XWOS在每个线程对象结构体中定义了一个 __errno 变量,并重新覆盖实现了 int * __errno(void) 函数, 返回 当前 线程对象的 __errno 的地址:
int * __errno(void)
{
        xwos_thd_d thdd = xwos_cthd_self();
        return &thdd.thd->osthd.libc.error_number;
}
  • 当使用 <errno.h> 中的 errno 宏时,就可获取线程自身的 __errno ,不再依赖libgloss。