errno
less than a minute
Description
- In Newlib, the
errnoin the standard header file<errno.h>is a macro:
/* <errno.h> */
#define errno (*__errno())
extern int *__errno (void);
int * __errno()
{
return &_REENT->_errno;
}
- Newlib’s low-level code handles errno in a very peculiar way, undefining errno and then redefining it as a variable, requiring libgloss to provide the variable definition:
/* <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 provides platform-related startup code, I/O support, system functions, etc., where libnosys is a stub implementation;
Porting Method
- XWOS defines an
__errnovariable in each thread object structure and re-implements theint * __errno(void)function, returning the address of the current thread object’s__errno:
int * __errno(void)
{
xwos_thd_d thdd = xwos_cthd_self();
return &thdd.thd->osthd.libc.error_number;
}
- When using the
errnomacro from<errno.h>, the thread’s own__errnocan be obtained, no longer depending on libgloss.