am a161eea2: am 7f3d6b69: am 0a5b0166: Merge "Register _cleanup function with atexit"

* commit 'a161eea241da06c70995248df7a00b6553050e05':
  Register _cleanup function with atexit
This commit is contained in:
Dmitriy Ivanov 2014-05-16 00:43:54 +00:00 committed by Android Git Automerger
commit 6a0f7d6187
8 changed files with 73 additions and 100 deletions

View File

@ -70,7 +70,6 @@ libc_common_src_files := \
bionic/sigsetmask.c \
bionic/system_properties_compat.c \
bionic/unlockpt.c \
stdio/findfp.c \
stdio/snprintf.c\
stdio/sprintf.c \
stdlib/atexit.c \
@ -227,9 +226,7 @@ libc_upstream_freebsd_src_files := \
upstream-freebsd/lib/libc/stdio/fclose.c \
upstream-freebsd/lib/libc/stdio/flags.c \
upstream-freebsd/lib/libc/stdio/fopen.c \
upstream-freebsd/lib/libc/stdio/makebuf.c \
upstream-freebsd/lib/libc/stdio/mktemp.c \
upstream-freebsd/lib/libc/stdio/setvbuf.c \
upstream-freebsd/lib/libc/stdlib/abs.c \
upstream-freebsd/lib/libc/stdlib/getopt_long.c \
upstream-freebsd/lib/libc/stdlib/imaxabs.c \
@ -279,7 +276,6 @@ libc_upstream_netbsd_src_files := \
upstream-netbsd/lib/libc/stdlib/div.c \
upstream-netbsd/lib/libc/stdlib/drand48.c \
upstream-netbsd/lib/libc/stdlib/erand48.c \
upstream-netbsd/lib/libc/stdlib/exit.c \
upstream-netbsd/lib/libc/stdlib/jrand48.c \
upstream-netbsd/lib/libc/stdlib/ldiv.c \
upstream-netbsd/lib/libc/stdlib/lldiv.c \
@ -381,6 +377,7 @@ libc_upstream_openbsd_src_files := \
upstream-openbsd/lib/libc/stdio/fgetwc.c \
upstream-openbsd/lib/libc/stdio/fgetws.c \
upstream-openbsd/lib/libc/stdio/fileno.c \
upstream-openbsd/lib/libc/stdio/findfp.c \
upstream-openbsd/lib/libc/stdio/fprintf.c \
upstream-openbsd/lib/libc/stdio/fpurge.c \
upstream-openbsd/lib/libc/stdio/fputc.c \
@ -407,6 +404,7 @@ libc_upstream_openbsd_src_files := \
upstream-openbsd/lib/libc/stdio/gets.c \
upstream-openbsd/lib/libc/stdio/getwc.c \
upstream-openbsd/lib/libc/stdio/getwchar.c \
upstream-openbsd/lib/libc/stdio/makebuf.c \
upstream-openbsd/lib/libc/stdio/perror.c \
upstream-openbsd/lib/libc/stdio/printf.c \
upstream-openbsd/lib/libc/stdio/putc.c \
@ -422,6 +420,7 @@ libc_upstream_openbsd_src_files := \
upstream-openbsd/lib/libc/stdio/scanf.c \
upstream-openbsd/lib/libc/stdio/setbuf.c \
upstream-openbsd/lib/libc/stdio/setbuffer.c \
upstream-openbsd/lib/libc/stdio/setvbuf.c \
upstream-openbsd/lib/libc/stdio/sscanf.c \
upstream-openbsd/lib/libc/stdio/stdio.c \
upstream-openbsd/lib/libc/stdio/swprintf.c \
@ -451,6 +450,7 @@ libc_upstream_openbsd_src_files := \
upstream-openbsd/lib/libc/stdlib/atoi.c \
upstream-openbsd/lib/libc/stdlib/atol.c \
upstream-openbsd/lib/libc/stdlib/atoll.c \
upstream-openbsd/lib/libc/stdlib/exit.c \
upstream-openbsd/lib/libc/stdlib/getenv.c \
upstream-openbsd/lib/libc/stdlib/setenv.c \
upstream-openbsd/lib/libc/stdlib/strtoimax.c \

