summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--libc/sysdeps/linux/m68k/vfork.S3
-rw-r--r--libpthread/linuxthreads/ptfork.c26
2 files changed, 28 insertions, 1 deletions
diff --git a/libc/sysdeps/linux/m68k/vfork.S b/libc/sysdeps/linux/m68k/vfork.S
index 5db163bf5..132c10989 100644
--- a/libc/sysdeps/linux/m68k/vfork.S
+++ b/libc/sysdeps/linux/m68k/vfork.S
@@ -11,10 +11,13 @@
.align 2
.globl errno
.globl vfork
+ .globl __libc_vfork
#if defined __HAVE_ELF__
.type vfork,@function
+ .type __libc_vfork,@function
#endif
vfork:
+__libc_vfork:
movl %sp@+, %a1 /* save the return address for later */
movl IMM __NR_vfork,%d0
trap #0
diff --git a/libpthread/linuxthreads/ptfork.c b/libpthread/linuxthreads/ptfork.c
index 0c4e252d6..5ed380555 100644
--- a/libpthread/linuxthreads/ptfork.c
+++ b/libpthread/linuxthreads/ptfork.c
@@ -74,7 +74,7 @@ static inline void pthread_call_handlers(struct handler_list * list)
{
for (/*nothing*/; list != NULL; list = list->next) (list->handler)();
}
-
+#ifdef __UCLIBC_HAS_MMU__
extern int __libc_fork(void);
pid_t __fork(void)
@@ -105,3 +105,27 @@ pid_t __vfork(void)
return __fork();
}
weak_alias (__vfork, vfork);
+#else
+pid_t __vfork(void)
+{
+ pid_t pid;
+ struct handler_list * prepare, * child, * parent;
+
+ pthread_mutex_lock(&pthread_atfork_lock);
+ prepare = pthread_atfork_prepare;
+ child = pthread_atfork_child;
+ parent = pthread_atfork_parent;
+ pthread_mutex_unlock(&pthread_atfork_lock);
+ pthread_call_handlers(prepare);
+ pid = __libc_vfork();
+ if (pid == 0) {
+ __pthread_reset_main_thread();
+ __fresetlockfiles();
+ pthread_call_handlers(child);
+ } else {
+ pthread_call_handlers(parent);
+ }
+ return pid;
+}
+weak_alias (__vfork, vfork);
+#endif