errno handling in nonreentrant syscalls (fwd)

Joachim Falk jfalk@netxpress.de
Thu May 24 21:30:00 GMT 2001


there seam to be 3 cases for syscall dispatching in newlib

case 1:
  Syscall handling via _xxx_r( struct _reent *REENT, ... )
  reentrant syscalls.
  The errno value is stored in REENT->_errno this is
  __errno_r( REENT )

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
  
  cat libc/reent/readr.c
  
  /* Reentrant versions of read system call. */
  
  #include <reent.h>
  #include <unistd.h>
  #include <_syslist.h>
  
  /* Some targets provides their own versions of this functions.  Those
     targets should define REENTRANT_SYSCALLS_PROVIDED in
TARGET_CFLAGS.  */
  
  #ifdef _REENT_ONLY
  #ifndef REENTRANT_SYSCALLS_PROVIDED
  #define REENTRANT_SYSCALLS_PROVIDED
  #endif
  #endif
  
  #ifndef REENTRANT_SYSCALLS_PROVIDED
  
  /* We use the errno variable used by the system dependent layer.  */
  #undef errno
  extern int errno;

  .
  . [SNIP DOC]
  .
  
  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 !!

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 ?




More information about the Newlib mailing list