This is the mail archive of the libc-help@sourceware.org mailing list for the glibc project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

What is errno really defined as


I've been following up on the research of Rical Jasan.
In the file /usr/include/bits/errno.h

# ifndef __ASSEMBLER__
/* Function to get address of global `errno' variable.  */
extern int *__errno_location (void) __THROW __attribute__ ((__const__));

#  if !defined _LIBC || defined _LIBC_REENTRANT
/* When using threads, errno is a per-thread value.  */
#   define errno (*__errno_location ())
#  endif
# endif /* !__ASSEMBLER__ */
#endif /* _ERRNO_H */

Errno is declared as a function returning pointer to int and it does not modify or read any golbal variables. What I'm confused by though, is the redefinition of errno as (*__errno_location ()), namely, why the extra parentheses, no argument, no const attribute, and the return type is * vs int * which, though defalting to int, is considered bad programming practice?

In the file /usr/include/errno.h errno is declared as "extern int errno;" and the file /usr/include/bits/errno.h defines errno and some values for errno and then it includes /usr/include/linux/errno.h which contains nothing except a directive to include /usr/include/asm/errno.h which does the same as it's predecessor, this time including /usr/include/asm-generic/errno.h which defines several values for errno and goes on to include /usr/include/asm-generic/errno-base.h which defines some more values for errno and the trail ends there.

Looking into the glibc-2.18 source I find __errno_location to possess a variety of definitions. For instance, on hurd systems glibc-2.18/sysdeps/mach/hurd/errno-loc.c reads:

#include <errno.h>
#include <hurd/threadvar.h>
int * __errno_location (void)
{
  return (int *) __hurd_threadvar_location (_HURD_THREADVAR_ERRNO);
}
strong_alias (__errno_location, __hurd_errno_location)
libc_hidden_def (__errno_location)
The file glibc-2.18/csu/errno-loc.c reads:
#include <errno.h>
#include <tls.h>
//csu
int *
__errno_location (void)
{
  return &errno;
}
libc_hidden_def (__errno_location)
Which looks to be a recursive funtion if errno is defined to call __errno_location.
I then thought I might track it down using gdb and a simple C program.
#include <errno.h>

int main(void)
{
    errno=1;
    return(errno);
}

(gdb) start
Temporary breakpoint 1, main () at a.c:5
5           errno=1;
(gdb) s
__GI___errno_location () at errno-loc.c:26
26        return &errno;
(gdb) s
27      }
(gdb) s
main () at a.c:6
6           return(errno);
(gdb) s
__GI___errno_location () at errno-loc.c:26
26        return &errno;
(gdb) s
27      }
(gdb) s
main () at a.c:7
7       }
(gdb) c
Continuing.
[Inferior 1 (process 6705) exited with code 01]

Which tells me nothing because __GI___errno_location is not defined anywhere and errno is defined to call __errno_location and if errno is supposed to create a call to __GI___errno_location then how do we get out of the recursive loop?

Going back to the brute force method I searched for the deffinition of errno again, this time in the sources
% cd ~/tmp/glibc-sources
% grep -r -E '\<(errno|__errno_location)\>' * | wc -l
5786
% grep -r -E '^[^/*]*errno[^.\;)][^-=!+][^E]' * | wc -l
2101
% grep -r -E '^[^/*]*__errno_location[^@][^F]' * | wc -l
24
% grep -r -E '[^@]volatile.*errno' *
ChangeLog.3:    __volatile keyword.  `volatile int errno' is not the same
ports/sysdeps/unix/sysv/linux/hppa/bits/atomic.h:     volatile int lws_errno;  \

The only real thing I found was that __errno_location appears to recieve a few different definitions along the way.
Now I decided to go looking through the changelogs. __errno_location has existed since it was added in Tue Dec  3 08:38:15 1996 by Richard Henderson  <rth@tamu.edu>. Here's an interesting note in changlog 13 from
2002-03-14  Ulrich Drepper  <drepper@redhat.com>
(__errno_location): New function.  Declare errno as hidden.
And another note in changelog 17 from
2008-05-21  Jakub Jelinek  <jakub@redhat.com>
HIDDEN_JUMPTARGET for __errno_location call in libc.so.
It seems to me IMHO that several transgressions against the recomendations of "The Art Of Unix Programmng" have occured. The libc developers appear to have broken the "Rule of Clarity", "Rule of Simplicity", "Rule of Parsimony", "RULE OF TRANSPARENCY" and, "Rule of Economy". In the event that you've no clue what I'm talking about it's all written here http://catb.org/~esr/writings/taoup/html/ by ESR himself. I've spent four hours on this, I keep hitting a brick wall.
Does anybody really know what errno is?


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]