xref: /dflybsd-src/lib/libc/stdlib/quick_exit.c (revision 1305f398305bd1fdf2b3b12e44f4d845597b7ff3)
1*a329a283SSascha Wildner /*-
2*a329a283SSascha Wildner * Copyright (c) 2012
3*a329a283SSascha Wildner *	The DragonFly Project.  All rights reserved.
4*a329a283SSascha Wildner *
5*a329a283SSascha Wildner * Redistribution and use in source and binary forms, with or without
6*a329a283SSascha Wildner * modification, are permitted provided that the following conditions
7*a329a283SSascha Wildner * are met:
8*a329a283SSascha Wildner *
9*a329a283SSascha Wildner * 1. Redistributions of source code must retain the above copyright
10*a329a283SSascha Wildner *    notice, this list of conditions and the following disclaimer.
11*a329a283SSascha Wildner * 2. Redistributions in binary form must reproduce the above copyright
12*a329a283SSascha Wildner *    notice, this list of conditions and the following disclaimer in
13*a329a283SSascha Wildner *    the documentation and/or other materials provided with the
14*a329a283SSascha Wildner *    distribution.
15*a329a283SSascha Wildner * 3. Neither the name of The DragonFly Project nor the names of its
16*a329a283SSascha Wildner *    contributors may be used to endorse or promote products derived
17*a329a283SSascha Wildner *    from this software without specific, prior written permission.
18*a329a283SSascha Wildner *
19*a329a283SSascha Wildner * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
20*a329a283SSascha Wildner * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
21*a329a283SSascha Wildner * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
22*a329a283SSascha Wildner * FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE
23*a329a283SSascha Wildner * COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
24*a329a283SSascha Wildner * INCIDENTAL, SPECIAL, EXEMPLARY OR CONSEQUENTIAL DAMAGES (INCLUDING,
25*a329a283SSascha Wildner * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
26*a329a283SSascha Wildner * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
27*a329a283SSascha Wildner * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
28*a329a283SSascha Wildner * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
29*a329a283SSascha Wildner * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
30*a329a283SSascha Wildner * SUCH DAMAGE.
31*a329a283SSascha Wildner */
3222ab97caSVenkatesh Srinivas 
3322ab97caSVenkatesh Srinivas #include <stdlib.h>
3422ab97caSVenkatesh Srinivas #include <unistd.h>
3522ab97caSVenkatesh Srinivas 
3622ab97caSVenkatesh Srinivas #include "libc_private.h"
3722ab97caSVenkatesh Srinivas #include "spinlock.h"
3822ab97caSVenkatesh Srinivas 
3922ab97caSVenkatesh Srinivas 
4022ab97caSVenkatesh Srinivas struct quick_exit_fn {
4122ab97caSVenkatesh Srinivas        struct quick_exit_fn    *next;
4222ab97caSVenkatesh Srinivas        void                    (*func)(void);
4322ab97caSVenkatesh Srinivas };
4422ab97caSVenkatesh Srinivas 
4522ab97caSVenkatesh Srinivas static struct quick_exit_fn *quick_exit_fns;
4622ab97caSVenkatesh Srinivas static spinlock_t quick_exit_spinlock;
4722ab97caSVenkatesh Srinivas 
4822ab97caSVenkatesh Srinivas /*
4922ab97caSVenkatesh Srinivas  * at_quick_exit:
5022ab97caSVenkatesh Srinivas  *
5122ab97caSVenkatesh Srinivas  *     Register a function to be called at quick_exit.
5222ab97caSVenkatesh Srinivas  */
5322ab97caSVenkatesh Srinivas int
at_quick_exit(void (* func)(void))5422ab97caSVenkatesh Srinivas at_quick_exit(void (*func)(void))
5522ab97caSVenkatesh Srinivas {
5622ab97caSVenkatesh Srinivas        struct quick_exit_fn *fn;
5722ab97caSVenkatesh Srinivas 
5822ab97caSVenkatesh Srinivas        fn = malloc(sizeof(struct quick_exit_fn));
5922ab97caSVenkatesh Srinivas        if (!fn)
6022ab97caSVenkatesh Srinivas                return (-1);
6122ab97caSVenkatesh Srinivas 
6222ab97caSVenkatesh Srinivas        fn->func = func;
6322ab97caSVenkatesh Srinivas 
6422ab97caSVenkatesh Srinivas        if (__isthreaded)
6522ab97caSVenkatesh Srinivas                _SPINLOCK(&quick_exit_spinlock);
6622ab97caSVenkatesh Srinivas 
6722ab97caSVenkatesh Srinivas        fn->next = quick_exit_fns;
6822ab97caSVenkatesh Srinivas        quick_exit_fns = fn;
6922ab97caSVenkatesh Srinivas 
7022ab97caSVenkatesh Srinivas        if (__isthreaded)
7122ab97caSVenkatesh Srinivas                _SPINUNLOCK(&quick_exit_spinlock);
7222ab97caSVenkatesh Srinivas 
7322ab97caSVenkatesh Srinivas        return (0);
7422ab97caSVenkatesh Srinivas }
7522ab97caSVenkatesh Srinivas 
7622ab97caSVenkatesh Srinivas /*
7722ab97caSVenkatesh Srinivas  * quick_exit:
7822ab97caSVenkatesh Srinivas  *
7922ab97caSVenkatesh Srinivas  *     Abandon a process. Execute all quick_exit handlers.
8022ab97caSVenkatesh Srinivas  */
8122ab97caSVenkatesh Srinivas void
quick_exit(int status)8222ab97caSVenkatesh Srinivas quick_exit(int status)
8322ab97caSVenkatesh Srinivas {
8422ab97caSVenkatesh Srinivas        struct quick_exit_fn *fn;
8522ab97caSVenkatesh Srinivas 
8622ab97caSVenkatesh Srinivas        if (__isthreaded)
8722ab97caSVenkatesh Srinivas                _SPINLOCK(&quick_exit_spinlock);
8822ab97caSVenkatesh Srinivas        for (fn = quick_exit_fns; fn != NULL; fn = fn->next) {
8922ab97caSVenkatesh Srinivas                fn->func();
9022ab97caSVenkatesh Srinivas        }
9122ab97caSVenkatesh Srinivas        if (__isthreaded)
9222ab97caSVenkatesh Srinivas                _SPINUNLOCK(&quick_exit_spinlock);
9322ab97caSVenkatesh Srinivas 
9422ab97caSVenkatesh Srinivas        _exit(status);
9522ab97caSVenkatesh Srinivas }
96