View File

@ -32,8 +32,6 @@
#include <unistd.h>
#include "atexit.h"
__LIBC_HIDDEN__ void (*__cleanup)();
#ifdef __arm__
extern "C" __LIBC_HIDDEN__ void __libc_android_abort()
#else
@ -47,11 +45,6 @@ void abort()
sigdelset(&mask, SIGABRT);
sigprocmask(SIG_SETMASK, &mask, NULL);
// POSIX requires we flush stdio buffers on abort.
if (__cleanup) {
(*__cleanup)();
}
raise(SIGABRT);
// If SIGABRT ignored, or caught and the handler returns,

View File

@ -34,10 +34,7 @@ static void* named_anonymous_mmap(size_t length);
// Ugly inclusion of C file so that bionic specific #defines configure dlmalloc.
#include "../upstream-dlmalloc/malloc.c"
extern void (*__cleanup)();
static void __bionic_heap_corruption_error(const char* function) {
__cleanup = NULL; // The heap is corrupt. We can forget trying to shut down stdio.
__libc_fatal("heap corruption detected by %s", function);
}

View File

@ -104,10 +104,10 @@ __cxa_atexit(void (*func)(void *), void *arg, void *dso)
{
struct atexit *p = __atexit;
struct atexit_fn *fnp;
int pgsize = getpagesize();
size_t pgsize = sysconf(_SC_PAGESIZE);
int ret = -1;
if (pgsize < (int)sizeof(*p))
if (pgsize < sizeof(*p))
return (-1);
_ATEXIT_LOCK();
p = __atexit;
@ -216,3 +216,41 @@ __cxa_finalize(void *dso)
}
_ATEXIT_UNLOCK();
}
/*
* Register the cleanup function
*/
void
__atexit_register_cleanup(void (*func)(void))
{
struct atexit *p;
size_t pgsize = sysconf(_SC_PAGESIZE);
if (pgsize < sizeof(*p))
return;
_ATEXIT_LOCK();
p = __atexit;
while (p != NULL && p->next != NULL)
p = p->next;
if (p == NULL) {
p = mmap(NULL, pgsize, PROT_READ | PROT_WRITE,
MAP_ANON | MAP_PRIVATE, -1, 0);
if (p == MAP_FAILED)
goto unlock;
p->ind = 1;
p->max = (pgsize - ((char *)&p->fns[0] - (char *)p)) /
sizeof(p->fns[0]);
p->next = NULL;
__atexit = p;
} else {
if (mprotect(p, pgsize, PROT_READ | PROT_WRITE))
goto unlock;
}
p->fns[0].cxa_func = (void (*)(void*))func;
p->fns[0].fn_arg = NULL;
p->fns[0].fn_dso = NULL;
mprotect(p, pgsize, PROT_READ);
unlock:
_ATEXIT_UNLOCK();
}

View File

