errno
少于1分钟
说明
- 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。