1*c9945492SAndroid Build Coastguard Worker #include <unistd.h>
2*c9945492SAndroid Build Coastguard Worker #include <errno.h>
3*c9945492SAndroid Build Coastguard Worker #include "libc.h"
4*c9945492SAndroid Build Coastguard Worker #include "lock.h"
5*c9945492SAndroid Build Coastguard Worker #include "pthread_impl.h"
6*c9945492SAndroid Build Coastguard Worker #include "fork_impl.h"
7*c9945492SAndroid Build Coastguard Worker
8*c9945492SAndroid Build Coastguard Worker static volatile int *const dummy_lockptr = 0;
9*c9945492SAndroid Build Coastguard Worker
10*c9945492SAndroid Build Coastguard Worker weak_alias(dummy_lockptr, __at_quick_exit_lockptr);
11*c9945492SAndroid Build Coastguard Worker weak_alias(dummy_lockptr, __atexit_lockptr);
12*c9945492SAndroid Build Coastguard Worker weak_alias(dummy_lockptr, __gettext_lockptr);
13*c9945492SAndroid Build Coastguard Worker weak_alias(dummy_lockptr, __locale_lockptr);
14*c9945492SAndroid Build Coastguard Worker weak_alias(dummy_lockptr, __random_lockptr);
15*c9945492SAndroid Build Coastguard Worker weak_alias(dummy_lockptr, __sem_open_lockptr);
16*c9945492SAndroid Build Coastguard Worker weak_alias(dummy_lockptr, __stdio_ofl_lockptr);
17*c9945492SAndroid Build Coastguard Worker weak_alias(dummy_lockptr, __syslog_lockptr);
18*c9945492SAndroid Build Coastguard Worker weak_alias(dummy_lockptr, __timezone_lockptr);
19*c9945492SAndroid Build Coastguard Worker weak_alias(dummy_lockptr, __bump_lockptr);
20*c9945492SAndroid Build Coastguard Worker
21*c9945492SAndroid Build Coastguard Worker weak_alias(dummy_lockptr, __vmlock_lockptr);
22*c9945492SAndroid Build Coastguard Worker
23*c9945492SAndroid Build Coastguard Worker static volatile int *const *const atfork_locks[] = {
24*c9945492SAndroid Build Coastguard Worker &__at_quick_exit_lockptr,
25*c9945492SAndroid Build Coastguard Worker &__atexit_lockptr,
26*c9945492SAndroid Build Coastguard Worker &__gettext_lockptr,
27*c9945492SAndroid Build Coastguard Worker &__locale_lockptr,
28*c9945492SAndroid Build Coastguard Worker &__random_lockptr,
29*c9945492SAndroid Build Coastguard Worker &__sem_open_lockptr,
30*c9945492SAndroid Build Coastguard Worker &__stdio_ofl_lockptr,
31*c9945492SAndroid Build Coastguard Worker &__syslog_lockptr,
32*c9945492SAndroid Build Coastguard Worker &__timezone_lockptr,
33*c9945492SAndroid Build Coastguard Worker &__bump_lockptr,
34*c9945492SAndroid Build Coastguard Worker };
35*c9945492SAndroid Build Coastguard Worker
dummy(int x)36*c9945492SAndroid Build Coastguard Worker static void dummy(int x) { }
37*c9945492SAndroid Build Coastguard Worker weak_alias(dummy, __fork_handler);
38*c9945492SAndroid Build Coastguard Worker weak_alias(dummy, __malloc_atfork);
39*c9945492SAndroid Build Coastguard Worker weak_alias(dummy, __aio_atfork);
40*c9945492SAndroid Build Coastguard Worker weak_alias(dummy, __pthread_key_atfork);
41*c9945492SAndroid Build Coastguard Worker weak_alias(dummy, __ldso_atfork);
42*c9945492SAndroid Build Coastguard Worker
dummy_0(void)43*c9945492SAndroid Build Coastguard Worker static void dummy_0(void) { }
44*c9945492SAndroid Build Coastguard Worker weak_alias(dummy_0, __tl_lock);
45*c9945492SAndroid Build Coastguard Worker weak_alias(dummy_0, __tl_unlock);
46*c9945492SAndroid Build Coastguard Worker
fork(void)47*c9945492SAndroid Build Coastguard Worker pid_t fork(void)
48*c9945492SAndroid Build Coastguard Worker {
49*c9945492SAndroid Build Coastguard Worker sigset_t set;
50*c9945492SAndroid Build Coastguard Worker __fork_handler(-1);
51*c9945492SAndroid Build Coastguard Worker __block_app_sigs(&set);
52*c9945492SAndroid Build Coastguard Worker int need_locks = libc.need_locks > 0;
53*c9945492SAndroid Build Coastguard Worker if (need_locks) {
54*c9945492SAndroid Build Coastguard Worker __ldso_atfork(-1);
55*c9945492SAndroid Build Coastguard Worker __pthread_key_atfork(-1);
56*c9945492SAndroid Build Coastguard Worker __aio_atfork(-1);
57*c9945492SAndroid Build Coastguard Worker __inhibit_ptc();
58*c9945492SAndroid Build Coastguard Worker for (int i=0; i<sizeof atfork_locks/sizeof *atfork_locks; i++)
59*c9945492SAndroid Build Coastguard Worker if (*atfork_locks[i]) LOCK(*atfork_locks[i]);
60*c9945492SAndroid Build Coastguard Worker __malloc_atfork(-1);
61*c9945492SAndroid Build Coastguard Worker __tl_lock();
62*c9945492SAndroid Build Coastguard Worker }
63*c9945492SAndroid Build Coastguard Worker pthread_t self=__pthread_self(), next=self->next;
64*c9945492SAndroid Build Coastguard Worker pid_t ret = _Fork();
65*c9945492SAndroid Build Coastguard Worker int errno_save = errno;
66*c9945492SAndroid Build Coastguard Worker if (need_locks) {
67*c9945492SAndroid Build Coastguard Worker if (!ret) {
68*c9945492SAndroid Build Coastguard Worker for (pthread_t td=next; td!=self; td=td->next)
69*c9945492SAndroid Build Coastguard Worker td->tid = -1;
70*c9945492SAndroid Build Coastguard Worker if (__vmlock_lockptr) {
71*c9945492SAndroid Build Coastguard Worker __vmlock_lockptr[0] = 0;
72*c9945492SAndroid Build Coastguard Worker __vmlock_lockptr[1] = 0;
73*c9945492SAndroid Build Coastguard Worker }
74*c9945492SAndroid Build Coastguard Worker }
75*c9945492SAndroid Build Coastguard Worker __tl_unlock();
76*c9945492SAndroid Build Coastguard Worker __malloc_atfork(!ret);
77*c9945492SAndroid Build Coastguard Worker for (int i=0; i<sizeof atfork_locks/sizeof *atfork_locks; i++)
78*c9945492SAndroid Build Coastguard Worker if (*atfork_locks[i])
79*c9945492SAndroid Build Coastguard Worker if (ret) UNLOCK(*atfork_locks[i]);
80*c9945492SAndroid Build Coastguard Worker else **atfork_locks[i] = 0;
81*c9945492SAndroid Build Coastguard Worker __release_ptc();
82*c9945492SAndroid Build Coastguard Worker if (ret) __aio_atfork(0);
83*c9945492SAndroid Build Coastguard Worker __pthread_key_atfork(!ret);
84*c9945492SAndroid Build Coastguard Worker __ldso_atfork(!ret);
85*c9945492SAndroid Build Coastguard Worker }
86*c9945492SAndroid Build Coastguard Worker __restore_sigs(&set);
87*c9945492SAndroid Build Coastguard Worker __fork_handler(!ret);
88*c9945492SAndroid Build Coastguard Worker if (ret<0) errno = errno_save;
89*c9945492SAndroid Build Coastguard Worker return ret;
90*c9945492SAndroid Build Coastguard Worker }
91