From: Brooks Moses Date: Thu, 12 Dec 2013 00:58:12 +0000 (-0800) Subject: Add error reporting (via errno) to getauxval(). X-Git-Tag: glibc-2.19~246 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=b9ab448f980e296eac21ac65f53783967cc6037b;p=thirdparty%2Fglibc.git 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(). --- diff --git a/ChangeLog b/ChangeLog index 76e323ff3d2..173c2801f1f 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,14 @@ +2013-12-18 Brooks Moses + + [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 * math/auto-libm-test-in: Add tests of jn and yn. diff --git a/elf/tst-auxv.c b/elf/tst-auxv.c index 454c0b0221e..0fb3ad53450 100644 --- a/elf/tst-auxv.c +++ b/elf/tst-auxv.c @@ -16,6 +16,7 @@ . */ #include +#include #include #include #include @@ -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); diff --git a/manual/startup.texi b/manual/startup.texi index a2777141c2d..edd1de47bed 100644 --- a/manual/startup.texi +++ b/manual/startup.texi @@ -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 diff --git a/misc/getauxval.c b/misc/getauxval.c index e0317fd6f9a..dd4c8ecab32 100644 --- a/misc/getauxval.c +++ b/misc/getauxval.c @@ -16,6 +16,7 @@ . */ #include +#include #include @@ -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; } diff --git a/misc/sys/auxv.h b/misc/sys/auxv.h index a69250bd526..7aec3a04b80 100644 --- a/misc/sys/auxv.h +++ b/misc/sys/auxv.h @@ -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