1*2c53affbSjmc /* $OpenBSD: atfork.c,v 1.4 2022/12/27 17:10:06 jmc Exp $ */
2514a545fSguenther
3514a545fSguenther /*
4514a545fSguenther * Copyright (c) 2008 Kurt Miller <kurt@openbsd.org>
5514a545fSguenther * Copyright (c) 2008 Philip Guenther <guenther@openbsd.org>
6514a545fSguenther * Copyright (c) 2003 Daniel Eischen <deischen@freebsd.org>
7514a545fSguenther * All rights reserved.
8514a545fSguenther *
9514a545fSguenther * Redistribution and use in source and binary forms, with or without
10514a545fSguenther * modification, are permitted provided that the following conditions
11514a545fSguenther * are met:
12514a545fSguenther * 1. Redistributions of source code must retain the above copyright
13514a545fSguenther * notice, this list of conditions and the following disclaimer.
14514a545fSguenther * 2. Neither the name of the author nor the names of any co-contributors
15514a545fSguenther * may be used to endorse or promote products derived from this software
16514a545fSguenther * without specific prior written permission.
17514a545fSguenther *
18514a545fSguenther * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
19514a545fSguenther * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
20514a545fSguenther * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
21514a545fSguenther * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
22514a545fSguenther * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
23514a545fSguenther * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
24514a545fSguenther * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
25514a545fSguenther * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
26514a545fSguenther * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
27514a545fSguenther * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
28514a545fSguenther * SUCH DAMAGE.
29514a545fSguenther *
30514a545fSguenther * $FreeBSD: /repoman/r/ncvs/src/lib/libc_r/uthread/uthread_atfork.c,v 1.1 2004/12/10 03:36:45 grog Exp $
31514a545fSguenther */
32514a545fSguenther
33514a545fSguenther #include <errno.h>
346897476fSguenther #include <pthread.h>
355be66c01Sguenther #include <stdlib.h>
36514a545fSguenther
37514a545fSguenther #include "thread_private.h"
38514a545fSguenther #include "atfork.h"
39514a545fSguenther
406897476fSguenther int _thread_atfork(void (*_prepare)(void), void (*_parent)(void),
416897476fSguenther void (*_child)(void), void *_dso);
426897476fSguenther PROTO_NORMAL(_thread_atfork);
436897476fSguenther
44514a545fSguenther int
_thread_atfork(void (* prepare)(void),void (* parent)(void),void (* child)(void),void * dso)45514a545fSguenther _thread_atfork(void (*prepare)(void), void (*parent)(void),
46514a545fSguenther void (*child)(void), void *dso)
47514a545fSguenther {
48514a545fSguenther struct atfork_fn *af;
49514a545fSguenther
50514a545fSguenther if ((af = malloc(sizeof *af)) == NULL)
51514a545fSguenther return (ENOMEM);
52514a545fSguenther
53514a545fSguenther af->fn_prepare = prepare;
54514a545fSguenther af->fn_parent = parent;
55514a545fSguenther af->fn_child = child;
56514a545fSguenther af->fn_dso = dso;
57514a545fSguenther _ATFORK_LOCK();
58514a545fSguenther TAILQ_INSERT_TAIL(&_atfork_list, af, fn_next);
59514a545fSguenther _ATFORK_UNLOCK();
60514a545fSguenther return (0);
61514a545fSguenther }
626897476fSguenther DEF_STRONG(_thread_atfork);
636897476fSguenther
646897476fSguenther /*
65*2c53affbSjmc * Copy of pthread_atfork() used by libc and anything statically linked
666897476fSguenther * into the executable. This passes NULL for the dso, so the callbacks
676897476fSguenther * are never removed by dlclose()
686897476fSguenther */
696897476fSguenther int
pthread_atfork(void (* prep)(void),void (* parent)(void),void (* child)(void))706897476fSguenther pthread_atfork(void (*prep)(void), void (*parent)(void), void (*child)(void))
716897476fSguenther {
726897476fSguenther return (_thread_atfork(prep, parent, child, NULL));
736897476fSguenther }
74