diff --git a/src/acconfig.h b/src/acconfig.h
index 4a98e1329817e2755a7735de3ae1c558fb399f9f..177cd6aca12dedd522cf098bcfb4530cdfcdb791 100644
--- a/src/acconfig.h
+++ b/src/acconfig.h
@@ -1,5 +1,5 @@
 /*
- * $Id: acconfig.h,v 1.47 1999/08/11 22:13:18 hubbe Exp $
+ * $Id: acconfig.h,v 1.48 1999/08/30 06:23:46 hubbe Exp $
  */
 #ifndef MACHINE_H
 #define MACHINE_H
@@ -238,6 +238,9 @@
 /* Define if you have the pthread_attr_setstacksize function.  */
 #undef HAVE_PTHREAD_ATTR_SETSTACKSIZE
 
+/* Define if you have the pthread_atfork function.  */
+#undef HAVE_PTHREAD_ATFORK
+
 /* Define if you have the pthread_cond_init function.  */
 #undef HAVE_PTHREAD_COND_INIT
 
diff --git a/src/configure.in b/src/configure.in
index 1131a3f8015904e7f1e8a8dc4a4abaad590171f3..6b3a7bda77d4ab080d442f611f5a8599c9c01b5e 100644
--- a/src/configure.in
+++ b/src/configure.in
@@ -1,4 +1,4 @@
-AC_REVISION("$Id: configure.in,v 1.316 1999/08/28 04:05:45 hubbe Exp $")
+AC_REVISION("$Id: configure.in,v 1.317 1999/08/30 06:23:47 hubbe Exp $")
 AC_INIT(interpret.c)
 AC_CONFIG_HEADER(machine.h)
 
@@ -1289,6 +1289,8 @@ int main()
     AC_DEFINE(_MIT_POSIX_THREADS,1)
     AC_DEFINE(PIKE_THREADS)
 
