syscalls, libgloss, errno

Jeff Johnston
Wed Jan 2 19:31:00 GMT 2008

Vincent Rivière wrote:
> Happy New Year 2008 !
> I have spent some time studying the Newlib sources, especially the way 
> how reentrant syscalls are implemented.
> I still can't understand some things.
> From a user program linked against newlib and libgloss, is it possible 
> to call the syscalls (open, close, etc.) and to get the errors in the 
> standard way, by including <errno.h> and using errno ?
Yes, as long as the libgloss implementation is set up correctly.  The 
first thing to note is
whether you want to support multiple threads or not for your platform.  
If the answer is
single-threaded only, then your libgloss implementation simply includes 
errno.h and
sets errno directly, if needed.

If you want to support multiple threads, then you must set errno per 
thread.  That is where
the reentrant structure comes in and the _r suffixed routines.  At this 
point, you have a
few choices.

 1) Implement the __getreent() routine and set the __DYNAMIC_REENT__ flag in
     libc/sys/config.h for your platform.  The __getreent() routine 
returns the reentrancy
     structure for the current thread.  You can implement it however you 
like.  With this,
     the libgloss implementation simply includes errno.h and sets errno 
directly.  This
     will end up calling __getreent() and setting errno for that 
reentrancy structure.  If
     you want to start out single-threaded and later move to multiple 
threads, you can
     just set the flag.  There is a default __getreent implementation 
which returns the
     main thread reentrancy structure.

 2) Implement _r versions of the syscalls in libgloss.  You can then set 
errno via
     __errno_r(ptr) = x;   where ptr is the passed in reentrancy 
structure.  You need
     to include errno.h which brings in sys/errno.h  As you noted, you 
must set
    REENTRANT_SYSCALLS_PROVIDED  As well, the user code that will
    be called within a thread must use the _r versions of all routines 
and pass in the
    current reentrancy structure.

> Is it possible with the current implementation of libnosys ?
Libnosys is not thread reentrant.  You would have to reimplement the stubs.
> I imagine that it would be possible to define 
> REENTRANT_SYSCALLS_PROVIDED, implement the _syscalls_r in libgloss, 
> implement the _syscalls too (by calling the _r versions). Then the 
> syscalls (without _) will be automatically implemented by libc/syscalls/*
> Thus the global variable errno will never be used, and everything will 
> be OK.
> In other words: is there a simple way to implement the syscalls (in 
> whatever form) in order to be able to call open() and fopen() and to 
> get the error values from errno, by simply including <errno.h> ?
Option 1 above.
> And another question: when porting Newlib to a new target (in 2008 !), 
> is it best to put everything (syscalls needed by Newlib, and all the 
> others) into libgloss, or in libc/sys ?
For a platform, they go in libgloss.

-- Jeff J.

More information about the Newlib mailing list