This is the mail archive of the newlib@sources.redhat.com mailing list for the newlib project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]

Re: errno handling in nonreentrant syscalls (fwd)


Joachim Falk wrote:
> 
> case 2:
>   Syscall handling via _xxx( ... ) nonreentrant syscalls
>   The errno value is stored where ?
>   + Global errno
>       #undef errno
>       extern int errno;
>   + or _REENT->_errno is __errno_r( _REENT ) is the errno from
>     sys/errno.h
> 
>   There seams support for both of this in
> 
>   cat libc/syscalls/sysread.c
> 
>   /* connector for read */
> 
>   #include <reent.h>
>   #include <unistd.h>
> 
>   int
>   read (fd, buf, cnt)
>        int fd;
>        void *buf;
>        size_t cnt;
>   {
>   #ifdef REENTRANT_SYSCALLS_PROVIDED
>     return _read_r (_REENT, fd, buf, cnt);
>   #else
>     return _read (fd, buf, cnt);
>   #endif
>   }
> 
>   Here _read is called directly without any wrapper code to
>   store global errno into _REENT->_errno
>   => Assume _read stores errno into _REENT->_errno itself
> 
>   long
>   _read_r (ptr, fd, buf, cnt)
>        struct _reent *ptr;
>        int fd;
>        _PTR buf;
>        size_t cnt;
>   {
>     long ret;
> 
>     errno = 0;
>     if ((ret = _read (fd, buf, cnt)) == -1 && errno != 0)
>       ptr->_errno = errno;
>     return ret;
>   }
> 
>   #endif /* ! defined (REENTRANT_SYSCALLS_PROVIDED) */
> 
>   Here _read is called with wrapper code to store global errno
>   into ptr->_errno
>   => Assume _read stores errno into global errno and not _REENT->_errno
> 
>   What gives it cannot be both true !!

You're right.  It's a bit of a mess caused by not being consistent in the past.  The system calls
are not supplied by newlib and are either in libgloss, provided in a bsp library, or the OS provides
them.  A number of libgloss implementations simply set the external errno value in a common trap
routine.  Some implementations use some C code which include errno.h and set errno that way. 
Already you can see there is a discrepancy in how newlib should handle this.

I think the first step is to create a new flag that states whether the non-reentrant system calls
use an external errno or the C library errno from errno.h.  This allows us to dual-path the code and
at least makes it possible to hook up to which ever system libgloss is using.  

As well, it makes sense to go through the library and change all direct errno references to use
__errno_r() instead of ptr->_errno.  Currently, __errno_r() is a macro which should be changed to be
a function in libc/errno/errno.c.  This allows us to override the function when necessary and
specify where the errno values come from.

T
> 
> case 3:
>   syscall dispatching via xxxx we have -DMISSING_SYSCALL_NAMES
>   if read stores errno into _REENT->_errno all is well
> 
>   but if read stores errno into a global errno we are screwd
>   the errno witch I get from
>   #include <errno.h> of newlib
>   is in fact _REENT->_errno so I cant get the errno from
>   my system call !!!!
> 
>   If I alter sys/errno.h of newlib to point to global errno
>   I get the errno values from my system calls
>   but not from newlib intern stuff witch still uses
>   _REENT->_errno in most cases see perror and consorts
> 
> Am I right or have I missed something ?

I think we should just assume that the <errno.h> errno will be used.  If not, the machine/system
should provide an appropriate override for __errno() / __errno_r().

Any areas I have missed?

-- Jeff J.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]