syscalls, libgloss, errno

Jeff Johnston jjohnstn@redhat.com
Wed Jan 2 22:29:00 GMT 2008


Vincent Rivière wrote:
> Jeff, many thanks for your answer !
>
> But there are still things I can't understand.
>
> Let's talk about a very simple configuration. The system is single 
> threaded, so there are no reentrancy issues. The libgloss 
> implementation is the standard libnosys, which returns ENOSYS in every 
> function call.
> I am in the configuration #2 from reent.h :
> MISSING_SYSCALL_NAMES is not defined
> and syscall_dir=syscalls
> REENTRANT_SYSCALLS_PROVIDED is not defined
>
> I want to :
> - #include <errno.h>
> - call fopen() and find ENOSYS in errno
> - call open() and find ENOSYS in errno
>
> 1) The case of fopen()
> fopen() will call _open_r().
> _open_r() is implemented in libc/reent/openr.c and calls _open()
> _open() is implemented in libgloss/libnosys/open.c
>
> 2) The case of open()
> open() is implemented in syscalls/sysopen.c and calls _open()
> _open() is implemented in libgloss/libnosys/open.c
>
> So in every case, we end up to _open() in libgloss. Good.
>
> Now, let's talk about errno.
>
> _open(), in libnosys, returns the error code in "extern int errno".
> This is not a problem because we are on a single threaded environment.
>
> open() just calls _open().
> So open() returns the error code in "extern int errno".
>
> _open_r() calls _open(), and copies the error code from "extern int 
> errno" to __errno_r(_REENT). That's good.
> So _open_r() returns the error code in __errno_r(_REENT).
>
> fopen() calls _open_r(), and doesn't mess errno.
> So fopen() returns the error code in __errno_r(_REENT).
>
> The application #include <errno.h> and uses errno.
> In errno.h: #define errno (*__errno())
> In errno.c: int * __errno () { return &_REENT->_errno; }
> So the application finds the error code in __errno_r(_REENT).
>
> Finally :
> When the application calls fopen(), it finds the correct error code in 
> errno.
> But when it calls open(), it will not find the error code in errno 
> (which is actually __errno_r(_REENT)), because open() returns the 
> error code into "extern int errno" !
>
> The problem is in the implementation of open() and other syscalls in 
> libc/syscalls/*
> If REENTRANT_SYSCALLS_PROVIDED is defined (which is not the case 
> here), open() calls _open_r() and the error is returned into 
> __errno_r(_REENT)) as expected.
> But if REENTRANT_SYSCALLS_PROVIDED is not defined (the case here), it 
> should call _open() and translate the error from "extern int errno" to 
> __errno_r(_REENT), just like the implementation of _open_r() does.
> Another solution to implement open() would be to unconditionally call 
> _open_r(), just like fopen().
>
Conclusion :
> Either I misunderstood something, either there is a problem in 
> syscalls/sys*.c. In the latter case, I provided 2 simple solutions.
>
You are correct.  The libc/reent directory provides default 
implementations of the _r syscalls if the platform doesn't supply them 
with the REENTRANT_SYSCALLS_PROVIDED.  The syscalls directory should 
call these unconditionally.

I have attached a patch for this.  If there are no problems, I'll check 
it in.

-- Jeff J.
-------------- next part --------------
A non-text attachment was scrubbed...
Name: syscall.patch
Type: text/x-patch
Size: 9096 bytes
Desc: not available
URL: <http://sourceware.org/pipermail/newlib/attachments/20080102/1bbda019/attachment.bin>


More information about the Newlib mailing list