When an error occurs in one of the UNIX System functions, a negative value is often returned, and the integer
errno
is set to a value, that gives additional information. -- Advanced Programming in the UNIX Environment, section 1.7
This seems weird:
errno
needs to be thread local.errno
Which is also another function call.Why not encode the error states in the return values?
For historical reasons mostly.
Notice that in reality, errno
is not an ordinary global variable today (that was the case in the 1980s). It is today (C99, C11...) a macro - usually expanded to some function call, perhaps __errno()
(and recent C standard requires errno
to be a macro, see n1570 §7.5); or it might be expanded to some thread local variable, or even some compiler magic.
errno
wants to be a macro for multi-threading needs, so I guess that standards evolved to require it to be some macro
So you should #include <errno.h>
and use the errno
macro nearly as if it was some global variable, but knowing that in fact it is not one.
Details are implementation specific. Look inside the source code of your C standard library, e.g. musl-libc has in errno/__errno_location.c
int *__errno_location(void)
{
return &__pthread_self()->errno_val;
}
and in include/errno.h public header:
int *__errno_location(void);
#define errno (*__errno_location())
and GNU libc has something very similar
BTW some system functions do not return an integer (e.g. mmap
), and some POSIX functions don't indicate errors thru errno
, e.g. dlopen
(see dlerror
). So it would be difficult to guarantee in some standard that every error could be indicated by returned values.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With