Updated to fedora-glibc-20041115T0915

This commit is contained in:
Jakub Jelinek 2004-11-15 09:47:23 +00:00
parent 87ffc9aca1
commit b3c20a361d
14 changed files with 521 additions and 306 deletions

View File

@ -1,3 +1,43 @@
2004-11-13 Ulrich Drepper <drepper@redhat.com>
* malloc/malloc.c (malloc_state): stat_lock_* elements need only
be defined if THREAD_STATS is defined. Remove pad0_ since it does
not align with cache line sizes in general anyway.
2004-11-13 Jakub Jelinek <jakub@redhat.com>
* elf/rtld.c (print_statistics): Avoid segfaults if not all namespaces
are used. Fix computation of num_relative_relocations on RELA
architectures other than IA-64 and Alpha.
2004-11-13 Ulrich Drepper <drepper@redhat.com>
* malloc/malloc.c (_int_free): Use munmap_chunk for handling
mmaped memory.
2004-11-12 Ulrich Drepper <drepper@redhat.com>
* malloc/malloc.c (_int_free): Remove test for NULL parameter.
(_int_realloc): Call _int_free only if memory parameter is not NULL.
* sysdeps/unix/sysv/linux/libc_fatal.c: Add new function __libc_message
which performs the printing and simple format string handling. The
string is written to tty, stderr, syslog in this order, stopping after
the first successful output.
(__libc_fatal): Call __libc_message.
* include/stdio.h: Declare __libc_message.
* malloc/malloc.c (malloc_printerr): Use __libc_message.
* debug/chk_fail.c: Also print message with __libc_message.
* debug/test-strcpy_chk.c: Ensure that debug messages are not printed
to the terminal or stderr.
* debug/tst-chk1.c: Likewise.
* posix/Makefile: Remove gpl2lgpl variable.
2004-11-12 Martin Schwidefsky <schwidefsky@de.ibm.com>
* elf/elf.h: Add 20 bit relocations R_390_*20.
2004-11-12 Jakub Jelinek <jakub@redhat.com>
* sysdeps/unix/sysv/linux/i386/setuid.c: Include linux/posix_types.h.
@ -7,16 +47,9 @@
* sysdeps/unix/sysv/linux/i386/setresuid.c: Likewise.
* sysdeps/unix/sysv/linux/i386/setresgid.c: Likewise.
2004-11-11 Jakub Jelinek <jakub@redhat.com>
2004-11-12 Andreas Schwab <schwab@suse.de>
* debug/chk_fail.c: Include errno.h and string.h.
(__chk_fail): Write a short message to stderr.
* debug/tst-chk1.c: Include fcntl.h.
(do_test): Redirect stderr to /dev/null.
* debug/test-strcpy_chk.c: Include fcntl.h.
(test_main): Redirect stderr to /dev/null.
(do_one_test, do_random_tests): Use printf instead of
error.
* nis/ypclnt.c (ypprot_err): Fix "minor optimizations".
2004-11-12 Ulrich Drepper <drepper@redhat.com>

View File

@ -1,3 +1,4 @@
/* Copyright (C) 2004 Free Software Foundation, Inc.
This file is part of the GNU C Library.
@ -16,27 +17,14 @@
Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
02111-1307 USA. */
#include <errno.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <abort-instr.h>
void
__attribute__ ((noreturn))
__chk_fail (void)
{
while (1)
{
const char *text = "*** buffer overflow detected ***\n";
TEMP_FAILURE_RETRY (write (STDERR_FILENO, text, strlen (text)));
/* This will leave a nice backtrace. */
abort ();
#ifdef ABORT_INSTRUCTION
ABORT_INSTRUCTION;
#endif
_exit (127);
}
__libc_fatal ("*** buffer overflow detected ***\n");
}
libc_hidden_def (__chk_fail)

View File

