Double definition of errno?

J. Johnston
Mon Aug 19 09:54:00 GMT 2002

KJK::Hyperion wrote:
> Hi all. I'm not very familiar with C library implementations, so I'm
> wondering what's the purpose of a double definition of errno, both as
> "extern int" and as a macro, but, correct me if I'm wrong, it seems that
> some calls (namely, "system calls") are assumed to use the "extern int
> errno", while all the others will use the errno macro. I'd like to use an
> unified definition of errno, would this break something? (except the
> reentrant system calls provided by newlib, which I can override)

The double definition has to do with what layer we are communicating with.
The errno macro in errno.h is the errno kept in the newlib reentrancy structure.

The extern int errno is used only to communicate with a non-reentrant syscall layer which
may have various implementations based on the actual hardware or simulator
used.  We cannot expect such an external syscall layer to adhere to newlib's
reentrancy scheme so we copy the syscall errno to newlib's errno if set.
This is not thread-safe with regards to setting errno in an
error situation.

For thread-safety,  a syscall reentrancy layer can be provided so that it is passed the reentrancy structure.  The macro __errno_r can be used to set
the errno for the particular reentrancy structure.  For such platforms, define the flag, -DREENTRANT_SYSCALLS_PROVIDED.

The reentrancy struct for threading can be automatically fetched so that the code only
needs to #include <errno.h> and refer to errno directly in C code.  This option is turned
on via the dynamic reentrancy struct option -D__DYNAMIC_REENT__ in libc/include/sys/config.h.
The option causes references to the default reentrancy pointer to invoke a call to
__getreent().  A threaded application can provide this function to return the reentrancy
structure for the current thread (e.g. using thread-specific storage).

For further information about the syscall layer, you can look at the comments in

Regarding your plans to change errno in the reentrant syscalls, this is going
to break a bunch of code because there are multiple reentrant routines in newlib
that directly access the reentrancy struct errno.  This means that your new errno
won't be set in many instances.

-- Jeff J.

More information about the Newlib mailing list