summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--lib/csu/crtbegin.c15
-rw-r--r--lib/csu/crtbeginS.c16
-rw-r--r--lib/libc/arch/alpha/SYS.h3
-rw-r--r--lib/libc/arch/alpha/sys/fork.S5
-rw-r--r--lib/libc/arch/amd64/SYS.h28
-rw-r--r--lib/libc/arch/amd64/sys/fork.S5
-rw-r--r--lib/libc/arch/arm/SYS.h15
-rw-r--r--lib/libc/arch/arm/sys/fork.S5
-rw-r--r--lib/libc/arch/hppa/SYS.h13
-rw-r--r--lib/libc/arch/hppa/sys/fork.S5
-rw-r--r--lib/libc/arch/hppa64/SYS.h13
-rw-r--r--lib/libc/arch/hppa64/sys/fork.S5
-rw-r--r--lib/libc/arch/i386/SYS.h28
-rw-r--r--lib/libc/arch/i386/sys/fork.S5
-rw-r--r--lib/libc/arch/m88k/SYS.h13
-rw-r--r--lib/libc/arch/m88k/sys/fork.S5
-rw-r--r--lib/libc/arch/mips64/SYS.h17
-rw-r--r--lib/libc/arch/mips64/sys/fork.S5
-rw-r--r--lib/libc/arch/powerpc/SYS.h8
-rw-r--r--lib/libc/arch/powerpc/sys/fork.S5
-rw-r--r--lib/libc/arch/sh/SYS.h23
-rw-r--r--lib/libc/arch/sh/sys/fork.S5
-rw-r--r--lib/libc/arch/sparc/SYS.h8
-rw-r--r--lib/libc/arch/sparc/sys/fork.S5
-rw-r--r--lib/libc/arch/sparc64/SYS.h18
-rw-r--r--lib/libc/arch/sparc64/sys/fork.S5
-rw-r--r--lib/libc/arch/vax/SYS.h3
-rw-r--r--lib/libc/arch/vax/sys/fork.S5
-rw-r--r--lib/libc/include/atfork.h44
-rw-r--r--lib/libc/include/thread_private.h19
-rw-r--r--lib/libc/shlib_version4
-rw-r--r--lib/libc/stdlib/atexit.c20
-rw-r--r--lib/libc/sys/Makefile.inc4
-rw-r--r--lib/libc/sys/w_fork.c74
-rw-r--r--lib/libc/thread/Makefile.inc4
-rw-r--r--lib/libc/thread/atfork.c56
-rw-r--r--lib/libc/thread/unithread_malloc_lock.c20
-rw-r--r--lib/librthread/rthread.c4
-rw-r--r--lib/librthread/rthread_fork.c56
-rw-r--r--lib/librthread/rthread_libc.c19
-rw-r--r--lib/librthread/shlib_version4
-rw-r--r--regress/lib/csu/callbacks/Makefile5
-rw-r--r--regress/lib/csu/callbacks/pthread_atfork/Makefile4
-rw-r--r--regress/lib/csu/callbacks/pthread_atfork/expected_child.out20
-rw-r--r--regress/lib/csu/callbacks/pthread_atfork/expected_parent.out37
-rw-r--r--regress/lib/csu/callbacks/pthread_atfork/pthread_atfork_test.c6
46 files changed, 557 insertions, 129 deletions
diff --git a/lib/csu/crtbegin.c b/lib/csu/crtbegin.c
index e1ffc16bb1b..2917bd38260 100644
--- a/lib/csu/crtbegin.c
+++ b/lib/csu/crtbegin.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: crtbegin.c,v 1.18 2015/04/04 18:05:05 guenther Exp $ */
+/* $OpenBSD: crtbegin.c,v 1.19 2015/04/07 01:27:06 guenther Exp $ */
/* $NetBSD: crtbegin.c,v 1.1 1996/09/12 16:59:03 cgd Exp $ */
/*
@@ -91,6 +91,19 @@ atexit(void (*fn)(void))
return (__cxa_atexit((void (*)(void *))fn, NULL, NULL));
}
+/*
+ * Ditto for pthread_atfork()
+ */
+int _thread_atfork(void (*)(void), void (*)(void), void (*)(void), void *)
+ __attribute__((weak));
+
+int
+pthread_atfork(void (*prep)(void), void (*parent)(void), void (*child)(void))
+{
+ return (_thread_atfork(prep, parent, child, NULL));
+}
+asm(".weak pthread_atfork");
+
static const init_f __CTOR_LIST__[1]
__attribute__((section(".ctors"))) = { (void *)-1 }; /* XXX */
diff --git a/lib/csu/crtbeginS.c b/lib/csu/crtbeginS.c
index 152bfa5ec79..f97d30f22b0 100644
--- a/lib/csu/crtbeginS.c
+++ b/lib/csu/crtbeginS.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: crtbeginS.c,v 1.15 2015/04/04 18:05:05 guenther Exp $ */
+/* $OpenBSD: crtbeginS.c,v 1.16 2015/04/07 01:27:06 guenther Exp $ */
/* $NetBSD: crtbegin.c,v 1.1 1996/09/12 16:59:03 cgd Exp $ */
/*
@@ -80,6 +80,20 @@ atexit(void (*fn)(void))
}
asm(".hidden atexit");
+/*
+ * Ditto for pthread_atfork()
+ */
+int _thread_atfork(void (*)(void), void (*)(void), void (*)(void), void *)
+ __attribute__((weak));
+
+int
+pthread_atfork(void (*prep)(void), void (*parent)(void), void (*child)(void))
+{
+ return (_thread_atfork(prep, parent, child, &__dso_handle));
+}
+/* hppa doesn't permit directives in first column, so space after newline */
+asm(".hidden pthread_atfork\n .weak pthread_atfork");
+
static init_f __CTOR_LIST__[1]
__attribute__((section(".ctors"))) = { (void *)-1 }; /* XXX */
diff --git a/lib/libc/arch/alpha/SYS.h b/lib/libc/arch/alpha/SYS.h
index bc2ea4ca888..f1d15c6a501 100644
--- a/lib/libc/arch/alpha/SYS.h
+++ b/lib/libc/arch/alpha/SYS.h
@@ -1,4 +1,4 @@
-/* $OpenBSD: SYS.h,v 1.9 2002/10/06 23:23:18 art Exp $ */
+/* $OpenBSD: SYS.h,v 1.10 2015/04/07 01:27:06 guenther Exp $ */
/* $NetBSD: SYS.h,v 1.4 1996/10/17 03:03:53 cgd Exp $ */
/*
@@ -90,6 +90,7 @@ __END(p,label);
__SYSCALL_NOERROR(_thread_sys_,x)
# define RSYSCALL(x) ALIAS(_thread_sys_,x) \
__RSYSCALL(_thread_sys_,x)
+# define RSYSCALL_HIDDEN(x) __RSYSCALL(_thread_sys_,x)
# define RSYSCALL_NOERROR(x) ALIAS(_thread_sys_,x) \
__RSYSCALL_NOERROR(_thread_sys_,x)
# define PSEUDO(x,y) ALIAS(_thread_sys_,x) \
diff --git a/lib/libc/arch/alpha/sys/fork.S b/lib/libc/arch/alpha/sys/fork.S
index d2509858586..59b96139585 100644
--- a/lib/libc/arch/alpha/sys/fork.S
+++ b/lib/libc/arch/alpha/sys/fork.S
@@ -1,4 +1,4 @@
-/* $OpenBSD: fork.S,v 1.6 2015/03/31 04:32:01 guenther Exp $ */
+/* $OpenBSD: fork.S,v 1.7 2015/04/07 01:27:06 guenther Exp $ */
/* $NetBSD: fork.S,v 1.1 1995/02/10 17:50:34 cgd Exp $ */
/*
@@ -30,4 +30,5 @@
#include "SYS.h"
-RSYSCALL(fork)
+RSYSCALL_HIDDEN(fork)
+WEAK_ALIAS(_thread_fork,_thread_sys_fork)
diff --git a/lib/libc/arch/amd64/SYS.h b/lib/libc/arch/amd64/SYS.h
index f5710a879c4..82eedd460fc 100644
--- a/lib/libc/arch/amd64/SYS.h
+++ b/lib/libc/arch/amd64/SYS.h
@@ -1,4 +1,4 @@
-/* $OpenBSD: SYS.h,v 1.9 2014/06/04 20:13:49 matthew Exp $ */
+/* $OpenBSD: SYS.h,v 1.10 2015/04/07 01:27:06 guenther Exp $ */
/*-
* Copyright (c) 1990 The Regents of the University of California.
@@ -40,10 +40,13 @@
#define SYSTRAP(x) movl $(SYS_ ## x),%eax; movq %rcx, %r10; syscall
+
#define SYSENTRY(x) \
ENTRY(_thread_sys_ ## x); \
.weak _C_LABEL(x); \
_C_LABEL(x) = _C_LABEL(_thread_sys_ ## x)
+#define SYSENTRY_HIDDEN(x) \
+ ENTRY(_thread_sys_ ## x) \
#define CERROR _C_LABEL(__cerror)
#define _CERROR _C_LABEL(___cerror)
@@ -52,6 +55,9 @@
#define _SYSCALL_NOERROR(x,y) \
SYSENTRY(x); \
SYSTRAP(y)
+#define _SYSCALL_HIDDEN_NOERROR(x,y) \
+ SYSENTRY_HIDDEN(x); \
+ SYSTRAP(y)
#ifdef __PIC__
#define _SYSCALL(x,y) \
@@ -60,12 +66,23 @@
jmp *%rcx; \
_SYSCALL_NOERROR(x,y); \
jc 2b
+#define _SYSCALL_HIDDEN(x,y) \
+ .text; _ALIGN_TEXT; \
+ 2: mov PIC_GOT(CERROR), %rcx; \
+ jmp *%rcx; \
+ _SYSCALL_HIDDEN_NOERROR(x,y); \
+ jc 2b
#else
#define _SYSCALL(x,y) \
.text; _ALIGN_TEXT; \
2: jmp CERROR; \
_SYSCALL_NOERROR(x,y); \
jc 2b
+#define _SYSCALL_HIDDEN(x,y) \
+ .text; _ALIGN_TEXT; \
+ 2: jmp CERROR; \
+ _SYSCALL_HIDDEN_NOERROR(x,y); \
+ jc 2b
#endif
#define SYSCALL_NOERROR(x) \
@@ -81,15 +98,16 @@
#define PSEUDO(x,y) \
_SYSCALL(x,y); \
ret
+#define PSEUDO_HIDDEN(x,y) \
+ _SYSCALL_HIDDEN(x,y); \
+ ret
#define RSYSCALL_NOERROR(x) \
PSEUDO_NOERROR(x,x)
#define RSYSCALL(x) \
PSEUDO(x,x)
-
-#define WSYSCALL(weak,strong) \
- WEAK_ALIAS(weak,strong); \
- PSEUDO(strong,weak)
+#define RSYSCALL_HIDDEN(x) \
+ PSEUDO_HIDDEN(x,x)
.globl CERROR
diff --git a/lib/libc/arch/amd64/sys/fork.S b/lib/libc/arch/amd64/sys/fork.S
index d0a2ea33178..6582d8a9a32 100644
--- a/lib/libc/arch/amd64/sys/fork.S
+++ b/lib/libc/arch/amd64/sys/fork.S
@@ -1,4 +1,4 @@
-/* $OpenBSD: fork.S,v 1.3 2015/03/31 04:32:01 guenther Exp $ */
+/* $OpenBSD: fork.S,v 1.4 2015/04/07 01:27:06 guenther Exp $ */
/* $NetBSD: fork.S,v 1.2 2003/02/13 02:50:51 nathanw Exp $ */
/*-
@@ -39,4 +39,5 @@
#include "SYS.h"
-RSYSCALL(fork)
+RSYSCALL_HIDDEN(fork)
+WEAK_ALIAS(_thread_fork,_thread_sys_fork)
diff --git a/lib/libc/arch/arm/SYS.h b/lib/libc/arch/arm/SYS.h
index c6cfdbc4fcd..2fb7c3a91ba 100644
--- a/lib/libc/arch/arm/SYS.h
+++ b/lib/libc/arch/arm/SYS.h
@@ -1,4 +1,4 @@
-/* $OpenBSD: SYS.h,v 1.8 2015/03/31 12:31:19 jsing Exp $ */
+/* $OpenBSD: SYS.h,v 1.9 2015/04/07 01:27:06 guenther Exp $ */
/* $NetBSD: SYS.h,v 1.8 2003/08/07 16:42:02 agc Exp $ */
/*-
@@ -42,6 +42,8 @@
.weak _C_LABEL(x); \
_C_LABEL(x) = _C_LABEL(_thread_sys_ ## x); \
ENTRY(_thread_sys_ ## x)
+#define SYSENTRY_HIDDEN(x) \
+ ENTRY(_thread_sys_ ## x)
#define SYSTRAP(x) \
ldr r12, =SYS_ ## x; \
@@ -54,10 +56,16 @@
#define _SYSCALL_NOERROR(x,y) \
SYSENTRY(x); \
SYSTRAP(y)
+#define _SYSCALL_HIDDEN_NOERROR(x,y) \
+ SYSENTRY_HIDDEN(x); \
+ SYSTRAP(y)
#define _SYSCALL(x, y) \
_SYSCALL_NOERROR(x,y); \
bcs PIC_SYM(CERROR, PLT)
+#define _SYSCALL_HIDDEN(x, y) \
+ _SYSCALL_HIDDEN_NOERROR(x,y); \
+ bcs PIC_SYM(CERROR, PLT)
#define SYSCALL_NOERROR(x) \
_SYSCALL_NOERROR(x,x)
@@ -73,6 +81,9 @@
#define PSEUDO(x,y) \
_SYSCALL(x,y); \
mov r15, r14
+#define PSEUDO_HIDDEN(x,y) \
+ _SYSCALL_HIDDEN(x,y); \
+ mov r15, r14
#define RSYSCALL_NOERROR(x) \
@@ -80,5 +91,7 @@
#define RSYSCALL(x) \
PSEUDO(x,x)
+#define RSYSCALL_HIDDEN(x) \
+ PSEUDO_HIDDEN(x,x)
.globl CERROR
diff --git a/lib/libc/arch/arm/sys/fork.S b/lib/libc/arch/arm/sys/fork.S
index 9836d80a975..8d92b286369 100644
--- a/lib/libc/arch/arm/sys/fork.S
+++ b/lib/libc/arch/arm/sys/fork.S
@@ -1,4 +1,4 @@
-/* $OpenBSD: fork.S,v 1.3 2015/03/31 04:32:01 guenther Exp $ */
+/* $OpenBSD: fork.S,v 1.4 2015/04/07 01:27:06 guenther Exp $ */
/* $NetBSD: fork.S,v 1.5 2003/08/07 16:42:04 agc Exp $ */
/*-
@@ -34,4 +34,5 @@
#include "SYS.h"
-RSYSCALL(fork)
+RSYSCALL_HIDDEN(fork)
+WEAK_ALIAS(_thread_fork,_thread_sys_fork)
diff --git a/lib/libc/arch/hppa/SYS.h b/lib/libc/arch/hppa/SYS.h
index 2c1f6a8e9e1..a2dbef50244 100644
--- a/lib/libc/arch/hppa/SYS.h
+++ b/lib/libc/arch/hppa/SYS.h
@@ -1,4 +1,4 @@
-/* $OpenBSD: SYS.h,v 1.16 2010/10/01 05:02:19 guenther Exp $ */
+/* $OpenBSD: SYS.h,v 1.17 2015/04/07 01:27:06 guenther Exp $ */
/*
* Copyright (c) 1998-2002 Michael Shalayeff
@@ -36,6 +36,8 @@
#define SYSENTRY(x) !\
LEAF_ENTRY(__CONCAT(_thread_sys_,x)) !\
WEAK_ALIAS(x,__CONCAT(_thread_sys_,x))
+#define SYSENTRY_HIDDEN(x) !\
+LEAF_ENTRY(__CONCAT(_thread_sys_,x))
#define SYSEXIT(x) !\
EXIT(__CONCAT(_thread_sys_,x))
@@ -54,6 +56,12 @@ SYSENTRY(x) !\
bv r0(rp) !\
nop !\
SYSEXIT(x)
+#define PSEUDO_HIDDEN(x,y) !\
+SYSENTRY_HIDDEN(x) !\
+ SYSCALL(y) !\
+ bv r0(rp) !\
+ nop !\
+SYSEXIT(x)
#define PSEUDO_NOERROR(x,y) !\
SYSENTRY(x) !\
@@ -66,5 +74,6 @@ SYSENTRY(x) !\
nop !\
SYSEXIT(x)
-#define RSYSCALL(x) PSEUDO(x,x)
+#define RSYSCALL(x) PSEUDO(x,x)
+#define RSYSCALL_HIDDEN(x) PSEUDO_HIDDEN(x,x)
diff --git a/lib/libc/arch/hppa/sys/fork.S b/lib/libc/arch/hppa/sys/fork.S
index 6a4efd8f3de..8bb3bc545b9 100644
--- a/lib/libc/arch/hppa/sys/fork.S
+++ b/lib/libc/arch/hppa/sys/fork.S
@@ -1,4 +1,4 @@
-/* $OpenBSD: fork.S,v 1.12 2015/03/31 04:32:01 guenther Exp $ */
+/* $OpenBSD: fork.S,v 1.13 2015/04/07 01:27:06 guenther Exp $ */
/*
* Copyright (c) 1999 Michael Shalayeff
@@ -28,4 +28,5 @@
#include "SYS.h"
-RSYSCALL(fork)
+RSYSCALL_HIDDEN(fork)
+WEAK_ALIAS(_thread_fork,_thread_sys_fork)
diff --git a/lib/libc/arch/hppa64/SYS.h b/lib/libc/arch/hppa64/SYS.h
index d60f389285d..510ab2c5fba 100644
--- a/lib/libc/arch/hppa64/SYS.h
+++ b/lib/libc/arch/hppa64/SYS.h
@@ -1,4 +1,4 @@
-/* $OpenBSD: SYS.h,v 1.6 2011/09/19 13:01:28 kettenis Exp $ */
+/* $OpenBSD: SYS.h,v 1.7 2015/04/07 01:27:06 guenther Exp $ */
/*
* Copyright (c) 1998-2002 Michael Shalayeff
@@ -36,6 +36,8 @@
#define SYSENTRY(x) !\
LEAF_ENTRY(__CONCAT(_thread_sys_,x)) !\
WEAK_ALIAS(x,__CONCAT(_thread_sys_,x))
+#define SYSENTRY_HIDDEN(x) !\
+LEAF_ENTRY(__CONCAT(_thread_sys_,x))
#define SYSEXIT(x) !\
EXIT(__CONCAT(_thread_sys_,x))
@@ -56,6 +58,12 @@ SYSENTRY(x) !\
bv %r0(%rp) !\
nop !\
SYSEXIT(x)
+#define PSEUDO_HIDDEN(x,y) !\
+SYSENTRY_HIDDEN(x) !\
+ SYSCALL(y) !\
+ bv %r0(%rp) !\
+ nop !\
+SYSEXIT(x)
#define PSEUDO_NOERROR(x,y) !\
SYSENTRY(x) !\
@@ -69,5 +77,6 @@ SYSENTRY(x) !\
nop !\
SYSEXIT(x)
-#define RSYSCALL(x) PSEUDO(x,x)
+#define RSYSCALL(x) PSEUDO(x,x)
+#define RSYSCALL_HIDDEN(x) PSEUDO_HIDDEN(x,x)
diff --git a/lib/libc/arch/hppa64/sys/fork.S b/lib/libc/arch/hppa64/sys/fork.S
index ce870ec4024..7602c801601 100644
--- a/lib/libc/arch/hppa64/sys/fork.S
+++ b/lib/libc/arch/hppa64/sys/fork.S
@@ -1,4 +1,4 @@
-/* $OpenBSD: fork.S,v 1.5 2015/03/31 04:32:01 guenther Exp $ */
+/* $OpenBSD: fork.S,v 1.6 2015/04/07 01:27:06 guenther Exp $ */
/*
* Copyright (c) 1999 Michael Shalayeff
@@ -28,4 +28,5 @@
#include "SYS.h"
-RSYSCALL(fork)
+RSYSCALL_HIDDEN(fork)
+WEAK_ALIAS(_thread_fork,_thread_sys_fork)
diff --git a/lib/libc/arch/i386/SYS.h b/lib/libc/arch/i386/SYS.h
index cc199d6bf3d..a6c1c852c03 100644
--- a/lib/libc/arch/i386/SYS.h
+++ b/lib/libc/arch/i386/SYS.h
@@ -29,7 +29,7 @@
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
- * $OpenBSD: SYS.h,v 1.19 2014/06/04 20:13:49 matthew Exp $
+ * $OpenBSD: SYS.h,v 1.20 2015/04/07 01:27:06 guenther Exp $
*/
#include <machine/asm.h>
@@ -49,6 +49,8 @@
ENTRY(_thread_sys_ ## x); \
.weak _C_LABEL(x); \
_C_LABEL(x) = _C_LABEL(_thread_sys_ ## x)
+#define SYSENTRY_HIDDEN(x) \
+ ENTRY(_thread_sys_ ## x)
#define __DO_SYSCALL(x) \
movl $(SYS_ ## x),%eax; \
@@ -62,6 +64,9 @@
#define _SYSCALL_NOERROR(x,y) \
SYSENTRY(x); \
__DO_SYSCALL(y);
+#define _SYSCALL_HIDDEN_NOERROR(x,y) \
+ SYSENTRY_HIDDEN(x); \
+ __DO_SYSCALL(y);
#define SYSCALL_NOERROR(x) \
_SYSCALL_NOERROR(x,x)
@@ -77,6 +82,15 @@
jmp *%ecx; \
_SYSCALL_NOERROR(x,y) \
jc 2b
+#define _SYSCALL_HIDDEN(x,y) \
+ .text; \
+ .align 2; \
+ 2: PIC_PROLOGUE; \
+ movl PIC_GOT(CERROR), %ecx; \
+ PIC_EPILOGUE; \
+ jmp *%ecx; \
+ _SYSCALL_HIDDEN_NOERROR(x,y) \
+ jc 2b
#else
#define _SYSCALL(x,y) \
.text; \
@@ -85,6 +99,13 @@
jmp PIC_PLT(CERROR); \
_SYSCALL_NOERROR(x,y) \
jc 2b
+#define _SYSCALL_HIDDEN(x,y) \
+ .text; \
+ .align 2; \
+ 2: \
+ jmp PIC_PLT(CERROR); \
+ _SYSCALL_HIDDEN_NOERROR(x,y) \
+ jc 2b
#endif
#define SYSCALL(x) \
@@ -99,9 +120,14 @@
#define PSEUDO(x,y) \
_SYSCALL(x,y); \
ret
+#define PSEUDO_HIDDEN(x,y) \
+ _SYSCALL_HIDDEN(x,y); \
+ ret
/* perform a syscall with the same name, set errno, return */
#define RSYSCALL(x) \
PSEUDO(x,x);
+#define RSYSCALL_HIDDEN(x) \
+ PSEUDO_HIDDEN(x,x)
.globl CERROR
diff --git a/lib/libc/arch/i386/sys/fork.S b/lib/libc/arch/i386/sys/fork.S
index 205ae5942c1..1e750d3f0d6 100644
--- a/lib/libc/arch/i386/sys/fork.S
+++ b/lib/libc/arch/i386/sys/fork.S
@@ -1,4 +1,4 @@
-/* $OpenBSD: fork.S,v 1.5 2015/03/31 04:32:01 guenther Exp $ */
+/* $OpenBSD: fork.S,v 1.6 2015/04/07 01:27:06 guenther Exp $ */
/*-
* Copyright (c) 1990 The Regents of the University of California.
* All rights reserved.
@@ -33,4 +33,5 @@
#include "SYS.h"
-RSYSCALL(fork)
+RSYSCALL_HIDDEN(fork)
+WEAK_ALIAS(_thread_fork,_thread_sys_fork)
diff --git a/lib/libc/arch/m88k/SYS.h b/lib/libc/arch/m88k/SYS.h
index 9d6de9d755e..70292c9d585 100644
--- a/lib/libc/arch/m88k/SYS.h
+++ b/lib/libc/arch/m88k/SYS.h
@@ -1,4 +1,4 @@
-/* $OpenBSD: SYS.h,v 1.18 2014/06/04 20:13:49 matthew Exp $*/
+/* $OpenBSD: SYS.h,v 1.19 2015/04/07 01:27:06 guenther Exp $*/
/*-
* Copyright (c) 1990 The Regents of the University of California.
* All rights reserved.
@@ -83,10 +83,16 @@
__ENTRY(p,x); \
__ALIAS(p,x); \
__DO_SYSCALL(y)
+#define __SYSCALL_HIDDEN__NOERROR(p,x,y) \
+ __ENTRY(p,x); \
+ __DO_SYSCALL(y)
#define __SYSCALL(p,x,y) \
__SYSCALL__NOERROR(p,x,y); \
br CERROR
+#define __SYSCALL_HIDDEN(p,x,y) \
+ __SYSCALL_HIDDEN__NOERROR(p,x,y); \
+ br CERROR
#define __PSEUDO_NOERROR(p,x,y) \
__SYSCALL__NOERROR(p,x,y); \
@@ -97,6 +103,10 @@
__SYSCALL(p,x,y); \
jmp %r1; \
__END(p,x)
+#define __PSEUDO_HIDDEN(p,x,y) \
+ __SYSCALL_HIDDEN(p,x,y); \
+ jmp %r1; \
+ __END(p,x)
/*
* System calls entry points are really named _thread_sys_{syscall},
@@ -105,6 +115,7 @@
*/
#define SYSCALL(x) __SYSCALL(_thread_sys_,x,x)
#define RSYSCALL(x) __PSEUDO(_thread_sys_,x,x)
+#define RSYSCALL_HIDDEN(x) __PSEUDO_HIDDEN(_thread_sys_,x,x)
#define PSEUDO(x,y) __PSEUDO(_thread_sys_,x,y)
#define PSEUDO_NOERROR(x,y) __PSEUDO_NOERROR(_thread_sys_,x,y)
#define SYSENTRY(x) __ENTRY(_thread_sys_,x); \
diff --git a/lib/libc/arch/m88k/sys/fork.S b/lib/libc/arch/m88k/sys/fork.S
index 3c88e9f65d0..2c664f74fd2 100644
--- a/lib/libc/arch/m88k/sys/fork.S
+++ b/lib/libc/arch/m88k/sys/fork.S
@@ -1,4 +1,4 @@
-/* $OpenBSD: fork.S,v 1.8 2013/09/08 18:01:56 miod Exp $ */
+/* $OpenBSD: fork.S,v 1.9 2015/04/07 01:27:06 guenther Exp $ */
/*-
* Copyright (c) 1990 The Regents of the University of California.
@@ -35,4 +35,5 @@
#include "SYS.h"
-RSYSCALL(fork)
+RSYSCALL_HIDDEN(fork)
+WEAK_ALIAS(_thread_fork,_thread_sys_fork)
diff --git a/lib/libc/arch/mips64/SYS.h b/lib/libc/arch/mips64/SYS.h
index 885ca700cec..55926724eb9 100644
--- a/lib/libc/arch/mips64/SYS.h
+++ b/lib/libc/arch/mips64/SYS.h
@@ -29,7 +29,7 @@
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
- * $OpenBSD: SYS.h,v 1.6 2014/06/04 20:13:49 matthew Exp $
+ * $OpenBSD: SYS.h,v 1.7 2015/04/07 01:27:06 guenther Exp $
*/
#include <sys/syscall.h>
@@ -71,9 +71,24 @@
PTR_ADDU sp,32; \
jr t9; \
__END2(p,x)
+#define __PSEUDO_HIDDEN(p,x,y) \
+ LEAF(p ## x,32); \
+ PTR_SUBU sp,32; \
+ SETUP_GP64(16,__CLABEL2(p,x)); \
+ __DO_SYSCALL(y); \
+ bne a3,zero,err; \
+ RESTORE_GP64; \
+ PTR_ADDU sp,32; \
+ j ra; \
+ err: LA t9,CERROR; \
+ RESTORE_GP64; \
+ PTR_ADDU sp,32; \
+ jr t9; \
+ END(p ## x)
#define RSYSCALL(x) __PSEUDO(_thread_sys_,x,x)
+#define RSYSCALL_HIDDEN(x) __PSEUDO_HIDDEN(_thread_sys_,x,x)
#define PSEUDO(x,y) __PSEUDO(_thread_sys_,x,y)
#define PSEUDO_NOERROR(x,y) __PSEUDO_NOERROR(_thread_sys_,x,y)
diff --git a/lib/libc/arch/mips64/sys/fork.S b/lib/libc/arch/mips64/sys/fork.S
index 39aebd47385..be3b2851414 100644
--- a/lib/libc/arch/mips64/sys/fork.S
+++ b/lib/libc/arch/mips64/sys/fork.S
@@ -1,4 +1,4 @@
-/* $OpenBSD: fork.S,v 1.6 2015/03/31 04:32:02 guenther Exp $ */
+/* $OpenBSD: fork.S,v 1.7 2015/04/07 01:27:06 guenther Exp $ */
/*-
* Copyright (c) 1991, 1993
* The Regents of the University of California. All rights reserved.
@@ -33,4 +33,5 @@
#include "SYS.h"
-RSYSCALL(fork)
+RSYSCALL_HIDDEN(fork)
+WEAK_ALIAS(_thread_fork,_thread_sys_fork)
diff --git a/lib/libc/arch/powerpc/SYS.h b/lib/libc/arch/powerpc/SYS.h
index 218c49f5878..fdd4e8913e3 100644
--- a/lib/libc/arch/powerpc/SYS.h
+++ b/lib/libc/arch/powerpc/SYS.h
@@ -1,4 +1,4 @@
-/* $OpenBSD: SYS.h,v 1.15 2014/06/04 20:13:49 matthew Exp $ */
+/* $OpenBSD: SYS.h,v 1.16 2015/04/07 01:27:06 guenther Exp $ */
/*-
* Copyright (c) 1994
* Andrew Cagney. All rights reserved.
@@ -68,9 +68,11 @@
sc ; \
PSEUDO_NOERROR_SUFFIX
-#define PSEUDO(x,y) ALIAS(_thread_sys_,x) \
- PSEUDO_PREFIX(_thread_sys_,x,y) ; \
+#define PSEUDO_HIDDEN(x,y) PSEUDO_PREFIX(_thread_sys_,x,y) ; \
sc ; \
PSEUDO_SUFFIX
+#define PSEUDO(x,y) ALIAS(_thread_sys_,x) \
+ PSEUDO_HIDDEN(x,y)
#define RSYSCALL(x) PSEUDO(x,x)
+#define RSYSCALL_HIDDEN(x) PSEUDO_HIDDEN(x,x)
diff --git a/lib/libc/arch/powerpc/sys/fork.S b/lib/libc/arch/powerpc/sys/fork.S
index d07de61737b..ace55a4a4d1 100644
--- a/lib/libc/arch/powerpc/sys/fork.S
+++ b/lib/libc/arch/powerpc/sys/fork.S
@@ -1,4 +1,4 @@
-/* $OpenBSD: fork.S,v 1.2 2002/10/07 04:47:12 drahn Exp $ */
+/* $OpenBSD: fork.S,v 1.3 2015/04/07 01:27:06 guenther Exp $ */
/*
* Copyright (c) 1996 Dale Rahn
@@ -29,4 +29,5 @@
#include "SYS.h"
-RSYSCALL(fork)
+RSYSCALL_HIDDEN(fork)
+WEAK_ALIAS(_thread_fork,_thread_sys_fork)
diff --git a/lib/libc/arch/sh/SYS.h b/lib/libc/arch/sh/SYS.h
index 4a9f22ac32c..468e265c947 100644
--- a/lib/libc/arch/sh/SYS.h
+++ b/lib/libc/arch/sh/SYS.h
@@ -1,4 +1,4 @@
-/* $OpenBSD: SYS.h,v 1.5 2014/06/04 20:13:49 matthew Exp $ */
+/* $OpenBSD: SYS.h,v 1.6 2015/04/07 01:27:06 guenther Exp $ */
/*-
* Copyright (c) 1990 The Regents of the University of California.
* All rights reserved.
@@ -40,6 +40,8 @@
#define SYSENTRY(x) \
WEAK_ALIAS(x,_thread_sys_ ## x); \
ENTRY(_thread_sys_ ## x)
+#define SYSENTRY_HIDDEN(x) \
+ ENTRY(_thread_sys_ ## x)
#define SYSTRAP(x) \
mov.l 903f, r0; \
@@ -56,6 +58,9 @@
#define _SYSCALL_NOERROR(x,y) \
SYSENTRY(x); \
SYSTRAP(y)
+#define _SYSCALL_HIDDEN_NOERROR(x,y) \
+ SYSENTRY_HIDDEN(x); \
+ SYSTRAP(y)
#ifdef __PIC__
@@ -88,6 +93,11 @@
911: JUMP_CERROR; \
_SYSCALL_NOERROR(x,y); \
bf 911b
+#define _SYSCALL_HIDDEN(x,y) \
+ .text; \
+ 911: JUMP_CERROR; \
+ _SYSCALL_HIDDEN_NOERROR(x,y); \
+ bf 911b
#define SYSCALL_NOERROR(x) \
_SYSCALL_NOERROR(x,x)
@@ -105,10 +115,13 @@
rts; \
nop
-#define RSYSCALL_NOERROR(x) \
- PSEUDO_NOERROR(x,x)
+#define PSEUDO_HIDDEN(x,y) \
+ _SYSCALL_HIDDEN(x,y); \
+ rts; \
+ nop
-#define RSYSCALL(x) \
- PSEUDO(x,x)
+#define RSYSCALL_NOERROR(x) PSEUDO_NOERROR(x,x)
+#define RSYSCALL(x) PSEUDO(x,x)
+#define RSYSCALL_HIDDEN(x) PSEUDO_HIDDEN(x,x)
.globl CERROR
diff --git a/lib/libc/arch/sh/sys/fork.S b/lib/libc/arch/sh/sys/fork.S
index cf552fd07b2..4ee5a0442df 100644
--- a/lib/libc/arch/sh/sys/fork.S
+++ b/lib/libc/arch/sh/sys/fork.S
@@ -1,4 +1,4 @@
-/* $OpenBSD: fork.S,v 1.3 2015/03/31 04:32:02 guenther Exp $ */
+/* $OpenBSD: fork.S,v 1.4 2015/04/07 01:27:07 guenther Exp $ */
/* $NetBSD: fork.S,v 1.10 2006/01/06 05:11:29 uwe Exp $ */
/*-
@@ -37,4 +37,5 @@
#include "SYS.h"
-RSYSCALL(fork)
+RSYSCALL_HIDDEN(fork)
+WEAK_ALIAS(_thread_fork,_thread_sys_fork)
diff --git a/lib/libc/arch/sparc/SYS.h b/lib/libc/arch/sparc/SYS.h
index f010285062d..729c386bfaa 100644
--- a/lib/libc/arch/sparc/SYS.h
+++ b/lib/libc/arch/sparc/SYS.h
@@ -30,7 +30,7 @@
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
- * $OpenBSD: SYS.h,v 1.16 2014/06/04 20:13:49 matthew Exp $
+ * $OpenBSD: SYS.h,v 1.17 2015/04/07 01:27:07 guenther Exp $
*/
#include <machine/asm.h>
@@ -39,7 +39,8 @@
#define _CAT(x,y) x##y
-#define __ENTRY(p,x) ENTRY(_CAT(p,x)) ; .weak x ; x = _CAT(p,x)
+#define __ENTRY(p,x) ENTRY(_CAT(p,x)) ; .weak x ; x = _CAT(p,x)
+#define __ENTRY_HIDDEN(p,x) ENTRY(_CAT(p,x))
/*
* ERROR branches to cerror.
@@ -71,6 +72,8 @@
*/
#define __SYSCALL(p,x) \
__ENTRY(p,x); mov _CAT(SYS_,x),%g1; t ST_SYSCALL; bcc 1f; nop; ERROR(); 1:
+#define __SYSCALL_HIDDEN(p,x) \
+ __ENTRY_HIDDEN(p,x); mov _CAT(SYS_,x),%g1; t ST_SYSCALL; bcc 1f; nop; ERROR(); 1:
/*
* RSYSCALL is used when the system call should just return. Here
@@ -97,6 +100,7 @@
# define SYSCALL(x) __SYSCALL(_thread_sys_,x)
# define RSYSCALL(x) __RSYSCALL(_thread_sys_,x)
+# define RSYSCALL_HIDDEN(x) __RSYSCALL(_thread_sys_,x)
# define PSEUDO(x,y) __PSEUDO(_thread_sys_,x,y)
# define PSEUDO_NOERROR(x,y) __PSEUDO_NOERROR(_thread_sys_,x,y)
# define SYSENTRY(x) __ENTRY(_thread_sys_,x)
diff --git a/lib/libc/arch/sparc/sys/fork.S b/lib/libc/arch/sparc/sys/fork.S
index 83916669e78..911fce204dd 100644
--- a/lib/libc/arch/sparc/sys/fork.S
+++ b/lib/libc/arch/sparc/sys/fork.S
@@ -1,4 +1,4 @@
-/* $OpenBSD: fork.S,v 1.5 2015/03/31 04:32:02 guenther Exp $ */
+/* $OpenBSD: fork.S,v 1.6 2015/04/07 01:27:07 guenther Exp $ */
/*
* Copyright (c) 1992, 1993
* The Regents of the University of California. All rights reserved.
@@ -34,4 +34,5 @@
#include "SYS.h"
-RSYSCALL(fork)
+RSYSCALL_HIDDEN(fork)
+WEAK_ALIAS(_thread_fork,_thread_sys_fork)
diff --git a/lib/libc/arch/sparc64/SYS.h b/lib/libc/arch/sparc64/SYS.h
index f47a4d47da7..3f934da0323 100644
--- a/lib/libc/arch/sparc64/SYS.h
+++ b/lib/libc/arch/sparc64/SYS.h
@@ -1,4 +1,4 @@
-/* $OpenBSD: SYS.h,v 1.11 2014/06/04 20:13:49 matthew Exp $ */
+/* $OpenBSD: SYS.h,v 1.12 2015/04/07 01:27:07 guenther Exp $ */
/*-
* Copyright (c) 1992, 1993
* The Regents of the University of California. All rights reserved.
@@ -43,7 +43,8 @@
#define _CAT(x,y) x##y
-#define __ENTRY(p,x) ENTRY(_CAT(p,x)) ; .weak x; x = _CAT(p,x)
+#define __ENTRY(p,x) ENTRY(_CAT(p,x)) ; .weak x; x = _CAT(p,x)
+#define __ENTRY_HIDDEN(p,x) ENTRY(_CAT(p,x))
/*
* ERROR branches to cerror. This is done with a macro so that I can
@@ -71,18 +72,26 @@
*/
#define _SYSCALL(p,x,y) \
__ENTRY(p,x); mov _CAT(SYS_,y),%g1; t ST_SYSCALL; bcc 1f; nop; ERROR(); 1:
+#define _SYSCALL_HIDDEN(p,x,y) \
+ __ENTRY_HIDDEN(p,x); mov _CAT(SYS_,y),%g1; t ST_SYSCALL; bcc 1f; nop; ERROR(); 1:
#define __SYSCALL(p,x) \
_SYSCALL(p,x,x)
+#define __SYSCALL_HIDDEN(p,x) \
+ _SYSCALL_HIDDEN(p,x,x)
+
/*
* RSYSCALL is used when the system call should just return. Here
* we use the SYSCALL_G2RFLAG to put the `success' return address in %g2
* and avoid a branch.
*/
#define __RSYSCALL(p,x) \
- __ENTRY(p,x); mov (_CAT(SYS_,x))|SYSCALL_G2RFLAG,%g1; add %o7,8,%g2; \
- t ST_SYSCALL; ERROR()
+ __ENTRY(p,x); mov (_CAT(SYS_,x))|SYSCALL_G2RFLAG,%g1; \
+ add %o7,8,%g2; t ST_SYSCALL; ERROR()
+#define __RSYSCALL_HIDDEN(p,x) \
+ __ENTRY_HIDDEN(p,x); mov (_CAT(SYS_,x))|SYSCALL_G2RFLAG,%g1; \
+ add %o7,8,%g2; t ST_SYSCALL; ERROR()
/*
* PSEUDO(x,y) is like RSYSCALL(y) except that the name is x.
@@ -126,6 +135,7 @@
#define SYSCALL(x) __SYSCALL(_thread_sys_,x)
#define RSYSCALL(x) __RSYSCALL(_thread_sys_,x)
+#define RSYSCALL_HIDDEN(x) __RSYSCALL_HIDDEN(_thread_sys_,x)
#define RSYSCALL_NOERROR(x,y) __RSYSCALL_NOERROR(_thread_sys_,x,y)
#define PSEUDO(x,y) __PSEUDO(_thread_sys_,x,y)
#define PSEUDO_NOERROR(x,y) __PSEUDO_NOERROR(_thread_sys_,x,y)
diff --git a/lib/libc/arch/sparc64/sys/fork.S b/lib/libc/arch/sparc64/sys/fork.S
index ffb32b62ad0..f432448d4ad 100644
--- a/lib/libc/arch/sparc64/sys/fork.S
+++ b/lib/libc/arch/sparc64/sys/fork.S
@@ -1,4 +1,4 @@
-/* $OpenBSD: fork.S,v 1.3 2015/03/31 04:32:02 guenther Exp $ */
+/* $OpenBSD: fork.S,v 1.4 2015/04/07 01:27:07 guenther Exp $ */
/*
* Copyright (c) 1992, 1993
@@ -37,4 +37,5 @@
#include "SYS.h"
-RSYSCALL(fork)
+RSYSCALL_HIDDEN(fork)
+WEAK_ALIAS(_thread_fork,_thread_sys_fork)
diff --git a/lib/libc/arch/vax/SYS.h b/lib/libc/arch/vax/SYS.h
index 816c700f2ff..2449243f186 100644
--- a/lib/libc/arch/vax/SYS.h
+++ b/lib/libc/arch/vax/SYS.h
@@ -1,4 +1,4 @@
-/* $OpenBSD: SYS.h,v 1.16 2014/06/04 20:13:49 matthew Exp $ */
+/* $OpenBSD: SYS.h,v 1.17 2015/04/07 01:27:07 guenther Exp $ */
/* $NetBSD: SYS.h,v 1.4 1997/05/02 18:15:32 kleink Exp $ */
/*
@@ -66,6 +66,7 @@
__SYSCALL(_thread_sys_,x,x)
#define RSYSCALL(x) __ALIAS(_thread_sys_,x) \
__PSEUDO(_thread_sys_,x,x)
+#define RSYSCALL_HIDDEN(x) __PSEUDO(_thread_sys_,x,x)
#define PSEUDO(x,y) __ALIAS(_thread_sys_,x) \
__PSEUDO(_thread_sys_,x,y)
#define PSEUDO_NOERROR(x,y) __ALIAS(_thread_sys_,x) \
diff --git a/lib/libc/arch/vax/sys/fork.S b/lib/libc/arch/vax/sys/fork.S
index 9204b5af8b2..4848c1e21ec 100644
--- a/lib/libc/arch/vax/sys/fork.S
+++ b/lib/libc/arch/vax/sys/fork.S
@@ -1,4 +1,4 @@
-/* $OpenBSD: fork.S,v 1.6 2015/03/31 04:32:02 guenther Exp $ */
+/* $OpenBSD: fork.S,v 1.7 2015/04/07 01:27:07 guenther Exp $ */
/*
* Copyright (c) 1983, 1993
* The Regents of the University of California. All rights reserved.
@@ -30,4 +30,5 @@
#include "SYS.h"
-RSYSCALL(fork)
+RSYSCALL_HIDDEN(fork)
+WEAK_ALIAS(_thread_fork,_thread_sys_fork)
diff --git a/lib/libc/include/atfork.h b/lib/libc/include/atfork.h
new file mode 100644
index 00000000000..8ec611098c1
--- /dev/null
+++ b/lib/libc/include/atfork.h
@@ -0,0 +1,44 @@
+/* $OpenBSD: atfork.h,v 1.1 2015/04/07 01:27:07 guenther Exp $ */
+
+/*
+ * Copyright (c) 2008 Kurt Miller <kurt@openbsd.org>
+ * Copyright (c) 2008 Philip Guenther <guenther@openbsd.org>
+ * Copyright (c) 2003 Daniel Eischen <deischen@freebsd.org>
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Neither the name of the author nor the names of any co-contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * $FreeBSD: /repoman/r/ncvs/src/lib/libc_r/uthread/uthread_atfork.c,v 1.1 2004/12/10 03:36:45 grog Exp $
+ */
+
+#include <sys/queue.h>
+
+struct atfork_fn {
+ TAILQ_ENTRY(atfork_fn) fn_next;
+ void (*fn_prepare)(void);
+ void (*fn_parent)(void);
+ void (*fn_child)(void);
+ void *fn_dso;
+};
+
+extern TAILQ_HEAD(atfork_listhead, atfork_fn) _atfork_list;
+
diff --git a/lib/libc/include/thread_private.h b/lib/libc/include/thread_private.h
index 673fb9c6a69..43ebf7d96e8 100644
--- a/lib/libc/include/thread_private.h
+++ b/lib/libc/include/thread_private.h
@@ -1,4 +1,4 @@
-/* $OpenBSD: thread_private.h,v 1.25 2011/10/16 06:29:56 guenther Exp $ */
+/* $OpenBSD: thread_private.h,v 1.26 2015/04/07 01:27:07 guenther Exp $ */
/* PUBLIC DOMAIN: No Rights Reserved. Marco S Hyman <marc@snafu.org> */
@@ -160,6 +160,18 @@ void _thread_atexit_unlock(void);
_thread_atexit_unlock();\
} while (0)
+void _thread_atfork_lock(void);
+void _thread_atfork_unlock(void);
+
+#define _ATFORK_LOCK() do { \
+ if (__isthreaded) \
+ _thread_atfork_lock(); \
+ } while (0)
+#define _ATFORK_UNLOCK() do { \
+ if (__isthreaded) \
+ _thread_atfork_unlock();\
+ } while (0)
+
void _thread_arc4_lock(void);
void _thread_arc4_unlock(void);
@@ -172,4 +184,9 @@ void _thread_arc4_unlock(void);
_thread_arc4_unlock();\
} while (0)
+/*
+ * Wrapper for _thread_sys_fork()
+ */
+pid_t _thread_fork(void);
+
#endif /* _THREAD_PRIVATE_H_ */
diff --git a/lib/libc/shlib_version b/lib/libc/shlib_version
index 72264f2e9ce..add7e4a9c1c 100644
--- a/lib/libc/shlib_version
+++ b/lib/libc/shlib_version
@@ -1,4 +1,4 @@
-major=78
-minor=1
+major=79
+minor=0
# note: If changes were made to include/thread_private.h or if system
# calls were added/changed then librthread/shlib_version also be updated.
diff --git a/lib/libc/stdlib/atexit.c b/lib/libc/stdlib/atexit.c
index 6532b382eab..a33080571fe 100644
--- a/lib/libc/stdlib/atexit.c
+++ b/lib/libc/stdlib/atexit.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: atexit.c,v 1.20 2014/07/11 09:51:37 kettenis Exp $ */
+/* $OpenBSD: atexit.c,v 1.21 2015/04/07 01:27:07 guenther Exp $ */
/*
* Copyright (c) 2002 Daniel Hartmeier
* All rights reserved.
@@ -35,6 +35,7 @@
#include <string.h>
#include <unistd.h>
#include "atexit.h"
+#include "atfork.h"
#include "thread_private.h"
struct atexit *__atexit;
@@ -161,6 +162,23 @@ restart:
__atexit = NULL;
}
_ATEXIT_UNLOCK();
+
+ /*
+ * If unloading a DSO, unregister any atfork handlers registered
+ * by it. Skip the locking if the list is currently empty.
+ */
+ if (dso != NULL && TAILQ_FIRST(&_atfork_list) != NULL) {
+ struct atfork_fn *af, *afnext;
+
+ _ATFORK_LOCK();
+ TAILQ_FOREACH_SAFE(af, &_atfork_list, fn_next, afnext)
+ if (af->fn_dso == dso) {
+ TAILQ_REMOVE(&_atfork_list, af, fn_next);
+ free(af);
+ }
+ _ATFORK_UNLOCK();
+
+ }
}
/*
diff --git a/lib/libc/sys/Makefile.inc b/lib/libc/sys/Makefile.inc
index 6cf739c5530..ee9b8ff6737 100644
--- a/lib/libc/sys/Makefile.inc
+++ b/lib/libc/sys/Makefile.inc
@@ -1,4 +1,4 @@
-# $OpenBSD: Makefile.inc,v 1.124 2014/12/08 20:56:11 guenther Exp $
+# $OpenBSD: Makefile.inc,v 1.125 2015/04/07 01:27:07 guenther Exp $
# $NetBSD: Makefile.inc,v 1.35 1995/10/16 23:49:07 jtc Exp $
# @(#)Makefile.inc 8.1 (Berkeley) 6/17/93
@@ -11,7 +11,7 @@ SRCS+= Ovfork.S brk.S cerror.S exect.S fork.S \
sigsuspend.S syscall.S tfork_thread.S
# glue to offer userland wrappers for some syscalls
-SRCS+= posix_madvise.c
+SRCS+= posix_madvise.c w_fork.c
# glue to provide compatibility between GCC 1.X and 2.X and for compat
# with old syscall interfaces.
diff --git a/lib/libc/sys/w_fork.c b/lib/libc/sys/w_fork.c
new file mode 100644
index 00000000000..1c6080e0cbd
--- /dev/null
+++ b/lib/libc/sys/w_fork.c
@@ -0,0 +1,74 @@
+/* $OpenBSD: w_fork.c,v 1.1 2015/04/07 01:27:07 guenther Exp $ */
+
+/*
+ * Copyright (c) 2008 Kurt Miller <kurt@openbsd.org>
+ * Copyright (c) 2008 Philip Guenther <guenther@openbsd.org>
+ * Copyright (c) 2003 Daniel Eischen <deischen@freebsd.org>
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Neither the name of the author nor the names of any co-contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * $FreeBSD: /repoman/r/ncvs/src/lib/libc_r/uthread/uthread_atfork.c,v 1.1 2004/12/10 03:36:45 grog Exp $
+ */
+
+#include <unistd.h>
+#include "thread_private.h"
+#include "atfork.h"
+
+/* define and initialize the list */
+struct atfork_listhead _atfork_list = TAILQ_HEAD_INITIALIZER(_atfork_list);
+
+pid_t _thread_fork(void);
+
+pid_t
+fork(void)
+{
+ struct atfork_fn *p;
+ pid_t newid;
+
+ /*
+ * In the common case the list is empty; remain async-signal-safe
+ * then by skipping the locking and just forking
+ */
+ if (TAILQ_FIRST(&_atfork_list) == NULL)
+ return (_thread_fork());
+
+ _ATFORK_LOCK();
+ TAILQ_FOREACH_REVERSE(p, &_atfork_list, atfork_listhead, fn_next)
+ if (p->fn_prepare)
+ p->fn_prepare();
+
+ newid = _thread_fork();
+
+ if (newid == 0) {
+ TAILQ_FOREACH(p, &_atfork_list, fn_next)
+ if (p->fn_child)
+ p->fn_child();
+ } else {
+ TAILQ_FOREACH(p, &_atfork_list, fn_next)
+ if (p->fn_parent)
+ p->fn_parent();
+ }
+ _ATFORK_UNLOCK();
+
+ return (newid);
+}
diff --git a/lib/libc/thread/Makefile.inc b/lib/libc/thread/Makefile.inc
index 248e6ede8cf..b5d3cb147dc 100644
--- a/lib/libc/thread/Makefile.inc
+++ b/lib/libc/thread/Makefile.inc
@@ -1,5 +1,5 @@
-# $OpenBSD: Makefile.inc,v 1.8 2014/07/16 20:02:17 okan Exp $
+# $OpenBSD: Makefile.inc,v 1.9 2015/04/07 01:27:07 guenther Exp $
.PATH: ${LIBCSRCDIR}/thread
-SRCS+= unithread_malloc_lock.c unithread_mutex.c unithread_tag.c
+SRCS+= unithread_malloc_lock.c unithread_mutex.c unithread_tag.c atfork.c
diff --git a/lib/libc/thread/atfork.c b/lib/libc/thread/atfork.c
new file mode 100644
index 00000000000..e4ae398df5a
--- /dev/null
+++ b/lib/libc/thread/atfork.c
@@ -0,0 +1,56 @@
+/* $OpenBSD: atfork.c,v 1.1 2015/04/07 01:27:07 guenther Exp $ */
+
+/*
+ * Copyright (c) 2008 Kurt Miller <kurt@openbsd.org>
+ * Copyright (c) 2008 Philip Guenther <guenther@openbsd.org>
+ * Copyright (c) 2003 Daniel Eischen <deischen@freebsd.org>
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Neither the name of the author nor the names of any co-contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * $FreeBSD: /repoman/r/ncvs/src/lib/libc_r/uthread/uthread_atfork.c,v 1.1 2004/12/10 03:36:45 grog Exp $
+ */
+
+#include <errno.h>
+#include <stdlib.h>
+
+#include "thread_private.h"
+#include "atfork.h"
+
+int
+_thread_atfork(void (*prepare)(void), void (*parent)(void),
+ void (*child)(void), void *dso)
+{
+ struct atfork_fn *af;
+
+ if ((af = malloc(sizeof *af)) == NULL)
+ return (ENOMEM);
+
+ af->fn_prepare = prepare;
+ af->fn_parent = parent;
+ af->fn_child = child;
+ af->fn_dso = dso;
+ _ATFORK_LOCK();
+ TAILQ_INSERT_TAIL(&_atfork_list, af, fn_next);
+ _ATFORK_UNLOCK();
+ return (0);
+}
diff --git a/lib/libc/thread/unithread_malloc_lock.c b/lib/libc/thread/unithread_malloc_lock.c
index 920250139b8..d813bc708f2 100644
--- a/lib/libc/thread/unithread_malloc_lock.c
+++ b/lib/libc/thread/unithread_malloc_lock.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: unithread_malloc_lock.c,v 1.8 2008/06/13 21:18:43 otto Exp $ */
+/* $OpenBSD: unithread_malloc_lock.c,v 1.9 2015/04/07 01:27:07 guenther Exp $ */
#include <sys/time.h>
#include "thread_private.h"
@@ -15,6 +15,12 @@ WEAK_PROTOTYPE(_thread_atexit_unlock);
WEAK_ALIAS(_thread_atexit_lock);
WEAK_ALIAS(_thread_atexit_unlock);
+WEAK_PROTOTYPE(_thread_atfork_lock);
+WEAK_PROTOTYPE(_thread_atfork_unlock);
+
+WEAK_ALIAS(_thread_atfork_lock);
+WEAK_ALIAS(_thread_atfork_unlock);
+
WEAK_PROTOTYPE(_thread_arc4_lock);
WEAK_PROTOTYPE(_thread_arc4_unlock);
@@ -46,6 +52,18 @@ WEAK_NAME(_thread_atexit_unlock)(void)
}
void
+WEAK_NAME(_thread_atfork_lock)(void)
+{
+ return;
+}
+
+void
+WEAK_NAME(_thread_atfork_unlock)(void)
+{
+ return;
+}
+
+void
WEAK_NAME(_thread_arc4_lock)(void)
{
return;
diff --git a/lib/librthread/rthread.c b/lib/librthread/rthread.c
index 632308ef5db..688f438a27b 100644
--- a/lib/librthread/rthread.c
+++ b/lib/librthread/rthread.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: rthread.c,v 1.79 2014/11/16 05:26:20 guenther Exp $ */
+/* $OpenBSD: rthread.c,v 1.80 2015/04/07 01:27:07 guenther Exp $ */
/*
* Copyright (c) 2004,2005 Ted Unangst <tedu@openbsd.org>
* All Rights Reserved.
@@ -736,6 +736,8 @@ static void *__libc_overrides[] __used = {
&_thread_arc4_unlock,
&_thread_atexit_lock,
&_thread_atexit_unlock,
+ &_thread_atfork_lock,
+ &_thread_atfork_unlock,
&_thread_malloc_lock,
&_thread_malloc_unlock,
&_thread_mutex_destroy,
diff --git a/lib/librthread/rthread_fork.c b/lib/librthread/rthread_fork.c
index cb76421d2a1..c9086daf595 100644
--- a/lib/librthread/rthread_fork.c
+++ b/lib/librthread/rthread_fork.c
@@ -1,8 +1,8 @@
-/* $OpenBSD: rthread_fork.c,v 1.10 2013/11/29 16:27:40 guenther Exp $ */
+/* $OpenBSD: rthread_fork.c,v 1.11 2015/04/07 01:27:07 guenther Exp $ */
/*
* Copyright (c) 2008 Kurt Miller <kurt@openbsd.org>
- * Copyright (c) 2008 Philip Guenther <guenther@gmail.com>
+ * Copyright (c) 2008 Philip Guenther <guenther@openbsd.org>
* Copyright (c) 2003 Daniel Eischen <deischen@freebsd.org>
* All rights reserved.
*
@@ -46,18 +46,6 @@
#include "rthread.h"
-struct rthread_atfork {
- TAILQ_ENTRY(rthread_atfork) next;
- void (*prepare)(void);
- void (*parent)(void);
- void (*child)(void);
-};
-
-static TAILQ_HEAD(atfork_listhead, rthread_atfork) _atfork_list =
- TAILQ_HEAD_INITIALIZER(_atfork_list);
-
-static struct _spinlock _atfork_lock = _SPINLOCK_UNLOCKED;
-
pid_t _thread_sys_fork(void);
pid_t _thread_sys_vfork(void);
pid_t _dofork(int);
@@ -144,27 +132,9 @@ _dofork(int is_vfork)
}
pid_t
-fork(void)
+_thread_fork(void)
{
- struct rthread_atfork *p;
- pid_t newid;
-
- _spinlock(&_atfork_lock);
- TAILQ_FOREACH_REVERSE(p, &_atfork_list, atfork_listhead, next)
- if (p->prepare)
- p->prepare();
- newid = _dofork(0);
- if (newid == 0) {
- TAILQ_FOREACH(p, &_atfork_list, next)
- if (p->child)
- p->child();
- } else {
- TAILQ_FOREACH(p, &_atfork_list, next)
- if (p->parent)
- p->parent();
- }
- _spinunlock(&_atfork_lock);
- return newid;
+ return _dofork(0);
}
pid_t
@@ -172,21 +142,3 @@ vfork(void)
{
return _dofork(1);
}
-
-int
-pthread_atfork(void (*prepare)(void), void (*parent)(void),
- void (*child)(void))
-{
- struct rthread_atfork *af;
-
- if ((af = malloc(sizeof *af)) == NULL)
- return (ENOMEM);
-
- af->prepare = prepare;
- af->parent = parent;
- af->child = child;
- _spinlock(&_atfork_lock);
- TAILQ_INSERT_TAIL(&_atfork_list, af, next);
- _spinunlock(&_atfork_lock);
- return (0);
-}
diff --git a/lib/librthread/rthread_libc.c b/lib/librthread/rthread_libc.c
index 13df27c498e..018368a84dd 100644
--- a/lib/librthread/rthread_libc.c
+++ b/lib/librthread/rthread_libc.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: rthread_libc.c,v 1.11 2013/06/01 20:47:40 tedu Exp $ */
+/* $OpenBSD: rthread_libc.c,v 1.12 2015/04/07 01:27:07 guenther Exp $ */
/* $snafu: libc_tag.c,v 1.4 2004/11/30 07:00:06 marc Exp $ */
/* PUBLIC DOMAIN: No Rights Reserved. Marco S Hyman <marc@snafu.org> */
@@ -184,6 +184,23 @@ _thread_atexit_unlock(void)
}
/*
+ * atfork lock
+ */
+static struct _spinlock atfork_lock = _SPINLOCK_UNLOCKED;
+
+void
+_thread_atfork_lock(void)
+{
+ _spinlock(&atfork_lock);
+}
+
+void
+_thread_atfork_unlock(void)
+{
+ _spinunlock(&atfork_lock);
+}
+
+/*
* arc4random lock
*/
static struct _spinlock arc4_lock = _SPINLOCK_UNLOCKED;
diff --git a/lib/librthread/shlib_version b/lib/librthread/shlib_version
index 7c92aff4893..0aab0406bf8 100644
--- a/lib/librthread/shlib_version
+++ b/lib/librthread/shlib_version
@@ -1,2 +1,2 @@
-major=18
-minor=1
+major=19
+minor=0
diff --git a/regress/lib/csu/callbacks/Makefile b/regress/lib/csu/callbacks/Makefile
index 48474134a56..b74854fb45c 100644
--- a/regress/lib/csu/callbacks/Makefile
+++ b/regress/lib/csu/callbacks/Makefile
@@ -1,7 +1,6 @@
-# $OpenBSD: Makefile,v 1.1 2014/11/23 08:46:49 guenther Exp $
+# $OpenBSD: Makefile,v 1.2 2015/04/07 01:27:07 guenther Exp $
-SUBDIR+= libaa libab atexit
-# not yet: pthread_atfork
+SUBDIR+= libaa libab atexit pthread_atfork
install:
diff --git a/regress/lib/csu/callbacks/pthread_atfork/Makefile b/regress/lib/csu/callbacks/pthread_atfork/Makefile
index 8e685447d7b..ecefb366a9b 100644
--- a/regress/lib/csu/callbacks/pthread_atfork/Makefile
+++ b/regress/lib/csu/callbacks/pthread_atfork/Makefile
@@ -1,4 +1,4 @@
-# $OpenBSD: Makefile,v 1.1 2014/11/23 08:46:49 guenther Exp $
+# $OpenBSD: Makefile,v 1.2 2015/04/07 01:27:07 guenther Exp $
.include <bsd.obj.mk>
@@ -31,7 +31,7 @@ NOMAN=
CLEANFILES= parent_out child_out
-TESTS= 0
+TESTS= 0 1 2 3
regress-pthread_atfork: ${PROG}
for i in ${TESTS}; do \
diff --git a/regress/lib/csu/callbacks/pthread_atfork/expected_child.out b/regress/lib/csu/callbacks/pthread_atfork/expected_child.out
new file mode 100644
index 00000000000..345d837c844
--- /dev/null
+++ b/regress/lib/csu/callbacks/pthread_atfork/expected_child.out
@@ -0,0 +1,20 @@
+testp atfork1_child
+libaa atfork_child
+testp atfork2_child
+libab atfork_child
+testp atfork3_child
+finished 0
+
+testp atfork1_child
+testp atfork2_child
+testp atfork3_child
+finished 1
+
+testp atfork1_child
+testp atfork3_child
+finished 2
+
+testp atfork1_child
+testp atfork2_child
+finished 3
+
diff --git a/regress/lib/csu/callbacks/pthread_atfork/expected_parent.out b/regress/lib/csu/callbacks/pthread_atfork/expected_parent.out
new file mode 100644
index 00000000000..18cdc22e663
--- /dev/null
+++ b/regress/lib/csu/callbacks/pthread_atfork/expected_parent.out
@@ -0,0 +1,37 @@
+testp atfork3_prepare
+libab atfork_prepare
+testp atfork2_prepare
+libaa atfork_prepare
+testp atfork1_prepare
+testp atfork1_parent
+libaa atfork_parent
+testp atfork2_parent
+libab atfork_parent
+testp atfork3_parent
+finished 0
+
+testp atfork3_prepare
+testp atfork2_prepare
+testp atfork1_prepare
+testp atfork1_parent
+testp atfork2_parent
+testp atfork3_parent
+finished 1
+
+testp atfork3_prepare
+libab atfork_prepare
+exe atfork_dlclose begin
+exe atfork_dlclose end
+testp atfork1_prepare
+testp atfork1_parent
+testp atfork3_parent
+finished 2
+
+exe atfork_dlclose begin
+exe atfork_dlclose end
+testp atfork2_prepare
+testp atfork1_prepare
+testp atfork1_parent
+testp atfork2_parent
+finished 3
+
diff --git a/regress/lib/csu/callbacks/pthread_atfork/pthread_atfork_test.c b/regress/lib/csu/callbacks/pthread_atfork/pthread_atfork_test.c
index c6a93a0e080..225e5f1f1af 100644
--- a/regress/lib/csu/callbacks/pthread_atfork/pthread_atfork_test.c
+++ b/regress/lib/csu/callbacks/pthread_atfork/pthread_atfork_test.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: pthread_atfork_test.c,v 1.1 2014/11/23 08:46:49 guenther Exp $ */
+/* $OpenBSD: pthread_atfork_test.c,v 1.2 2015/04/07 01:27:07 guenther Exp $ */
/*
* Copyright (c) 2014 Philip Guenther <guenther@openbsd.org>
@@ -16,6 +16,7 @@
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/
+#include <sys/wait.h>
#include <dlfcn.h>
#include <err.h>
#include <pthread.h>
@@ -86,7 +87,7 @@ int
main(int argc, char **argv)
{
pid_t pid;
- int test;
+ int test, status;
otherf = fdopen(3, "w");
if (otherf == NULL)
@@ -150,5 +151,6 @@ main(int argc, char **argv)
fflush(otherf);
pid = fork();
+ waitpid(pid, &status, 0);
return (0);
}