Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why errno, when POSIX function indicate error condition by returning -1 or NULL

Tags:

c

posix

errno

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:

  • It introduces coupling between different compilation units of the standard library - error states are not defined in the modules causing them.
  • It introduces implementation complexity, because errno needs to be thread local.
  • It introduces usability complexity because the user needs to check that the original system call is in error, and then check errno Which is also another function call.

Why not encode the error states in the return values?

like image 361
Vorac Avatar asked Jan 29 '16 16:01

Vorac


1 Answers

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.

like image 146
Basile Starynkevitch Avatar answered Oct 03 '22 17:10

Basile Starynkevitch