X-Git-Url: http://nsz.repo.hu/git/?a=blobdiff_plain;f=src%2Fprocess%2Ffork.c;h=56f1931331f9ba07a8e10e73d37ee4ce6158abf7;hb=cf76df0e1fe09b0d504ca650fdaa01df5bf9ab72;hp=bcd47c97a6e117e16c9c4bf534a26b56edc6aec8;hpb=9080cc153cc2b09881c3245becbd68534db18d7c;p=musl diff --git a/src/process/fork.c b/src/process/fork.c index bcd47c97..56f19313 100644 --- a/src/process/fork.c +++ b/src/process/fork.c @@ -1,18 +1,90 @@ #include -#include "syscall.h" +#include #include "libc.h" +#include "lock.h" #include "pthread_impl.h" +#include "fork_impl.h" + +static volatile int *const dummy_lockptr = 0; + +weak_alias(dummy_lockptr, __at_quick_exit_lockptr); +weak_alias(dummy_lockptr, __atexit_lockptr); +weak_alias(dummy_lockptr, __gettext_lockptr); +weak_alias(dummy_lockptr, __locale_lockptr); +weak_alias(dummy_lockptr, __random_lockptr); +weak_alias(dummy_lockptr, __sem_open_lockptr); +weak_alias(dummy_lockptr, __stdio_ofl_lockptr); +weak_alias(dummy_lockptr, __syslog_lockptr); +weak_alias(dummy_lockptr, __timezone_lockptr); +weak_alias(dummy_lockptr, __bump_lockptr); + +weak_alias(dummy_lockptr, __vmlock_lockptr); + +static volatile int *const *const atfork_locks[] = { + &__at_quick_exit_lockptr, + &__atexit_lockptr, + &__gettext_lockptr, + &__locale_lockptr, + &__random_lockptr, + &__sem_open_lockptr, + &__stdio_ofl_lockptr, + &__syslog_lockptr, + &__timezone_lockptr, + &__bump_lockptr, +}; + +static void dummy(int x) { } +weak_alias(dummy, __fork_handler); +weak_alias(dummy, __malloc_atfork); +weak_alias(dummy, __aio_atfork); +weak_alias(dummy, __pthread_key_atfork); +weak_alias(dummy, __ldso_atfork); + +static void dummy_0(void) { } +weak_alias(dummy_0, __tl_lock); +weak_alias(dummy_0, __tl_unlock); pid_t fork(void) { - pid_t ret; - if (libc.fork_handler) libc.fork_handler(-1); - ret = syscall(SYS_fork); - if (libc.threaded && !ret) { - pthread_t self = __pthread_self(); - self->tid = self->pid = syscall(SYS_getpid); - libc.threads_minus_1 = 0; + sigset_t set; + __fork_handler(-1); + __block_app_sigs(&set); + int need_locks = libc.need_locks > 0; + if (need_locks) { + __ldso_atfork(-1); + __pthread_key_atfork(-1); + __aio_atfork(-1); + __inhibit_ptc(); + for (int i=0; inext; + pid_t ret = _Fork(); + int errno_save = errno; + if (need_locks) { + if (!ret) { + for (pthread_t td=next; td!=self; td=td->next) + td->tid = -1; + if (__vmlock_lockptr) { + __vmlock_lockptr[0] = 0; + __vmlock_lockptr[1] = 0; + } + } + __tl_unlock(); + __malloc_atfork(!ret); + for (int i=0; i