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