2N/A * The contents of this file are subject to the terms of the 2N/A * Common Development and Distribution License (the "License"). 2N/A * You may not use this file except in compliance with the License. 2N/A * See the License for the specific language governing permissions 2N/A * and limitations under the License. 2N/A * When distributing Covered Code, include this CDDL HEADER in each 2N/A * If applicable, add the following below this CDDL HEADER, with the 2N/A * fields enclosed by brackets "[]" replaced with your own identifying 2N/A * information: Portions Copyright [yyyy] [name of copyright owner] 2N/A * Copyright 2008 Sun Microsystems, Inc. All rights reserved. 2N/A * Use is subject to license terms. 2N/A/* Copyright (c) 1988 AT&T */ 2N/A/* All Rights Reserved */ 2N/A * Note that memory is managed by lmalloc()/lfree(). 2N/A * Among other reasons, this is occasioned by the insistence of our 2N/A * brothers sh(1) and csh(1) that they can do malloc, etc., better than 2N/A * libc can. Those programs define their own malloc routines, and 2N/A * initialize the underlying mechanism in main(). This means that calls 2N/A * to malloc occuring before main will crash. The loader calls atexit(3C) 2N/A * before calling main, so we'd better avoid malloc() when it does. 2N/A * Another reason for using lmalloc()/lfree() is that the atexit() 2N/A * list must transcend all link maps. See the Linker and Libraries 2N/A * Guide for information on alternate link maps. 2N/A * exitfns_lock is declared to be a recursive mutex so that we 2N/A * can hold it while calling out to the registered functions. 2N/A * If they call back to us, we are self-consistent and everything 2N/A * works, even the case of calling exit() from functions called 2N/A * by _exithandle() (recursive exit()). All that is required is 2N/A * that the registered functions actually return (no longjmp()s). 2N/A * Because exitfns_lock is declared to be a recursive mutex, we 2N/A * cannot use it with lmutex_lock()/lmutex_unlock() and we must 2N/A * use mutex_lock()/mutex_unlock(). This means that atexit() 2N/A * and exit() are not async-signal-safe. We make them fork1-safe 2N/A * via the atexit_locks()/atexit_unlocks() functions, called from 2N/A * libc_prepare_atfork()/libc_child_atfork()/libc_parent_atfork() 2N/A * atexit_locks() and atexit_unlocks() are called on every link map. 2N/A * Do not use curthread->ul_uberdata->atexit_root for these. 2N/A * atexit() is called before the primordial thread is fully set up. 2N/A * Be careful about dereferencing self->ul_uberdata->atexit_root. 2N/A /* disable cancellation while running atexit handlers */ 2N/A * _get_exit_frame_monitor is called by the C++ runtimes. 2N/A * The following is a routine which the loader (ld.so.1) calls when it 2N/A * processes a dlclose call on an object. It resets all signal handlers 2N/A * which fall within the union of the ranges specified by the elements 2N/A * of the array range to SIG_DFL. 2N/A * The following is a routine which the loader (ld.so.1) calls when it 2N/A * processes a dlclose call on an object. It cancels all atfork() entries 2N/A * whose prefork, parent postfork, or child postfork functions fall within 2N/A * the union of the ranges specified by the elements of the array range. 2N/A * dlclose() called from a fork handler. 2N/A * Deleting the entry would wreak havoc. 2N/A * Just null out the function pointers 2N/A * and leave the entry in place. 2N/A /* deleting the list head member */ 2N/A /* we deleted the whole list */ 2N/A * The following is a routine which the loader (ld.so.1) calls when it 2N/A * processes a dlclose call on an object. It sets the destructor 2N/A * function pointer to NULL for all keys whose destructors fall within 2N/A * the union of the ranges specified by the elements of the array range. 2N/A * We don't assign TSD_UNALLOCATED (the equivalent of pthread_key_destroy()) 2N/A * because the thread may use the key's TSD further on in fini processing. 2N/A * The following is a routine which the loader (ld.so.1) calls when it 2N/A * processes dlclose calls on objects with atexit registrations. It 2N/A * executes the exit handlers that fall within the union of the ranges 2N/A * specified by the elements of the array range in the REVERSE ORDER of 2N/A * their registration. Do not change this characteristic; it is REQUIRED 2N/A /* disable cancellation while running atexit handlers */ 2N/A /* We need to execute this one */