why "Reentrant covers for OS subroutines" use global errno?
Fri Aug 12 14:51:00 GMT 2011
On 08/09/2011 05:31 AM, Can Finner wrote:
> I am studying the reentrancy mechanism in newlib/libgloss, and read
> several threads in newlib mail archive,
> I still cannot understand following question.
> Why do "Reentrant covers for OS subroutines"(in libc/reent/) use
> global errno variable with codes like:
> #undef errno
> extern int errno;
The __getreent() support is rather new in the scheme of things for newlib.
Historically, the reentrant wrappers in libc/reent were done to wrap
The target may provide the needed syscalls by any of the following:
1) Define the reentrant versions of the syscalls directly.
(eg: _open_r, _close_r, etc.). Please keep the namespace clean.
When you do this, set "syscall_dir" to "syscalls" and add
-DREENTRANT_SYSCALLS_PROVIDED to newlib_cflags in configure.host.
2) Define namespace clean versions of the system calls by prefixing
them with '_' (eg: _open, _close, etc.). Technically, there
true reentrancy at the syscall level, but the library will be
Number 2 applies here.
The non-reentrant syscalls don't take the extra parameter to pass them
the reentrancy structure so the answer at the time was to have them set
the external int errno. The wrapper sets the newlib-ized version of
errno when an error occurs.
Hence there is not true reentrancy at the syscall level.
If desired, arm can go the route of 1) whereby it provides _r versions
of the syscalls which then can access the reentrancy structure at will
since it is passed
the syscalls in arm libgloss can be modified to access the _REENT macro
in the case of SINGLE_THREAD and/or arm can provide a getreent()
function. In these cases, the syscalls would set _errno directly and
not touch the value of int errno on an error condition. The wrapper
will then not use the value of int errno and it will be reentrant.
-- Jeff J.
> It is said the system can achieve reentrancy by implementing its own
> __getreent function,
> defining macro __DYNAMIC_REENT__ and implementing libgloss with
> errno.h directly.
> However, with routines in libc/reent directory, system won't be
> reentrant unless defining macro
> REENTRANT_SYSCALLS_PROVIDED and implementing _r versions of syscalls
> in libgloss.
> Think about calling sequence of a simple case for arm:
> fwrite --> __swrite --> _write_r(in libc/reent) --> _write(in libgloss/arm)
> routine _write_r uses global errno variable, which breaks the
> reentrancy in the calling sequence.
> Did I misunderstand the reentrancy mechanism in newlib/libgloss or
> something wrong?
> Please help, thanks in advance.
More information about the Newlib