X-Git-Url: http://nsz.repo.hu/git/?a=blobdiff_plain;f=src%2Fprocess%2Ffork.c;h=54bc289202955a8f47a0ed2f17d8b3722500bc81;hb=a75283d777ed1827ed247dbb465818a0ce371c8f;hp=a04e8929a70e10ce7e32e3e44834ebb9ab51e049;hpb=870cc679771f776333953b2a990a107393d9d0fd;p=musl diff --git a/src/process/fork.c b/src/process/fork.c index a04e8929..54bc2892 100644 --- a/src/process/fork.c +++ b/src/process/fork.c @@ -1,19 +1,86 @@ #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, __dlerror_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, + &__dlerror_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, __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.main_thread && !ret) { - pthread_t self = __pthread_self(); - self->tid = self->pid = syscall(SYS_getpid); - libc.threads_minus_1 = 0; - libc.main_thread = self; + sigset_t set; + __fork_handler(-1); + __block_app_sigs(&set); + int need_locks = libc.need_locks > 0; + if (need_locks) { + __ldso_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