summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorEric Andersen <andersen@codepoet.org>2003-11-05 02:12:56 +0000
committerEric Andersen <andersen@codepoet.org>2003-11-05 02:12:56 +0000
commitdfc535be8fc57eccf4975ed6efedf51b4d27b05e (patch)
tree35882de51fa80a025a1cec0d833cf82aca8767f5
parent72d527f0b6e7ba7fd44359ff1268f0c240048732 (diff)
Arthur Shipkowski, art ! videon-central ! com, writes:
I've noticed a few people have posted over the last year about problems compiling programs that use vfork when pthreads are involved. Some detective work turned up that ptfork.c aliases vfork to fork and then tries to call the original fork as __libc_fork. This patch removes the aliasing when there is no MMU present, and uses the same call semantics to call __libc_vfork. I then added a symbol to the m68k vfork.S to allow vfork to be called as __libc_vfork. The same bug exists in the uClibc CVS, and with a possible tweak this patch should go through there as well. Obviously, all other platforms need __libc_vfork as a workable means to call vfork in order for this to work for them. Let me know if there are any problems with this patch. Art Shipkowski Videon Central Software Engineer (814)235-1111 x307
-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