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。