@ -1,4 +1,4 @@
/* $OpenBSD: findfp.c,v 1.9 2005/08/08 08:05:36 espie Exp $ */
/* $OpenBSD: findfp.c,v 1.15 2013/12/17 16:33:27 deraadt Exp $ */
/*-
* Copyright (c) 1990, 1993
* The Regents of the University of California. All rights reserved.
@ -54,7 +54,7 @@ int __sdidinit;
/* p r w flags file _bf z cookie close read seek write
ext */
/* the usual - (stdin + stdout + stderr) */
/* the usual - (stdin + stdout + stderr) */
static FILE usual[FOPEN_MAX - 3];
static struct __sfileext usualext[FOPEN_MAX - 3];
static struct glue uglue = { 0, FOPEN_MAX - 3, usual };
@ -62,7 +62,6 @@ static struct glue *lastglue = &uglue;
_THREAD_PRIVATE_MUTEX(__sfp_mutex);
static struct __sfileext __sFext[3];
FILE __sF[3] = {
std(__SRD, STDIN_FILENO), /* stdin */
std(__SWR, STDOUT_FILENO), /* stdout */
@ -144,35 +143,11 @@ found:
return (fp);
}
#if 0
#define getdtablesize() sysconf(_SC_OPEN_MAX)
/*
* XXX. Force immediate allocation of internal memory. Not used by stdio,
* but documented historically for certain applications. Bad applications.
*/
void
f_prealloc(void)
{
struct glue *g;
int n;
n = getdtablesize() - FOPEN_MAX + 20; /* 20 for slop. */
for (g = &__sglue; (n -= g->niobs) > 0 && g->next; g = g->next)
/* void */;
if (n > 0 && ((g = moreglue(n)) != NULL)) {
_THREAD_PRIVATE_MUTEX_LOCK(__sfp_mutex);
lastglue->next = g;
lastglue = g;
_THREAD_PRIVATE_MUTEX_UNLOCK(__sfp_mutex);
}
}
#endif
/*
* exit() calls _cleanup() through *__cleanup, set whenever we
* open or buffer a file. This chicanery is done so that programs
* that do not use stdio need not link it all in.
* exit() and abort() call _cleanup() through the callback registered
* with __atexit_register_cleanup(), set whenever we open or buffer a
* file. This chicanery is done so that programs that do not use stdio
* need not link it all in.
*
* The name `_cleanup' is, alas, fairly well known outside stdio.
*/
@ -199,7 +174,7 @@ __sinit(void)
_FILEEXT_SETUP(usual+i, usualext+i);
}
/* make sure we clean up on exit */
__cleanup = _cleanup; /* conservative */
__atexit_register_cleanup(_cleanup); /* conservative */
__sdidinit = 1;
out:
_THREAD_PRIVATE_MUTEX_UNLOCK(__sinit_mutex);

View File

