Add error reporting (via errno) to getauxval().

[BZ 15846] As discussed in the recent thread on my $EXEC_ORIGIN patch
and in BZ 15846, getauxval() presently has no unambiguous way of
reporting an error condition.  It currently returns zero on error, but
this may also be a valid result for some auxv entries.  As there is no
clear invalid result for all current and future auxv entries, this patch
sets errno (following a suggestion in the BZ entry).

This version of the patch also adds documentation and tests for the
value-not-found conditions in getauxval().
This commit is contained in:
Brooks Moses 2013-12-11 16:58:12 -08:00
parent f889953b44
commit b9ab448f98
5 changed files with 44 additions and 5 deletions

View File

@ -1,3 +1,14 @@
2013-12-18 Brooks Moses <bmoses@google.com>
[BZ #15846]
* misc/getauxval.c: Include errno.h.
(__getauxval): Set errno to ENOENT if the requested type is not
found.
* misc/sys/auxv.h (getauxval): Document that it may set errno;
don't declare with __attribute_const__.
* elf/tst-auxv.c: Add tests for errno and type-not-found case.
* manual/startup.texi: Document that getauxval sets errno.
2013-12-18 Joseph Myers <joseph@codesourcery.com>
* math/auto-libm-test-in: Add tests of jn and yn.

View File

@ -16,6 +16,7 @@
<http://www.gnu.org/licenses/>. */
#include <elf.h>
#include <errno.h>
#include <link.h>
#include <string.h>
#include <stdio.h>
@ -25,14 +26,37 @@
static int
do_test (int argc, char *argv[])
{
const char *execfn = (const char *) getauxval (AT_EXECFN);
errno = 0;
const char *execfn = (const char *) getauxval (AT_NULL);
if (errno != ENOENT)
{
printf ("errno is %d rather than %d (ENOENT) on failure\n", errno,
ENOENT);
return 1;
}
if (execfn != NULL)
{
printf ("getauxval return value is nonzero on failure\n");
return 1;
}
errno = 0;
execfn = (const char *) getauxval (AT_EXECFN);
if (execfn == NULL)
{
printf ("No AT_EXECFN found, test skipped\n");
printf ("No AT_EXECFN found, AT_EXECFN test skipped\n");
return 0;
}
if (errno != 0)
{
printf ("errno erroneously set to %d on success\n", errno);
return 1;
}
if (strcmp (argv[0], execfn) != 0)
{
printf ("Mismatch: argv[0]: %s vs. AT_EXECFN: %s\n", argv[0], execfn);

View File

@ -625,7 +625,8 @@ basis there may be information that is not available any other way.
This function is used to inquire about the entries in the auxiliary
vector. The @var{type} argument should be one of the @samp{AT_} symbols
defined in @file{elf.h}. If a matching entry is found, the value is
returned; if the entry is not found, zero is returned.
returned; if the entry is not found, zero is returned and @code{errno} is
set to @code{ENOENT}.
@end deftypefun
For some platforms, the key @code{AT_HWCAP} is the easiest way to inquire

View File

@ -16,6 +16,7 @@
<http://www.gnu.org/licenses/>. */
#include <sys/auxv.h>
#include <errno.h>
#include <ldsodefs.h>
@ -32,6 +33,8 @@ __getauxval (unsigned long int type)
for (p = GLRO(dl_auxv); p->a_type != AT_NULL; p++)
if (p->a_type == type)
return p->a_un.a_val;
__set_errno (ENOENT);
return 0;
}

View File

@ -27,9 +27,9 @@ __BEGIN_DECLS
/* Return the value associated with an Elf*_auxv_t type from the auxv list
passed to the program on startup. If TYPE was not present in the auxv
list, returns zero. */
list, returns zero and sets errno to ENOENT. */
extern unsigned long int getauxval (unsigned long int __type)
__THROW __attribute_const__;
__THROW;
__END_DECLS