summaryrefslogtreecommitdiffstats
path: root/lib/libc
diff options
context:
space:
mode:
Diffstat (limited to 'lib/libc')
-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
35 files changed, 436 insertions, 64 deletions
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;