_REENT->_errno v. extern int errno

Jeff Johnston jjohnstn@redhat.com
Tue Dec 6 21:43:00 GMT 2005

Shaun Jackman wrote:
> There's something funny going on with errno. The libgloss ARM
> implementation includes <errno.h>, and so stores its errno result
> direclty in _REENT->_errno. REENTRANT_SYSCALLS_PROVIDED is not
> defined, so write, for example, calls _write in libgloss, and not
> _write_r. All is good. However, a function such as __swrite calls
> _write_r instead of _write. _write_r does a funny little fix up where
> it assumes the OS layer (libgloss) stores the errno result in extern
> int errno, and not in _REENT->_errno.
> syscalls/syswrite.c assumes the OS layer stores errno in _REENT->_errno.
> reent/writer.c assumes the OS layer stores errno in extern int errno.
> It seems to me reent/writer.c is broken, or at least should be told
> through a define that the errno result is already in _REENT->_errno.

Actually, arm's libgloss is not following the prescribed reentrancy 
scheme.  The writer.c routine is doing what is meant to do.  What you 
must remember is that errno needs to be set manually for the reentrancy 
struct argument when being set in a newlib _r suffixed routine.  The 
reentrancy struct may represent a virtual thread, for example.  Using 
errno from errno.h sets the default reentrancy struct errno which is 
incorrect unless the _DYNAMIC_REENT_ flag is set "and" a __getreent() 
function is provided "or" the system guarantees only to ever use one 
reentrancy structure (__SINGLE_THREAD__).

Possible alternatives are:

- Switch over to use MISSING_SYSCALL_NAMES or
   REENTRANT_SYSCALLS_PROVIDED (_r routine additions needed with this
- Modify the reent functions to add a new scenario (__SINGLE_THREAD__
   and __SYSCALLS_USE_ERRNO_H__).  You would have to set these flags
   for arm and the new scenario would have to be documented in
   libc/include/reent.h.  (In the case of __DYNAMIC_REENT__
   described earlier, one would go with MISSING_SYSCALL_NAMES
   since the _r routines aren't needed).
- Use the external errno and add _r versions of the syscall functions
   not found in libc/reent

-- Jeff J.

> Cheers,
> Shaun

More information about the Newlib mailing list