Merge "Register _cleanup function with atexit"
diff --git a/libc/Android.mk b/libc/Android.mk
index 2d56af0..82dcc55 100644
--- a/libc/Android.mk
+++ b/libc/Android.mk
@@ -70,7 +70,6 @@
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 @@
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 @@
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 @@
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 @@
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 @@
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 @@
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 \
diff --git a/libc/bionic/abort.cpp b/libc/bionic/abort.cpp
index 6fcdfda..69ac0e5 100644
--- a/libc/bionic/abort.cpp
+++ b/libc/bionic/abort.cpp
@@ -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 @@
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,
diff --git a/libc/bionic/dlmalloc.c b/libc/bionic/dlmalloc.c
index 66a825b..3a615d2 100644
--- a/libc/bionic/dlmalloc.c
+++ b/libc/bionic/dlmalloc.c
@@ -34,10 +34,7 @@
// 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);
}
diff --git a/libc/stdlib/atexit.c b/libc/stdlib/atexit.c
index b051e22..c607206 100644
--- a/libc/stdlib/atexit.c
+++ b/libc/stdlib/atexit.c
@@ -104,10 +104,10 @@
{
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 @@
}
_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();
+}
+
diff --git a/libc/stdio/findfp.c b/libc/upstream-openbsd/lib/libc/stdio/findfp.c
similarity index 84%
rename from libc/stdio/findfp.c
rename to libc/upstream-openbsd/lib/libc/stdio/findfp.c
index 2dd32c9..b8c7dc1 100644
--- a/libc/stdio/findfp.c
+++ b/libc/upstream-openbsd/lib/libc/stdio/findfp.c
@@ -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 @@
/* 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 @@
_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 @@
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 @@
_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);
diff --git a/libc/upstream-freebsd/lib/libc/stdio/makebuf.c b/libc/upstream-openbsd/lib/libc/stdio/makebuf.c
similarity index 86%
rename from libc/upstream-freebsd/lib/libc/stdio/makebuf.c
rename to libc/upstream-openbsd/lib/libc/stdio/makebuf.c
index a92087e..d47e27c 100644
--- a/libc/upstream-freebsd/lib/libc/stdio/makebuf.c
+++ b/libc/upstream-openbsd/lib/libc/stdio/makebuf.c
@@ -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 @@
* 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 @@
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 @@
{
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);
}
diff --git a/libc/upstream-freebsd/lib/libc/stdio/setvbuf.c b/libc/upstream-openbsd/lib/libc/stdio/setvbuf.c
similarity index 90%
rename from libc/upstream-freebsd/lib/libc/stdio/setvbuf.c
rename to libc/upstream-openbsd/lib/libc/stdio/setvbuf.c
index d396960..6c49f7a 100644
--- a/libc/upstream-freebsd/lib/libc/stdio/setvbuf.c
+++ b/libc/upstream-openbsd/lib/libc/stdio/setvbuf.c
@@ -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 @@
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 @@
/* begin/continue reading, or stay in intermediate state */
fp->_w = 0;
}
- __cleanup = _cleanup;
-
FUNLOCKFILE(fp);
+ __atexit_register_cleanup(_cleanup);
+
return (ret);
}
diff --git a/libc/upstream-netbsd/lib/libc/stdlib/exit.c b/libc/upstream-openbsd/lib/libc/stdlib/exit.c
similarity index 76%
rename from libc/upstream-netbsd/lib/libc/stdlib/exit.c
rename to libc/upstream-openbsd/lib/libc/stdlib/exit.c
index 67e6adf..ef8b335 100644
--- a/libc/upstream-netbsd/lib/libc/stdlib/exit.c
+++ b/libc/upstream-openbsd/lib/libc/stdlib/exit.c
@@ -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
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);
}