@ -1,3 +1,4 @@
/* $OpenBSD: makebuf.c,v 1.8 2005/12/28 18:50:22 millert Exp $ */
/*-
* Copyright (c) 1990, 1993
* The Regents of the University of California. All rights reserved.
@ -30,21 +31,11 @@
* SUCH DAMAGE.
*/
#if defined(LIBC_SCCS) && !defined(lint)
static char sccsid[] = "@(#)makebuf.c 8.1 (Berkeley) 6/4/93";
#endif /* LIBC_SCCS and not lint */
#include <sys/cdefs.h>
__FBSDID("$FreeBSD$");
#include "namespace.h"
#include <sys/types.h>
#include <sys/stat.h>
#include <unistd.h>
#include <stdio.h>
#include <stdlib.h>
#include "un-namespace.h"
#include "libc_private.h"
#include "local.h"
/*
@ -52,7 +43,7 @@ __FBSDID("$FreeBSD$");
* Per the ANSI C standard, ALL tty devices default to line buffered.
*
* As a side effect, we set __SOPT or __SNPT (en/dis-able fseek
* optimisation) right after the _fstat() that finds the buffer size.
* optimisation) right after the fstat() that finds the buffer size.
*/
void
__smakebuf(FILE *fp)
@ -74,7 +65,7 @@ __smakebuf(FILE *fp)
fp->_bf._size = 1;
return;
}
__cleanup = _cleanup;
__atexit_register_cleanup(_cleanup);
flags |= __SMBF;
fp->_bf._base = fp->_p = p;
fp->_bf._size = size;
@ -91,15 +82,15 @@ __swhatbuf(FILE *fp, size_t *bufsize, int *couldbetty)
{
struct stat st;
if (fp->_file < 0 || _fstat(fp->_file, &st) < 0) {
if (fp->_file < 0 || fstat(fp->_file, &st) < 0) {
*couldbetty = 0;
*bufsize = BUFSIZ;
return (__SNPT);
}
/* could be a tty iff it is a character device */
*couldbetty = (st.st_mode & S_IFMT) == S_IFCHR;
if (st.st_blksize <= 0) {
*couldbetty = S_ISCHR(st.st_mode);
if (st.st_blksize == 0) {
*bufsize = BUFSIZ;
return (__SNPT);
}

View File

@ -1,3 +1,4 @@
/* $OpenBSD: setvbuf.c,v 1.11 2009/11/09 00:18:27 kurt Exp $ */
/*-
* Copyright (c) 1990, 1993
* The Regents of the University of California. All rights reserved.
@ -30,25 +31,16 @@
* SUCH DAMAGE.
*/
#if defined(LIBC_SCCS) && !defined(lint)
static char sccsid[] = "@(#)setvbuf.c 8.2 (Berkeley) 11/16/93";
#endif /* LIBC_SCCS and not lint */
#include <sys/cdefs.h>
__FBSDID("$FreeBSD$");
#include "namespace.h"
#include <stdio.h>
#include <stdlib.h>
#include "un-namespace.h"
#include "local.h"
#include "libc_private.h"
/*
* Set one of the three kinds of buffering, optionally including
* a buffer.
*/
int
setvbuf(FILE * __restrict fp, char * __restrict buf, int mode, size_t size)
setvbuf(FILE *fp, char *buf, int mode, size_t size)
{
int ret, flags;
size_t iosize;
@ -63,22 +55,23 @@ setvbuf(FILE * __restrict fp, char * __restrict buf, int mode, size_t size)
if ((mode != _IOFBF && mode != _IOLBF) || (int)size < 0)
return (EOF);
FLOCKFILE(fp);
/*
* Write current buffer, if any. Discard unread input (including
* ungetc data), cancel line buffering, and free old buffer if
* malloc()ed. We also clear any eof condition, as if this were
* a seek.
*/
FLOCKFILE(fp);
ret = 0;
(void)__sflush(fp);
if (HASUB(fp))
FREEUB(fp);
WCIO_FREE(fp);
fp->_r = fp->_lbfsize = 0;
flags = fp->_flags;
if (flags & __SMBF)
free((void *)fp->_bf._base);
flags &= ~(__SLBF | __SNBF | __SMBF | __SOPT | __SOFF | __SNPT | __SEOF);
flags &= ~(__SLBF | __SNBF | __SMBF | __SOPT | __SNPT | __SEOF);
/* If setting unbuffered mode, skip all the hard work. */
if (mode == _IONBF)
@ -154,8 +147,8 @@ nbf:
/* begin/continue reading, or stay in intermediate state */
fp->_w = 0;
}
__cleanup = _cleanup;
FUNLOCKFILE(fp);
__atexit_register_cleanup(_cleanup);
return (ret);
}

View File

@ -1,8 +1,7 @@
/* $NetBSD: exit.c,v 1.15 2011/05/18 19:36:36 dsl Exp $ */
/* $OpenBSD: exit.c,v 1.12 2007/09/03 14:40:16 millert Exp $ */
/*-
* Copyright (c) 1990, 1993
* The Regents of the University of California. All rights reserved.
* Copyright (c) 1990 The Regents of the University of California.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
@ -29,23 +28,11 @@
* SUCH DAMAGE.
*/
#include <sys/cdefs.h>
#if defined(LIBC_SCCS) && !defined(lint)
#if 0
static char sccsid[] = "@(#)exit.c 8.1 (Berkeley) 6/4/93";
#else
__RCSID("$NetBSD: exit.c,v 1.15 2011/05/18 19:36:36 dsl Exp $");
#endif
#endif /* LIBC_SCCS and not lint */
#include <sys/types.h>
#include <sys/mman.h>
#include <stdlib.h>
#include <unistd.h>
#ifdef _LIBC
#include "reentrant.h"
#include "atexit.h"
#endif
void (*__cleanup)(void);
/*
* Exit, flushing stdio buffers if necessary.
@ -53,11 +40,10 @@ void (*__cleanup)(void);
void
exit(int status)
{
#ifdef _LIBC
/*
* Call functions registered by atexit() or _cxa_atexit()
* (including the stdio cleanup routine) and then _exit().
*/
__cxa_finalize(NULL);
#endif
if (__cleanup)
(*__cleanup)();
_exit(status);
}