_REENT->_errno v. extern int errno
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.
More information about the Newlib