+##########################################################################
+
     AC_MSG_CHECKING(for pthread_attr_setstacksize)
     AC_CACHE_VAL(pike_cv_have_pthread_attr_setstacksize,[
       AC_TRY_LINK([#include <pthread.h>
@@ -1306,6 +1308,27 @@ int main()
       :
     fi
 
+##########################################################################
+
+    AC_MSG_CHECKING(for pthread_atfork)
+    AC_CACHE_VAL(pike_cv_have_pthread_atfork,[
+      AC_TRY_LINK([#include <pthread.h>
+        void foo(void) { pthread_atfork(0,0,0); }
+      ],[],[
+        pike_cv_have_pthread_atfork=yes
+      ],[
+        pike_cv_have_pthread_atfork=no
+      ])
+    ])
+    if test x$pike_cv_have_pthread_attr_setstacksize = xyes ; then
+      AC_MSG_RESULT(yes)
+      AC_DEFINE(HAVE_PTHREAD_ATFORK)
+    else
+      AC_MSG_RESULT([no - FreeBSD?])
+    fi
+
+##########################################################################
+
     AC_MSG_CHECKING(for pthread_yield)
     AC_CACHE_VAL(pike_cv_have_pthread_yield,[
       AC_TRY_LINK([#include <pthread.h>
@@ -1323,6 +1346,8 @@ int main()
       :
     fi
 
+##########################################################################
+
     AC_MSG_CHECKING(for pthread_cond_init)
     AC_CACHE_VAL(pike_cv_have_pthread_cond_init,[
       AC_TRY_LINK([#include <pthread.h>
@@ -1340,6 +1365,8 @@ int main()
       :
     fi
 
+##########################################################################
+
     AC_MSG_CHECKING(if pthread_condattr_default is defined)
     AC_CACHE_VAL(pike_cv_have_pthread_condattr_default,[
       AC_TRY_LINK([#include <pthread.h>
@@ -1383,6 +1410,7 @@ int main()
       :
     fi
 
+##########################################################################
 
     AC_MSG_CHECKING(for __pthread_initial_thread_bos)
     AC_CACHE_VAL(pike_cv_have_pthread_initial_thread_bos,[
diff --git a/src/signal_handler.c b/src/signal_handler.c
index aaa0aeec46cfd7847f9835707e91ea0004713c65..8e6caa0cf721384705692129a607655a28277108 100644
--- a/src/signal_handler.c
+++ b/src/signal_handler.c
@@ -25,7 +25,7 @@
 #include "main.h"
 #include <signal.h>
 
-RCSID("$Id: signal_handler.c,v 1.149 1999/08/28 00:39:01 hubbe Exp $");
+RCSID("$Id: signal_handler.c,v 1.150 1999/08/30 06:23:48 hubbe Exp $");
 
 #ifdef HAVE_PASSWD_H
 # include <passwd.h>
@@ -1014,7 +1014,7 @@ static void do_bi_do_da_lock(void)
 
 static TH_RETURN_TYPE wait_thread(void *data)
 {
-  if(pthread_atfork(do_da_lock,do_bi_do_da_lock,0))
+  if(th_atfork(do_da_lock,do_bi_do_da_lock,0))
   {
     perror("pthread atfork");
     exit(1);
@@ -2342,6 +2342,7 @@ void f_create_process(INT32 args)
     storage.disabled = 1;
 #endif
 
+    th_atfork_prepare();
     do
     {
 #ifdef PROC_DEBUG
@@ -2354,6 +2355,14 @@ void f_create_process(INT32 args)
 #endif
     }while(pid==-1 && errno==EINTR);
 
+    if(pid!=-1)
+    {
+      if(pid)
+	th_atfork_parent();
+      else
+	th_atfork_child();
+    }
+
     UNSET_ONERROR(err);
 
     if(pid == -1) {
@@ -2704,6 +2713,7 @@ void f_fork(INT32 args)
     error("fork: permission denied.\n");
 #endif
 
+  th_atfork_prepare();
 /*   THREADS_ALLOW_UID(); */
 #if 0 && defined(HAVE_FORK1) && defined(_REENTRANT)
   /* This section is disabled, since fork1() isn't usefull if
@@ -2717,6 +2727,13 @@ void f_fork(INT32 args)
   pid=fork();
 #endif
 /*  THREADS_DISALLOW_UID(); */
+  if(pid!=-1)
+  {
+    if(pid)
+      th_atfork_parent();
+    else
+      th_atfork_child();
+  }
 
   if(pid==-1) {
     error("Fork failed\n"
diff --git a/src/threads.c b/src/threads.c
index 9525a01a269452beaf7cf08e5783ec870066f023..48826bca94b31c0290fdbe027862b55c1a3e6c46 100644
--- a/src/threads.c
+++ b/src/threads.c
@@ -1,5 +1,5 @@
 #include "global.h"
-RCSID("$Id: threads.c,v 1.102 1999/08/17 17:20:18 grubba Exp $");
+RCSID("$Id: threads.c,v 1.103 1999/08/30 06:23:50 hubbe Exp $");
 
 int num_threads = 1;
 int threads_disabled = 0;
@@ -25,6 +25,37 @@ COND_T live_threads_change;
 COND_T threads_disabled_change;
 size_t thread_stack_size=1024 * 1204;
 
+#ifndef HAVE_PTHREAD_ATFORK
+#include "callback.h"
+
+static struct callback_list atfork_prepare_callback;
+static struct callback_list atfork_parent_callback;
+static struct callback_list atfork_child_callback;
+
+int th_atfork(void (*prepare)(void),void (*parent)(void),void (*child)(void))
+{
+  if(prepare)
+    add_to_callback(&atfork_prepare_callback, (callback_func) prepare, 0, 0);
+  if(parent)
+    add_to_callback(&atfork_parent_callback, (callback_func) parent, 0, 0);
+  if(child)
+    add_to_callback(&atfork_child_callback, (callback_func) child, 0, 0);
+  return 0;
+}
+void th_atfork_prepare(void)
+{
+  call_callback(& atfork_prepare_callback, 0);
+}
+void th_atfork_parent(void)
+{
+  call_callback(& atfork_parent_callback, 0);
+}
+void th_atfork_child(void)
+{
+  call_callback(& atfork_child_callback, 0);
+}
+#endif
+
 #ifdef __NT__
 
 int low_nt_create_thread(unsigned stack_size,
diff --git a/src/threads.h b/src/threads.h
index 20551ca68f6abfac839852f1cca479e9da99ce1d..96f113d73117c7de3933a18dfc1e02a4638d8083 100644
--- a/src/threads.h
+++ b/src/threads.h
@@ -1,5 +1,5 @@
 /*
- * $Id: threads.h,v 1.68 1999/08/10 00:19:00 mast Exp $
+ * $Id: threads.h,v 1.69 1999/08/30 06:23:51 hubbe Exp $
  */
 #ifndef THREADS_H
 #define THREADS_H
@@ -57,6 +57,19 @@ extern struct object *thread_id;
 
 
 #ifdef POSIX_THREADS
+
+#ifdef HAVE_PTHREAD_ATFORK
+#define th_atfork(X,Y,Z) pthread_atfork((X),(Y),(Z))
+#define th_atfork_prepare()
+#define th_atfork_parent()
+#define th_atfork_child()
+#else
+int th_atfork(void (*)(void),void (*)(void),void (*)(void));
+void th_atfork_prepare(void);
+void th_atfork_parent(void);
+void th_atfork_child(void);
+#endif
+
 #define THREAD_T pthread_t
 #define MUTEX_T pthread_mutex_t
 #define mt_init(X) pthread_mutex_init((X),0)