* commit 'a161eea241da06c70995248df7a00b6553050e05': Register _cleanup function with atexit
This commit is contained in:
commit
6a0f7d6187
@ -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 \
|
||||
|
@ -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,
|
||||
|
@ -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);
|
||||
}
|
||||
|
||||
|
@ -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();
|
||||
}
|
||||
|
||||
|
@ -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);
|
@ -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);
|
||||
}
|
@ -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);
|
||||
}
|
@ -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);
|
||||
}
|
Loading…
Reference in New Issue
Block a user