why "Reentrant covers for OS subroutines" use global errno?

Jeff Johnston jjohnstn@redhat.com
Fri Aug 12 14:51:00 GMT 2011


On 08/09/2011 05:31 AM, Can Finner wrote:
> Hi,
> 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:
>       #include<errno.h>
>       #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 
non-reentrant syscalls.

 From libc/include/reent.h:

    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
       won't be
       true reentrancy at the syscall level, but the library will be
       namespace clean.

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

OR

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 mailing list