@ -46,9 +46,10 @@ simple_strcpy_chk (char *dst, const char *src, size_t len)
}
#endif
#include <fcntl.h>
#include <paths.h>
#include <setjmp.h>
#include <signal.h>
#include <fcntl.h>
volatile int chk_fail_ok;
jmp_buf chk_fail_buf;
@ -81,8 +82,8 @@ do_one_test (impl_t *impl, char *dst, const char *src,
if (setjmp (chk_fail_buf) == 0)
{
res = CALL (impl, dst, src, dlen);
printf ("*** Function %s (%zd; %zd) did not __chk_fail",
impl->name, len, dlen);
printf ("*** Function %s (%zd; %zd) did not __chk_fail\n",
impl->name, len, dlen);
chk_fail_ok = 0;
ret = 1;
}
@ -93,7 +94,7 @@ do_one_test (impl_t *impl, char *dst, const char *src,
if (res != STRCPY_RESULT (dst, len))
{
printf ("*** Wrong result in function %s %p %p", impl->name,
printf ("Wrong result in function %s %p %p\n", impl->name,
res, STRCPY_RESULT (dst, len));
ret = 1;
return;
@ -101,7 +102,7 @@ do_one_test (impl_t *impl, char *dst, const char *src,
if (strcmp (dst, src) != 0)
{
printf ("*** Wrong result in function %s dst \"%s\" src \"%s\"",
printf ("Wrong result in function %s dst \"%s\" src \"%s\"\n",
impl->name, dst, src);
ret = 1;
return;
@ -233,7 +234,7 @@ do_random_tests (void)
if (setjmp (chk_fail_buf) == 0)
{
res = CALL (impl, p2 + align2, p1 + align1, dlen);
printf ("*** Iteration %zd - did not __chk_fail", n);
printf ("Iteration %zd - did not __chk_fail\n", n);
chk_fail_ok = 0;
ret = 1;
}
@ -244,7 +245,8 @@ do_random_tests (void)
res = CALL (impl, p2 + align2, p1 + align1, dlen);
if (res != STRCPY_RESULT (p2 + align2, len))
{
printf ("*** Iteration %zd - wrong result in function %s (%zd, %zd, %zd) %p != %p",
printf ("\
Iteration %zd - wrong result in function %s (%zd, %zd, %zd) %p != %p\n",
n, impl->name, align1, align2, len, res,
STRCPY_RESULT (p2 + align2, len));
ret = 1;
@ -253,7 +255,8 @@ do_random_tests (void)
{
if (p2[j - 64] != '\1')
{
printf ("*** Iteration %zd - garbage before, %s (%zd, %zd, %zd)",
printf ("\
Iteration %zd - garbage before, %s (%zd, %zd, %zd)\n",
n, impl->name, align1, align2, len);
ret = 1;
break;
@ -263,7 +266,8 @@ do_random_tests (void)
{
if (p2[j] != '\1')
{
printf ("*** Iteration %zd - garbage after, %s (%zd, %zd, %zd)",
printf ("\
Iteration %zd - garbage after, %s (%zd, %zd, %zd)\n",
n, impl->name, align1, align2, len);
ret = 1;
break;
@ -271,7 +275,8 @@ do_random_tests (void)
}
if (memcmp (p1 + align1, p2 + align2, len + 1))
{
printf ("*** Iteration %zd - different strings, %s (%zd, %zd, %zd)",
printf ("\
Iteration %zd - different strings, %s (%zd, %zd, %zd)\n",
n, impl->name, align1, align2, len);
ret = 1;
}
@ -292,8 +297,15 @@ test_main (void)
sigaction (SIGABRT, &sa, NULL);
/* Avoid all the buffer overflow messages on stderr. */
close (STDERR_FILENO);
open ("/dev/null", O_WRONLY);
int fd = open (_PATH_DEVNULL, O_WRONLY);
if (fd == -1)
close (STDERR_FILENO);
else
{
dup2 (fd, STDERR_FILENO);
close (fd);
}
setenv ("LIBC_FATAL_STDERR_", "1", 1);
test_init ();

View File

@ -18,6 +18,7 @@
02111-1307 USA. */
#include <fcntl.h>
#include <paths.h>
#include <setjmp.h>
#include <signal.h>
#include <stdio.h>
@ -108,8 +109,15 @@ do_test (void)
sigaction (SIGABRT, &sa, NULL);
/* Avoid all the buffer overflow messages on stderr. */
close (STDERR_FILENO);
open ("/dev/null", O_WRONLY);
int fd = open (_PATH_DEVNULL, O_WRONLY);
if (fd == -1)
close (STDERR_FILENO);
else
{
dup2 (fd, STDERR_FILENO);
close (fd);
}
setenv ("LIBC_FATAL_STDERR_", "1", 1);
struct A { char buf1[9]; char buf2[1]; } a;
@ -205,7 +213,7 @@ do_test (void)
if (memcmp (a.buf1, "aabcdabcjj", 10))
FAIL ();
#if __USE_FORTIFY_LEVEL < 2 || !__GNUC_PREREQ (4, 0)
#if __USE_FORTIFY_LEVEL < 2
/* The following tests are supposed to crash with -D_FORTIFY_SOURCE=2
and sufficient GCC support, as the string operations overflow
from a.buf1 into a.buf2. */
@ -304,7 +312,7 @@ do_test (void)
memset (a.buf1 + 9, 'j', l0 + 2);
CHK_FAIL_END
#if __USE_FORTIFY_LEVEL >= 2 && __GNUC_PREREQ (4, 0)
#if __USE_FORTIFY_LEVEL >= 2
# define O 0
#else
# define O 1

View File

@ -2402,8 +2402,13 @@ typedef Elf32_Addr Elf32_Conflict;
#define R_390_TLS_DTPOFF 55 /* Offset in TLS block. */
#define R_390_TLS_TPOFF 56 /* Negated offset in static TLS
block. */
#define R_390_20 57 /* Direct 20 bit. */
#define R_390_GOT20 58 /* 20 bit GOT offset. */
#define R_390_GOTPLT20 59 /* 20 bit offset to jump slot. */
#define R_390_TLS_GOTIE20 60 /* 20 bit GOT offset for static TLS
block offset. */
/* Keep this the last entry. */
#define R_390_NUM 57
#define R_390_NUM 61
/* CRIS relocations. */

View File

@ -2444,19 +2444,29 @@ print_statistics (hp_timing_t *rtld_total_timep)
unsigned long int num_relative_relocations = 0;
for (Lmid_t ns = 0; ns < DL_NNS; ++ns)
{
if (GL(dl_ns)[ns]._ns_loaded == NULL)
continue;
struct r_scope_elem *scope = &GL(dl_ns)[ns]._ns_loaded->l_searchlist;
for (unsigned int i = 0; i < scope->r_nlist; i++)
{
struct link_map *l = scope->r_list [i];
if (!l->l_addr)
continue;
if (l->l_info[VERSYMIDX (DT_RELCOUNT)])
if (l->l_addr != 0 && l->l_info[VERSYMIDX (DT_RELCOUNT)])
num_relative_relocations
+= l->l_info[VERSYMIDX (DT_RELCOUNT)]->d_un.d_val;
if (l->l_info[VERSYMIDX (DT_RELACOUNT)])
#ifndef ELF_MACHINE_REL_RELATIVE
/* Relative relocations are processed on these architectures if
library is loaded to different address than p_vaddr or
if not prelinked. */
if ((l->l_addr != 0 || !l->l_info[VALIDX(DT_GNU_PRELINKED)])
&& l->l_info[VERSYMIDX (DT_RELACOUNT)])
#else
/* On e.g. IA-64 or Alpha, relative relocations are processed
only if library is loaded to different address than p_vaddr. */
if (l->l_addr != 0 && l->l_info[VERSYMIDX (DT_RELACOUNT)])
#endif
num_relative_relocations
+= l->l_info[VERSYMIDX (DT_RELACOUNT)]->d_un.d_val;
}

View File

@ -1,5 +1,5 @@
# This file is updated automatically by Makefile.
glibc-branch := fedora
glibc-base := HEAD
fedora-sync-date := 2004-11-12 16:40 UTC
fedora-sync-tag := fedora-glibc-20041112T1640
fedora-sync-date := 2004-11-15 09:15 UTC
fedora-sync-tag := fedora-glibc-20041115T0915

View File

@ -1,4 +1,4 @@
%define glibcrelease 77
%define glibcrelease 78
%define auxarches i586 i686 athlon sparcv9 alphaev6
%define prelinkarches noarch
%define nptlarches i386 i686 athlon x86_64 ia64 s390 s390x sparcv9 ppc ppc64
@ -1256,6 +1256,11 @@ rm -f *.filelist*
%endif
%changelog
* Mon Nov 15 2004 Jakub Jelinek <jakub@redhat.com> 2.3.3-78
- update from CVS
- issue error message before aborting in __chk_fail ()
- some more free () checking
* Fri Nov 12 2004 Jakub Jelinek <jakub@redhat.com> 2.3.3-77
- update from CVS
- speedup regex on palindromes (BZ #429)

View File

@ -62,6 +62,8 @@ extern int __gen_tempname (char *__tmpl, int __kind);
/* Print out MESSAGE on the error output and abort. */
extern void __libc_fatal (__const char *__message)
__attribute__ ((__noreturn__));
extern void __libc_message (int do_abort, __const char *__fnt, ...)
__attribute__ ((__noreturn__));
/* Acquire ownership of STREAM. */
extern void __flockfile (FILE *__stream);

View File

@ -2192,10 +2192,12 @@ typedef struct malloc_chunk* mfastbinptr;
struct malloc_state {
/* Serialize access. */
mutex_t mutex;
// Should we have padding to move the mutex to its own cache line?
#if THREAD_STATS
/* Statistics for locking. Only used if THREAD_STATS is defined. */
long stat_lock_direct, stat_lock_loop, stat_lock_wait;
long pad0_[1]; /* try to give the mutex its own cacheline */
#endif
/* The maximum chunk size to be eligible for fastbin */
INTERNAL_SIZE_T max_fast; /* low 2 bits used as flags */
@ -4196,191 +4198,182 @@ _int_free(mstate av, Void_t* mem)
mchunkptr fwd; /* misc temp for linking */
/* free(0) has no effect */
if (mem != 0) {
const char *errstr = NULL;
const char *errstr = NULL;
p = mem2chunk(mem);
size = chunksize(p);
p = mem2chunk(mem);
size = chunksize(p);
/* Little security check which won't hurt performance: the
allocator never wrapps around at the end of the address space.
Therefore we can exclude some size values which might appear
here by accident or by "design" from some intruder. */
if (__builtin_expect ((uintptr_t) p > (uintptr_t) -size, 0))
{
errstr = "free(): invalid pointer";
errout:
malloc_printerr (check_action, errstr, mem);
return;
}
/* Little security check which won't hurt performance: the
allocator never wrapps around at the end of the address space.
Therefore we can exclude some size values which might appear
here by accident or by "design" from some intruder. */
if (__builtin_expect ((uintptr_t) p > (uintptr_t) -size, 0))
{
errstr = "free(): invalid pointer";
errout:
malloc_printerr (check_action, errstr, mem);
return;
}
check_inuse_chunk(av, p);
check_inuse_chunk(av, p);
/*
If eligible, place chunk on a fastbin so it can be found
and used quickly in malloc.
*/
/*
If eligible, place chunk on a fastbin so it can be found
and used quickly in malloc.
*/
if ((unsigned long)(size) <= (unsigned long)(av->max_fast)
if ((unsigned long)(size) <= (unsigned long)(av->max_fast)
#if TRIM_FASTBINS
/*
If TRIM_FASTBINS set, don't place chunks
bordering top into fastbins
*/
&& (chunk_at_offset(p, size) != av->top)
/*
If TRIM_FASTBINS set, don't place chunks
bordering top into fastbins
*/
&& (chunk_at_offset(p, size) != av->top)
#endif
) {
) {
set_fastchunks(av);
fb = &(av->fastbins[fastbin_index(size)]);
/* Another simple check: make sure the top of the bin is not the
record we are going to add (i.e., double free). */
if (__builtin_expect (*fb == p, 0))
{
errstr = "double free or corruption (fasttop)";
goto errout;
}
p->fd = *fb;
*fb = p;
set_fastchunks(av);
fb = &(av->fastbins[fastbin_index(size)]);
/* Another simple check: make sure the top of the bin is not the
record we are going to add (i.e., double free). */
if (__builtin_expect (*fb == p, 0))
{
errstr = "double free or corruption (fasttop)";
goto errout;
}
p->fd = *fb;
*fb = p;
}
/*
Consolidate other non-mmapped chunks as they arrive.
*/
else if (!chunk_is_mmapped(p)) {
nextchunk = chunk_at_offset(p, size);
/* Lightweight tests: check whether the block is already the
top block. */
if (__builtin_expect (p == av->top, 0))
{
errstr = "double free or corruption (top)";
goto errout;
}
/* Or whether the next chunk is beyond the boundaries of the arena. */
if (__builtin_expect (contiguous (av)
&& (char *) nextchunk
>= ((char *) av->top + chunksize(av->top)), 0))
{
errstr = "double free or corruption (out)";
goto errout;
}
/* Or whether the block is actually not marked used. */
if (__builtin_expect (!prev_inuse(nextchunk), 0))
{
errstr = "double free or corruption (!prev)";
goto errout;
}
nextsize = chunksize(nextchunk);
assert(nextsize > 0);
/* consolidate backward */
if (!prev_inuse(p)) {
prevsize = p->prev_size;
size += prevsize;
p = chunk_at_offset(p, -((long) prevsize));
unlink(p, bck, fwd);
}
if (nextchunk != av->top) {
/* get and clear inuse bit */
nextinuse = inuse_bit_at_offset(nextchunk, nextsize);
/* consolidate forward */
if (!nextinuse) {
unlink(nextchunk, bck, fwd);
size += nextsize;
} else
clear_inuse_bit_at_offset(nextchunk, 0);
/*
Place the chunk in unsorted chunk list. Chunks are
not placed into regular bins until after they have
been given one chance to be used in malloc.
*/
bck = unsorted_chunks(av);
fwd = bck->fd;
p->bk = bck;
p->fd = fwd;
bck->fd = p;
fwd->bk = p;
set_head(p, size | PREV_INUSE);
set_foot(p, size);
check_free_chunk(av, p);
}
/*
Consolidate other non-mmapped chunks as they arrive.
*/
else if (!chunk_is_mmapped(p)) {
nextchunk = chunk_at_offset(p, size);
/* Lightweight tests: check whether the block is already the
top block. */
if (__builtin_expect (p == av->top, 0))
{
errstr = "double free or corruption (top)";
goto errout;
}
/* Or whether the next chunk is beyond the boundaries of the arena. */
if (__builtin_expect (contiguous (av)
&& (char *) nextchunk
>= ((char *) av->top + chunksize(av->top)), 0))
{
errstr = "double free or corruption (out)";
goto errout;
}
/* Or whether the block is actually not marked used. */
if (__builtin_expect (!prev_inuse(nextchunk), 0))
{
errstr = "double free or corruption (!prev)";
goto errout;
}
nextsize = chunksize(nextchunk);
assert(nextsize > 0);
/* consolidate backward */
if (!prev_inuse(p)) {
prevsize = p->prev_size;
size += prevsize;
p = chunk_at_offset(p, -((long) prevsize));
unlink(p, bck, fwd);
}
if (nextchunk != av->top) {
/* get and clear inuse bit */
nextinuse = inuse_bit_at_offset(nextchunk, nextsize);
/* consolidate forward */
if (!nextinuse) {
unlink(nextchunk, bck, fwd);
size += nextsize;
} else
clear_inuse_bit_at_offset(nextchunk, 0);
/*
Place the chunk in unsorted chunk list. Chunks are
not placed into regular bins until after they have
been given one chance to be used in malloc.
*/
bck = unsorted_chunks(av);
fwd = bck->fd;
p->bk = bck;
p->fd = fwd;
bck->fd = p;
fwd->bk = p;
set_head(p, size | PREV_INUSE);
set_foot(p, size);
check_free_chunk(av, p);
}
/*
If the chunk borders the current high end of memory,
consolidate into top
*/
else {
size += nextsize;
set_head(p, size | PREV_INUSE);
av->top = p;
check_chunk(av, p);
}
/*
If freeing a large space, consolidate possibly-surrounding
chunks. Then, if the total unused topmost memory exceeds trim
threshold, ask malloc_trim to reduce top.
Unless max_fast is 0, we don't know if there are fastbins
bordering top, so we cannot tell for sure whether threshold
has been reached unless fastbins are consolidated. But we
don't want to consolidate on each free. As a compromise,
consolidation is performed if FASTBIN_CONSOLIDATION_THRESHOLD
is reached.
*/
if ((unsigned long)(size) >= FASTBIN_CONSOLIDATION_THRESHOLD) {
if (have_fastchunks(av))
malloc_consolidate(av);
if (av == &main_arena) {
#ifndef MORECORE_CANNOT_TRIM
if ((unsigned long)(chunksize(av->top)) >=
(unsigned long)(mp_.trim_threshold))
sYSTRIm(mp_.top_pad, av);
#endif
} else {
/* Always try heap_trim(), even if the top chunk is not
large, because the corresponding heap might go away. */
heap_info *heap = heap_for_ptr(top(av));
assert(heap->ar_ptr == av);
heap_trim(heap, mp_.top_pad);
}
}
}
/*
If the chunk was allocated via mmap, release via munmap(). Note
that if HAVE_MMAP is false but chunk_is_mmapped is true, then
user must have overwritten memory. There's nothing we can do to
catch this error unless MALLOC_DEBUG is set, in which case
check_inuse_chunk (above) will have triggered error.
If the chunk borders the current high end of memory,
consolidate into top
*/
else {
#if HAVE_MMAP
int ret;
INTERNAL_SIZE_T offset = p->prev_size;
mp_.n_mmaps--;
mp_.mmapped_mem -= (size + offset);
ret = munmap((char*)p - offset, size + offset);
/* munmap returns non-zero on failure */
assert(ret == 0);
#endif
size += nextsize;
set_head(p, size | PREV_INUSE);
av->top = p;
check_chunk(av, p);
}
/*
If freeing a large space, consolidate possibly-surrounding
chunks. Then, if the total unused topmost memory exceeds trim
threshold, ask malloc_trim to reduce top.
Unless max_fast is 0, we don't know if there are fastbins
bordering top, so we cannot tell for sure whether threshold
has been reached unless fastbins are consolidated. But we
don't want to consolidate on each free. As a compromise,
consolidation is performed if FASTBIN_CONSOLIDATION_THRESHOLD
is reached.
*/
if ((unsigned long)(size) >= FASTBIN_CONSOLIDATION_THRESHOLD) {
if (have_fastchunks(av))
malloc_consolidate(av);
if (av == &main_arena) {
#ifndef MORECORE_CANNOT_TRIM
if ((unsigned long)(chunksize(av->top)) >=
(unsigned long)(mp_.trim_threshold))
sYSTRIm(mp_.top_pad, av);
#endif
} else {
/* Always try heap_trim(), even if the top chunk is not
large, because the corresponding heap might go away. */
heap_info *heap = heap_for_ptr(top(av));
assert(heap->ar_ptr == av);
heap_trim(heap, mp_.top_pad);
}
}
}
/*
If the chunk was allocated via mmap, release via munmap(). Note
that if HAVE_MMAP is false but chunk_is_mmapped is true, then
user must have overwritten memory. There's nothing we can do to
catch this error unless MALLOC_DEBUG is set, in which case
check_inuse_chunk (above) will have triggered error.
*/
else {
#if HAVE_MMAP
munmap_chunk (p);
#endif
}
}
@ -4528,7 +4521,8 @@ _int_realloc(mstate av, Void_t* oldmem, size_t bytes)
#if REALLOC_ZERO_BYTES_FREES
if (bytes == 0) {
_int_free(av, oldmem);
if (oldmem != 0)
_int_free(av, oldmem);
return 0;
}
#endif
@ -5474,45 +5468,19 @@ malloc_printerr(int action, const char *str, void *ptr)
{
if (action & 1)
{
/* output string will be ": ADDR ***\n" */
static const char suffix[] = " ***\n";
static const char prefix[] = ": 0x";
char buf[sizeof (prefix) - 1 + sizeof (void *) * 2 + sizeof (suffix)];
char *cp;
if (action & 4)
cp = memcpy (&buf[sizeof (buf) - 2], "\n", 2);
else
{
cp = memcpy (&buf[sizeof (buf) - sizeof (suffix)], suffix,
sizeof (suffix));
cp = _itoa_word ((unsigned long int) ptr, cp, 16, 0);
while (cp > &buf[sizeof (prefix) - 1])
*--cp = '0';
cp = memcpy (buf, prefix, sizeof (prefix) - 1);
}
char buf[2 * sizeof (uintptr_t) + 1];
struct iovec iov[3];
int n = 0;
if ((action & 4) == 0)
{
iov[0].iov_base = (char *) "*** glibc detected *** ";
iov[0].iov_len = strlen (iov[0].iov_base);
++n;
}
iov[n].iov_base = (char *) str;
iov[n].iov_len = strlen (str);
++n;
iov[n].iov_base = cp;
iov[n].iov_len = &buf[sizeof (buf) - 1] - cp;
++n;
if (TEMP_FAILURE_RETRY (__writev (STDERR_FILENO, iov, n)) == -1
&& errno == EBADF)
/* Standard error is not opened. Try using syslog. */
syslog (LOG_ERR, "%s%s%s", (char *) iov[0].iov_base,
(char *) iov[1].iov_base,
n == 3 ? (const char *) iov[2].iov_base : "");
buf[sizeof (buf) - 1] = '\0';
char *cp = _itoa_word ((uintptr_t) ptr, &buf[sizeof (buf) - 1], 16, 0);
while (cp > buf)
*--cp = '0';
__libc_message (action & 2,
action & 4
? "%s\n" : "*** glibc detected *** %s: 0x%s ***\n",
str, cp);
}
if (action & 2)
else if (action & 2)
abort ();
}

View File

@ -846,7 +846,7 @@ ypprot_err (const int code)
{
if (code < YP_VERS || code > YP_NOKEY)
return YPERR_YPERR;
return yp_2_yperr[code];
return yp_2_yperr[code - YP_VERS];
}
libnsl_hidden_def (ypprot_err)

View File

@ -91,7 +91,6 @@ tests += wordexp-test tst-exec tst-spawn
endif
others := getconf
install-bin := getconf
gpl2lgpl := getopt.c getopt1.c getopt.h regex.c regex.h
before-compile := testcases.h ptestcases.h

View File

@ -1,4 +1,4 @@
/* Copyright (C) 1993, 1994, 1995, 1997, 2000 Free Software Foundation, Inc.
/* Copyright (C) 1993,1994,1995,1997,2000,2004 Free Software Foundation, Inc.
This file is part of the GNU C Library.
The GNU C Library is free software; you can redistribute it and/or
@ -16,44 +16,131 @@
Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
02111-1307 USA. */
#include <errno.h>
#include <fcntl.h>
#include <paths.h>
#include <stdarg.h>
#include <stdbool.h>
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <errno.h>
#include <sysdep.h>
#include <string.h>
#include <sysdep.h>
#include <unistd.h>
#include <sys/syslog.h>
#include <not-cancel.h>
#ifdef FATAL_PREPARE_INCLUDE
#include FATAL_PREPARE_INCLUDE
#endif
struct str_list
{
const char *str;
size_t len;
struct str_list *next;
};
/* Abort with an error message. */
void
__libc_fatal (message)
const char *message;
__libc_message (int do_abort, const char *fmt, ...)
{
size_t len = strlen (message);
va_list ap;
va_list ap_copy;
int fd = -1;
va_start (ap, fmt);
va_copy (ap_copy, ap);
#ifdef FATAL_PREPARE
FATAL_PREPARE;
#endif
while (len > 0)
/* Open a descriptor for /dev/tty unless the user explicitly
requests errors on standard error. */
const char *on_2 = __secure_getenv ("LIBC_FATAL_STDERR_");
if (on_2 == NULL || *on_2 == '\0')
fd = open_not_cancel_2 (_PATH_TTY, O_RDWR | O_NOCTTY | O_NDELAY);
if (fd == -1)
fd = STDERR_FILENO;
struct str_list *list = NULL;
int nlist = 0;
const char *cp = fmt;
while (*cp != '\0')
{
register int count = __write (STDERR_FILENO, message, len);
if (count > 0)
/* Find the next "%s" or the end of the string. */
char *next = cp;
while (next[0] != '%' || next[1] != 's')
{
message += count;
len -= count;
next = __strchrnul (next + 1, '%');
if (next[0] == '\0')
break;
}
else if (count < 0
#ifdef EINTR
&& errno != EINTR
#endif
)
break;
/* Determine what to print. */
const char *str;
size_t len;
if (cp[0] == '%' && cp[1] == 's')
{
str = va_arg (ap, const char *);
len = strlen (str);
cp += 2;
}
else
{
str = cp;
len = next - cp;
cp = next;
}
struct str_list *newp = alloca (sizeof (struct str_list));
newp->str = str;
newp->len = len;
newp->next = list;
list = newp;
++nlist;
}
abort ();
bool written = false;
if (nlist > 0)
{
struct iovec *iov = alloca (nlist * sizeof (struct iovec));
ssize_t total = 0;
for (int cnt = nlist - 1; cnt >= 0; --cnt)
{
iov[cnt].iov_base = list->str;
iov[cnt].iov_len = list->len;
total += list->len;
list = list->next;
}
if (TEMP_FAILURE_RETRY (__writev (fd, iov, nlist)) == total)
written = true;
}
va_end (ap);
/* If we had no success writing the message, use syslog. */
if (! written)
vsyslog (LOG_ERR, fmt, ap_copy);
va_end (ap_copy);
if (do_abort()
/* Kill the application. */
abort ();
}
void
__libc_fatal (message)
const char *message;
{
__libc_message (1, "%s", message);
}
libc_hidden_def (__libc_fatal)

View File

@ -1,4 +1,4 @@
/* Copyright (C) 1993-1995,1997,2000,2002, 2003 Free Software Foundation, Inc.
/* Copyright (C) 1993-1995,1997,2000,2002-2004 Free Software Foundation, Inc.
This file is part of the GNU C Library.
The GNU C Library is free software; you can redistribute it and/or
@ -16,45 +16,143 @@
Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
02111-1307 USA. */
#include <errno.h>
#include <fcntl.h>
#include <paths.h>
#include <stdarg.h>
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <errno.h>
#include <sysdep.h>
#include <string.h>
#include <abort-instr.h>
#include <sysdep.h>
#include <unistd.h>
#include <sys/syslog.h>
#ifndef ABORT_INSTRUCTION
/* No such instruction is available. */
# define ABORT_INSTRUCTION
#endif
/* Abort with an error message. */
#include <not-cancel.h>
#ifdef FATAL_PREPARE_INCLUDE
#include FATAL_PREPARE_INCLUDE
#endif
struct str_list
{
const char *str;
size_t len;
struct str_list *next;
};
/* Abort with an error message. */
void
__libc_message (int do_abort, const char *fmt, ...)
{
va_list ap;
va_list ap_copy;
int fd = -1;
va_start (ap, fmt);
va_copy (ap_copy, ap);
#ifdef FATAL_PREPARE
FATAL_PREPARE;
#endif
/* Open a descriptor for /dev/tty unless the user explicitly
requests errors on standard error. */
const char *on_2 = __secure_getenv ("LIBC_FATAL_STDERR_");
if (on_2 == NULL || *on_2 == '\0')
fd = open_not_cancel_2 (_PATH_TTY, O_RDWR | O_NOCTTY | O_NDELAY);
if (fd == -1)
fd = STDERR_FILENO;
struct str_list *list = NULL;
int nlist = 0;
const char *cp = fmt;
while (*cp != '\0')
{
/* Find the next "%s" or the end of the string. */
const char *next = cp;
while (next[0] != '%' || next[1] != 's')
{
next = __strchrnul (next + 1, '%');
if (next[0] == '\0')
break;
}
/* Determine what to print. */
const char *str;
size_t len;
if (cp[0] == '%' && cp[1] == 's')
{
str = va_arg (ap, const char *);
len = strlen (str);
cp += 2;
}
else
{
str = cp;
len = next - cp;
cp = next;
}
struct str_list *newp = alloca (sizeof (struct str_list));
newp->str = str;
newp->len = len;
newp->next = list;
list = newp;
++nlist;
}
bool written = false;
if (nlist > 0)
{
struct iovec *iov = alloca (nlist * sizeof (struct iovec));
ssize_t total = 0;
for (int cnt = nlist - 1; cnt >= 0; --cnt)
{
iov[cnt].iov_base = (void *) list->str;
iov[cnt].iov_len = list->len;
total += list->len;
list = list->next;
}
INTERNAL_SYSCALL_DECL (err);
ssize_t cnt;
do
cnt = INTERNAL_SYSCALL (writev, err, 3, fd, iov, nlist);
while (INTERNAL_SYSCALL_ERROR_P (cnt, err)
&& INTERNAL_SYSCALL_ERRNO (cnt, err) == EINTR);
if (cnt == total)
written = true;
}
va_end (ap);
/* If we had no success writing the message, use syslog. */
if (! written)
vsyslog (LOG_ERR, fmt, ap_copy);
va_end (ap_copy);
if (do_abort)
/* Terminate the process. */
abort ();
}
void
__libc_fatal (message)
const char *message;
{
size_t len = strlen (message);
while (len > 0)
{
INTERNAL_SYSCALL_DECL (err);
ssize_t count = INTERNAL_SYSCALL (write, err, 3, STDERR_FILENO,
message, len);
if (! INTERNAL_SYSCALL_ERROR_P (count, err))
{
message += count;
len -= count;
}
else if (INTERNAL_SYSCALL_ERRNO (count, err) != EINTR)
break;
}
/* Terminate the process. */
_exit (127);
/* The previous call should never have returned. */
while (1)
/* Try for ever and ever. */
ABORT_INSTRUCTION;
__libc_message (1, "%s", message);
}
libc_hidden_def (__libc_fatal)