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