2022-01-02 02:54:23 +08:00
|
|
|
/* Copyright (C) 1999-2022 Free Software Foundation, Inc.
|
1999-12-28 05:50:29 +08:00
|
|
|
This file is part of the GNU C Library.
|
|
|
|
|
|
|
|
The GNU C Library is free software; you can redistribute it and/or
|
2001-07-06 12:58:11 +08:00
|
|
|
modify it under the terms of the GNU Lesser General Public
|
|
|
|
License as published by the Free Software Foundation; either
|
|
|
|
version 2.1 of the License, or (at your option) any later version.
|
1999-12-28 05:50:29 +08:00
|
|
|
|
|
|
|
The GNU C Library is distributed in the hope that it will be useful,
|
|
|
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
|
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
2001-07-06 12:58:11 +08:00
|
|
|
Lesser General Public License for more details.
|
1999-12-28 05:50:29 +08:00
|
|
|
|
2001-07-06 12:58:11 +08:00
|
|
|
You should have received a copy of the GNU Lesser General Public
|
2012-02-10 07:18:22 +08:00
|
|
|
License along with the GNU C Library; if not, see
|
Prefer https to http for gnu.org and fsf.org URLs
Also, change sources.redhat.com to sourceware.org.
This patch was automatically generated by running the following shell
script, which uses GNU sed, and which avoids modifying files imported
from upstream:
sed -ri '
s,(http|ftp)(://(.*\.)?(gnu|fsf|sourceware)\.org($|[^.]|\.[^a-z])),https\2,g
s,(http|ftp)(://(.*\.)?)sources\.redhat\.com($|[^.]|\.[^a-z]),https\2sourceware.org\4,g
' \
$(find $(git ls-files) -prune -type f \
! -name '*.po' \
! -name 'ChangeLog*' \
! -path COPYING ! -path COPYING.LIB \
! -path manual/fdl-1.3.texi ! -path manual/lgpl-2.1.texi \
! -path manual/texinfo.tex ! -path scripts/config.guess \
! -path scripts/config.sub ! -path scripts/install-sh \
! -path scripts/mkinstalldirs ! -path scripts/move-if-change \
! -path INSTALL ! -path locale/programs/charmap-kw.h \
! -path po/libc.pot ! -path sysdeps/gnu/errlist.c \
! '(' -name configure \
-execdir test -f configure.ac -o -f configure.in ';' ')' \
! '(' -name preconfigure \
-execdir test -f preconfigure.ac ';' ')' \
-print)
and then by running 'make dist-prepare' to regenerate files built
from the altered files, and then executing the following to cleanup:
chmod a+x sysdeps/unix/sysv/linux/riscv/configure
# Omit irrelevant whitespace and comment-only changes,
# perhaps from a slightly-different Autoconf version.
git checkout -f \
sysdeps/csky/configure \
sysdeps/hppa/configure \
sysdeps/riscv/configure \
sysdeps/unix/sysv/linux/csky/configure
# Omit changes that caused a pre-commit check to fail like this:
# remote: *** error: sysdeps/powerpc/powerpc64/ppc-mcount.S: trailing lines
git checkout -f \
sysdeps/powerpc/powerpc64/ppc-mcount.S \
sysdeps/unix/sysv/linux/s390/s390-64/syscall.S
# Omit change that caused a pre-commit check to fail like this:
# remote: *** error: sysdeps/sparc/sparc64/multiarch/memcpy-ultra3.S: last line does not end in newline
git checkout -f sysdeps/sparc/sparc64/multiarch/memcpy-ultra3.S
2019-09-07 13:40:42 +08:00
|
|
|
<https://www.gnu.org/licenses/>. */
|
1999-12-28 05:50:29 +08:00
|
|
|
|
2005-09-28 08:10:09 +08:00
|
|
|
#include <assert.h>
|
2004-12-23 04:10:10 +08:00
|
|
|
#include <stdlib.h>
|
2013-05-01 23:46:34 +08:00
|
|
|
#include <stdint.h>
|
2005-09-28 08:10:09 +08:00
|
|
|
|
2015-09-09 05:11:03 +08:00
|
|
|
#include <libc-lock.h>
|
1999-12-28 05:50:29 +08:00
|
|
|
#include "exit.h"
|
2005-12-19 01:32:37 +08:00
|
|
|
#include <sysdep.h>
|
1999-12-28 05:50:29 +08:00
|
|
|
|
Update.
* sysdeps/mach/hurd/chown.c: Use INTDEF for __chown.
* sysdeps/unix/sysv/aix/chown.c: Likewise.
* sysdeps/unix/grantpt.c: Use INTUSE for __chown calls.
* sysdeps/unix/sysv/linux/m68k/chown.c: Likewise.
* sysdeps/unix/sysv/linux/powerpc/chown.c: Likewise.
* sysdeps/unix/sysv/linux/i386/chown.c: Use INTDEF2 to define
__chown_internal.
* sysdeps/unix/sysv/linux/s390/s390-32//chown.c: Likewise.
* intl/dcngettext.c [_LIBC]: Use INTUSE for __dcngettext.
* intl/dngettext.c [_LIBC] (DCNGETTEXT): Use INTUSE.
* intl/ngettext.c: Likewise.
* include/sys/socket.h: Declare __connect_internal and define
__connect macro if not NOT_IN_libc.
* sysdeps/mach/hurd/connect.c: Use INTDEF for __connect.
* sysdeps/unix/sysv/aix/connect.c: Likewise.
* sysdeps/unix/sysv/linux/connect.S: Add __connect_internal alias.
* include/unistd.h: Declare __close_internal and define __close macro
if not NOT_IN_libc.
* libio/libioP.h (JUMO0, JUMP1, JUMP2, JUMP3, WJUMP0, WJUMP1, WJUMP2,
WJUMP3): Add extra parenthesis to avoid expanding element names with
macors like __close.
* sysdeps/unix/syscalls.list: Add __close_internal alias.
* include/unistd.h: Declare __dup2_internal and define __dup2 macro
if not NOT_IN_libc.
* sysdeps/mach/hurd/dup2.c: Use INTDEF for __dup2.
* sysdeps/posix/dup2.c: Use INTDEF for __dup2.
* sysdeps/unix/syscalls.list: Add __dup2_internal alias.
* include/unistd.h: Declare __fork_internal and define __fork macro
if not NOT_IN_libc.
* sysdeps/mach/hurd/fork.c: Use INTDEF for __fork.
* sysdeps/unix/sysv/aix/fork.c: Likewise.
* sysdeps/unix/sysv/linux/syscalls.list: Add __fork_internal alias.
* include/stdio_ext.h: Declare __fsetlocking_internal and define
__fsetlocking macro to use it if not NOT_IN_libc.
* libio/__fsetlocking.c: Use INTDEF for __fsetlocking.
* libio/__fbufsize.c: Correct copyright.
* libio/__flbf.c: Likewise.
* libio/__fpending.c: Likewise.
* libio/__fpurge.c: Likewise.
* libio/__freadable.c: Likewise.
* libio/__freading.c: Likewise.
* libio/__fsetlocking.c: Likewise.
* libio/__fwritable.c: Likewise.
* libio/__fwriting.c: Likewise.
* include/stdio.h: Declare __asprintf_internal and define __asprintf
macro to use it if not NOT_IN_libc.
* stdio-common/asprintf.c: Use INTDEF for __asprintf.
* include/mntent.h: Declare __setmntent_internal,
__getmntent_r_internal, __endmntent_internal. Define __setmntent,
__getmntent_r, and __endmntent macros to use these functions if not
NOT_IN_libc.
* misc/mntent_r.c: Use INTDEF for __setmntent, __getmntent_r, and
__endmntent.
* include/math.h: Declare __finite_internal, __finitef_internal, and
__finitel_internal. Redefine isfinite macro if in libc or libm using
these functions.
* sysdeps/generic/s_ldexp.c: Use INTUSE for __finite calls.
* sysdeps/generic/s_ldexpf.c: Use INTUSE for __finitef calls.
* sysdeps/generic/s_ldexpl.c: Use INTUSE for __finitel calls.
* sysdeps/i386/fpu/s_finite.S: Define _internal alias.
* sysdeps/i386/fpu/s_finitef.S: Likewise.
* sysdeps/i386/fpu/s_finitel.S: Likewise.
* sysdeps/ieee754/dbl-64/s_finite.c: Likewise.
* sysdeps/ieee754/flt-32/s_finitef.c: Likewise.
* sysdeps/ieee754/ldbl-128/s_finitel.c: Likewise.
* sysdeps/ieee754/ldbl-96/s_finitel.c: Likewise.
* include/fcntl.h: Declare __fcntl_internal. Define __fcntl macro
to use this function if not NOT_IN_libc.
* libio/iofdopen.c (_IO_fcntl): Use INTUSE.
* sysdeps/generic/fcntl.c: Use INTDEF for __fcntl.
* sysdeps/mach/hurd/fcntl.c: Likewise.
* sysdeps/unix/sysv/aix/fcntl.c: Likewise.
* sysdeps/unix/sysv/linux/i386/fcntl.c: Likewise.
* include/argz.h: Declare __argz_count_internal and
__argz_stringify_internal.
* intl/l10nflist.c [_LIBC]: Use INTUSE for __argz_count and
__argz_stringify.
* string/argz-count.c: Use INTDEF for __argz_count.
* string/argz-stringify.c: Use INTDEF for __argz_stringify.
* include/stdlib.h: Declare __cxa_atexit_internal and define
__cxa_atexit macro if not NOT_IN_libc.
* stdlib/cxa_atexit.c: Use INTDEF for __cxa_atexit.
* dlfcn/Makefile: Define NOT_IN_libc when compiling modcxaatexit.c.
* assert/assert.c: Use INTDEF for __assert_fail.
* assert/__assert.c: Use INTUSE for call to __assert_fail.
* include/assert.h: Declare __assert_fail_internal.
2002-04-10 04:36:24 +08:00
|
|
|
#undef __cxa_atexit
|
|
|
|
|
2017-09-21 00:31:48 +08:00
|
|
|
/* See concurrency notes in stdlib/exit.h where this lock is declared. */
|
|
|
|
__libc_lock_define_initialized (, __exit_funcs_lock)
|
|
|
|
|
2009-03-09 03:53:12 +08:00
|
|
|
|
1999-12-28 05:50:29 +08:00
|
|
|
int
|
2009-03-09 03:53:12 +08:00
|
|
|
attribute_hidden
|
|
|
|
__internal_atexit (void (*func) (void *), void *arg, void *d,
|
|
|
|
struct exit_function_list **listp)
|
1999-12-28 05:50:29 +08:00
|
|
|
{
|
2017-09-21 00:31:48 +08:00
|
|
|
struct exit_function *new;
|
|
|
|
|
2018-09-02 01:50:41 +08:00
|
|
|
/* As a QoI issue we detect NULL early with an assertion instead
|
|
|
|
of a SIGSEGV at program exit when the handler is run (bug 20544). */
|
|
|
|
assert (func != NULL);
|
|
|
|
|
2017-09-21 00:31:48 +08:00
|
|
|
__libc_lock_lock (__exit_funcs_lock);
|
|
|
|
new = __new_exitfn (listp);
|
1999-12-28 05:50:29 +08:00
|
|
|
|
|
|
|
if (new == NULL)
|
2017-09-21 00:31:48 +08:00
|
|
|
{
|
|
|
|
__libc_lock_unlock (__exit_funcs_lock);
|
|
|
|
return -1;
|
|
|
|
}
|
1999-12-28 05:50:29 +08:00
|
|
|
|
2005-12-19 01:32:37 +08:00
|
|
|
#ifdef PTR_MANGLE
|
|
|
|
PTR_MANGLE (func);
|
|
|
|
#endif
|
2001-01-12 15:29:55 +08:00
|
|
|
new->func.cxa.fn = (void (*) (void *, int)) func;
|
1999-12-28 05:50:29 +08:00
|
|
|
new->func.cxa.arg = arg;
|
|
|
|
new->func.cxa.dso_handle = d;
|
2005-12-19 01:32:37 +08:00
|
|
|
new->flavor = ef_cxa;
|
2017-09-21 00:31:48 +08:00
|
|
|
__libc_lock_unlock (__exit_funcs_lock);
|
1999-12-28 05:50:29 +08:00
|
|
|
return 0;
|
|
|
|
}
|
2009-03-09 03:53:12 +08:00
|
|
|
|
|
|
|
|
|
|
|
/* Register a function to be called by exit or when a shared library
|
|
|
|
is unloaded. This function is only called from code generated by
|
|
|
|
the C++ compiler. */
|
|
|
|
int
|
|
|
|
__cxa_atexit (void (*func) (void *), void *arg, void *d)
|
|
|
|
{
|
|
|
|
return __internal_atexit (func, arg, d, &__exit_funcs);
|
|
|
|
}
|
2014-10-09 19:22:33 +08:00
|
|
|
libc_hidden_def (__cxa_atexit)
|
2001-02-27 01:53:15 +08:00
|
|
|
|
|
|
|
|
|
|
|
static struct exit_function_list initial;
|
|
|
|
struct exit_function_list *__exit_funcs = &initial;
|
2006-07-26 15:27:20 +08:00
|
|
|
uint64_t __new_exitfn_called;
|
2001-02-27 01:53:15 +08:00
|
|
|
|
2017-09-21 00:31:48 +08:00
|
|
|
/* Must be called with __exit_funcs_lock held. */
|
2001-02-27 01:53:15 +08:00
|
|
|
struct exit_function *
|
2009-03-09 03:53:12 +08:00
|
|
|
__new_exitfn (struct exit_function_list **listp)
|
2001-02-27 01:53:15 +08:00
|
|
|
{
|
2005-09-28 08:10:09 +08:00
|
|
|
struct exit_function_list *p = NULL;
|
2001-02-27 01:53:15 +08:00
|
|
|
struct exit_function_list *l;
|
2005-09-28 08:10:09 +08:00
|
|
|
struct exit_function *r = NULL;
|
2001-02-27 01:53:15 +08:00
|
|
|
size_t i = 0;
|
|
|
|
|
2017-09-21 00:31:48 +08:00
|
|
|
if (__exit_funcs_done)
|
|
|
|
/* Exit code is finished processing all registered exit functions,
|
|
|
|
therefore we fail this registration. */
|
|
|
|
return NULL;
|
2001-02-27 01:53:15 +08:00
|
|
|
|
2009-03-09 03:53:12 +08:00
|
|
|
for (l = *listp; l != NULL; p = l, l = l->next)
|
2001-02-27 01:53:15 +08:00
|
|
|
{
|
2005-09-28 08:10:09 +08:00
|
|
|
for (i = l->idx; i > 0; --i)
|
|
|
|
if (l->fns[i - 1].flavor != ef_free)
|
2001-02-27 01:53:15 +08:00
|
|
|
break;
|
2005-09-28 08:10:09 +08:00
|
|
|
|
|
|
|
if (i > 0)
|
2001-02-27 01:53:15 +08:00
|
|
|
break;
|
|
|
|
|
2005-09-28 08:10:09 +08:00
|
|
|
/* This block is completely unused. */
|
|
|
|
l->idx = 0;
|
2001-02-27 01:53:15 +08:00
|
|
|
}
|
|
|
|
|
2005-09-28 08:10:09 +08:00
|
|
|
if (l == NULL || i == sizeof (l->fns) / sizeof (l->fns[0]))
|
2001-02-27 01:53:15 +08:00
|
|
|
{
|
2005-09-28 08:10:09 +08:00
|
|
|
/* The last entry in a block is used. Use the first entry in
|
|
|
|
the previous block if it exists. Otherwise create a new one. */
|
|
|
|
if (p == NULL)
|
2001-02-27 01:53:15 +08:00
|
|
|
{
|
2005-09-28 08:10:09 +08:00
|
|
|
assert (l != NULL);
|
|
|
|
p = (struct exit_function_list *)
|
|
|
|
calloc (1, sizeof (struct exit_function_list));
|
|
|
|
if (p != NULL)
|
|
|
|
{
|
2009-03-09 03:53:12 +08:00
|
|
|
p->next = *listp;
|
|
|
|
*listp = p;
|
2005-09-28 08:10:09 +08:00
|
|
|
}
|
|
|
|
}
|
2001-02-27 01:53:15 +08:00
|
|
|
|
2005-09-28 08:10:09 +08:00
|
|
|
if (p != NULL)
|
|
|
|
{
|
|
|
|
r = &p->fns[0];
|
|
|
|
p->idx = 1;
|
2001-02-27 01:53:15 +08:00
|
|
|
}
|
|
|
|
}
|
2005-09-28 08:10:09 +08:00
|
|
|
else
|
|
|
|
{
|
|
|
|
/* There is more room in the block. */
|
|
|
|
r = &l->fns[i];
|
|
|
|
l->idx = i + 1;
|
|
|
|
}
|
2001-02-27 01:53:15 +08:00
|
|
|
|
|
|
|
/* Mark entry as used, but we don't know the flavor now. */
|
2005-09-28 08:10:09 +08:00
|
|
|
if (r != NULL)
|
2006-07-26 15:27:20 +08:00
|
|
|
{
|
|
|
|
r->flavor = ef_us;
|
|
|
|
++__new_exitfn_called;
|
|
|
|
}
|
2001-02-27 01:53:15 +08:00
|
|
|
|
2005-09-28 08:10:09 +08:00
|
|
|
return r;
|
2001-02-27 01:53:15 +08:00
|
|
|
}
|