aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--include/Makefile8
-rw-r--r--include/time.h7
-rw-r--r--include/unistd.h1
-rw-r--r--lib/csu/i386/crt0.c10
-rw-r--r--lib/libc/amd64/SYS.h17
-rw-r--r--lib/libc/amd64/gen/_setjmp.S12
-rw-r--r--lib/libc/amd64/gen/setjmp.S20
-rw-r--r--lib/libc/amd64/gen/sigsetjmp.S20
-rw-r--r--lib/libc/amd64/sys/cerror.S28
-rw-r--r--lib/libc/amd64/sys/pipe.S6
-rw-r--r--lib/libc/amd64/sys/sigreturn.S6
-rw-r--r--lib/libc/amd64/sys/vfork.S28
-rw-r--r--lib/libc/db/hash/hash.c14
-rw-r--r--lib/libc/db/hash/hash.h2
-rw-r--r--lib/libc/db/hash/ndbm.c4
-rw-r--r--lib/libc/gen/Makefile.inc4
-rw-r--r--lib/libc/gen/isatty.c17
-rw-r--r--lib/libc/gen/sleep.c20
-rw-r--r--lib/libc/gen/ttyname.c111
-rw-r--r--lib/libc/gen/usleep.c19
-rw-r--r--lib/libc/i386/SYS.h17
-rw-r--r--lib/libc/i386/gen/_setjmp.S12
-rw-r--r--lib/libc/i386/gen/setjmp.S20
-rw-r--r--lib/libc/i386/gen/sigsetjmp.S20
-rw-r--r--lib/libc/i386/sys/Ovfork.S28
-rw-r--r--lib/libc/i386/sys/cerror.S28
-rw-r--r--lib/libc/i386/sys/fork.S6
-rw-r--r--lib/libc/i386/sys/pipe.S6
-rw-r--r--lib/libc/i386/sys/sigpending.S6
-rw-r--r--lib/libc/i386/sys/sigprocmask.S8
-rw-r--r--lib/libc/i386/sys/sigreturn.S6
-rw-r--r--lib/libc/i386/sys/sigsuspend.S8
-rw-r--r--lib/libc/stdio/clrerr.c10
-rw-r--r--lib/libc/stdio/fclose.c12
-rw-r--r--lib/libc/stdio/fflush.c19
-rw-r--r--lib/libc/stdio/fgetc.c15
-rw-r--r--lib/libc/stdio/fgetpos.c15
-rw-r--r--lib/libc/stdio/fgets.c20
-rw-r--r--lib/libc/stdio/fpurge.c28
-rw-r--r--lib/libc/stdio/fputc.c15
-rw-r--r--lib/libc/stdio/fputs.c15
-rw-r--r--lib/libc/stdio/fread.c11
-rw-r--r--lib/libc/stdio/fscanf.c12
-rw-r--r--lib/libc/stdio/fseek.c28
-rw-r--r--lib/libc/stdio/ftell.c16
-rw-r--r--lib/libc/stdio/fwrite.c16
-rw-r--r--lib/libc/stdio/getc.c15
-rw-r--r--lib/libc/stdio/getchar.c15
-rw-r--r--lib/libc/stdio/putc.c15
-rw-r--r--lib/libc/stdio/putchar.c15
-rw-r--r--lib/libc/stdio/puts.c15
-rw-r--r--lib/libc/stdio/putw.c15
-rw-r--r--lib/libc/stdio/rewind.c10
-rw-r--r--lib/libc/stdio/scanf.c12
-rw-r--r--lib/libc/stdio/setvbuf.c14
-rw-r--r--lib/libc/stdio/snprintf.c3
-rw-r--r--lib/libc/stdio/sprintf.c3
-rw-r--r--lib/libc/stdio/sscanf.c3
-rw-r--r--lib/libc/stdio/ungetc.c37
-rw-r--r--lib/libc/stdio/vfprintf.c26
-rw-r--r--lib/libc/stdio/vscanf.c15
-rw-r--r--lib/libc/stdio/vsnprintf.c2
-rw-r--r--lib/libc/stdio/vsprintf.c2
-rw-r--r--lib/libc/stdio/vsscanf.c2
-rw-r--r--lib/libc/stdlib/abort.c13
-rw-r--r--lib/libc/stdlib/malloc.c69
-rw-r--r--lib/libc/stdtime/localtime.c130
-rw-r--r--lib/libc/sys/accept.225
-rw-r--r--lib/libc/sys/bind.222
-rw-r--r--lib/libc/sys/close.222
-rw-r--r--lib/libc/sys/connect.228
-rw-r--r--lib/libc/sys/dup.247
-rw-r--r--lib/libc/sys/execve.217
-rw-r--r--lib/libc/sys/fcntl.223
-rw-r--r--lib/libc/sys/flock.222
-rw-r--r--lib/libc/sys/fsync.222
-rw-r--r--lib/libc/sys/ftruncate.c16
-rw-r--r--lib/libc/sys/getdirentries.222
-rw-r--r--lib/libc/sys/getpeername.222
-rw-r--r--lib/libc/sys/getsockname.222
-rw-r--r--lib/libc/sys/getsockopt.245
-rw-r--r--lib/libc/sys/intro.244
-rw-r--r--lib/libc/sys/ioctl.222
-rw-r--r--lib/libc/sys/listen.224
-rw-r--r--lib/libc/sys/lseek.c17
-rw-r--r--lib/libc/sys/open.220
-rw-r--r--lib/libc/sys/read.247
-rw-r--r--lib/libc/sys/write.247
-rw-r--r--sys/sys/errno.h7
89 files changed, 1652 insertions, 113 deletions
diff --git a/include/Makefile b/include/Makefile
index c0ef1183e913..22bbe8a45b69 100644
--- a/include/Makefile
+++ b/include/Makefile
@@ -1,5 +1,5 @@
# From: @(#)Makefile 8.2 (Berkeley) 1/4/94
-# $Id: Makefile,v 1.30 1995/10/27 06:51:02 julian Exp $
+# $Id: Makefile,v 1.31 1995/11/12 19:29:08 markm Exp $
#
# Doing a make install builds /usr/include
#
@@ -13,10 +13,10 @@ SUBDIR= rpcsvc
FILES= a.out.h ar.h assert.h bitstring.h ctype.h db.h dirent.h disktab.h \
err.h f2c.h fnmatch.h fstab.h fts.h glob.h grp.h strhash.h histedit.h \
kvm.h limits.h link.h locale.h malloc.h memory.h mpool.h ndbm.h \
- netdb.h nl_types.h nlist.h paths.h pwd.h ranlib.h regex.h regexp.h \
- resolv.h rune.h runetype.h setjmp.h sgtty.h signal.h \
+ netdb.h nl_types.h nlist.h paths.h pthread.h pwd.h ranlib.h regex.h \
+ regexp.h resolv.h rune.h runetype.h setjmp.h sgtty.h signal.h \
stab.h stddef.h stdio.h stdlib.h string.h strings.h struct.h \
- sysexits.h tar.h time.h ttyent.h unistd.h utime.h \
+ sysexits.h tar.h time.h timers.h ttyent.h unistd.h utime.h \
utmp.h vis.h
.if defined(WANT_CSRG_LIBM)
FILES+= math.h
diff --git a/include/time.h b/include/time.h
index 884a2fb9bfd6..0c119a3c3ede 100644
--- a/include/time.h
+++ b/include/time.h
@@ -100,6 +100,13 @@ time_t mktime __P((struct tm *));
size_t strftime __P((char *, size_t, const char *, const struct tm *));
time_t time __P((time_t *));
+#ifdef _THREAD_SAFE
+int asctime_r __P((const struct tm *, char *, int));
+int ctime_r __P((const time_t *, char *, int));
+int gmtime_r __P((const time_t *, struct tm *));
+int localtime_r __P((const time_t *, struct tm *));
+#endif
+
#ifndef _ANSI_SOURCE
void tzset __P((void));
#endif /* not ANSI */
diff --git a/include/unistd.h b/include/unistd.h
index eb6d141aba6f..050a9cfe2301 100644
--- a/include/unistd.h
+++ b/include/unistd.h
@@ -165,6 +165,7 @@ int swapon __P((const char *));
int symlink __P((const char *, const char *));
void sync __P((void));
int syscall __P((int, ...));
+off_t __syscall __P((quad_t, ...));
int truncate __P((const char *, off_t));
int ttyslot __P((void));
unsigned int ualarm __P((unsigned int, unsigned int));
diff --git a/lib/csu/i386/crt0.c b/lib/csu/i386/crt0.c
index ecafd5d7457b..2cd03c30e34a 100644
--- a/lib/csu/i386/crt0.c
+++ b/lib/csu/i386/crt0.c
@@ -27,7 +27,7 @@
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
- * $Id: crt0.c,v 1.20 1995/10/29 09:49:21 phk Exp $
+ * $Id: crt0.c,v 1.21 1995/11/02 12:42:42 ache Exp $
*/
#include <sys/param.h>
@@ -98,6 +98,7 @@ extern start() asm("start");
extern mcount() asm ("mcount");
extern int main(int argc, char **argv, char **envp);
int __syscall(int syscall,...);
+void _thread_init();
#ifdef MCRT0
void monstartup(void *low, void *high);
#endif /* MCRT0 */
@@ -181,6 +182,13 @@ asm("eprol:");
monstartup(&eprol, &etext);
#endif /* MCRT0 */
+ /*
+ * Initialize the initial thread.
+ * This function might be a stub if libc does not
+ * contain thread support.
+ */
+ _thread_init();
+
asm ("__callmain:"); /* Defined for the benefit of debuggers */
exit(main(kfp->kargc, argv, environ));
}
diff --git a/lib/libc/amd64/SYS.h b/lib/libc/amd64/SYS.h
index 53837ab541f5..9e989e5116af 100644
--- a/lib/libc/amd64/SYS.h
+++ b/lib/libc/amd64/SYS.h
@@ -35,7 +35,7 @@
*
* from: @(#)SYS.h 5.5 (Berkeley) 5/7/91
*
- * $Id: SYS.h,v 1.3 1993/11/04 00:01:17 paul Exp $
+ * $Id: SYS.h,v 1.2 1994/08/05 01:17:57 wollman Exp $
*/
#include <sys/syscall.h>
@@ -63,6 +63,21 @@
#define SYSCALL(x) 2: jmp cerror; ENTRY(x); lea SYS_/**/x,%eax; LCALL(7,0); jb 2b
#define RSYSCALL(x) SYSCALL(x); ret
+
+#ifdef _THREAD_SAFE
+/*
+ * Support for user-space threads which require that some syscalls be
+ * private to the threaded library.
+ */
+#define PSYSCALL(x) 2: jmp cerror; ENTRY(_thread_sys_/**/x); lea SYS_/**/x,%eax; LCALL(7,0); jb 2b
+#else
+/*
+ * The non-threaded library defaults to traditional syscalls where
+ * the function name matches the syscall name.
+ */
+#define PSYSCALL(x) SYSCALL(x)
+#endif
+#define PRSYSCALL(x) PSYSCALL(x); ret
#define PSEUDO(x,y) ENTRY(x); lea SYS_/**/y, %eax; ; LCALL(7,0); ret
#define CALL(x,y) call _/**/y; addl $4*x,%esp
/* gas fucks up offset -- although we don't currently need it, do for BCS */
diff --git a/lib/libc/amd64/gen/_setjmp.S b/lib/libc/amd64/gen/_setjmp.S
index abd268486565..23a2cdea0a03 100644
--- a/lib/libc/amd64/gen/_setjmp.S
+++ b/lib/libc/amd64/gen/_setjmp.S
@@ -33,12 +33,12 @@
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
- * $Id$
+ * $Id: _setjmp.S,v 1.3 1995/01/23 01:26:41 davidg Exp $
*/
#if defined(LIBC_RCS) && !defined(lint)
.text
- .asciz "$Id$"
+ .asciz "$Id: _setjmp.S,v 1.3 1995/01/23 01:26:41 davidg Exp $"
#endif /* LIBC_RCS and not lint */
/*
@@ -53,7 +53,11 @@
#include "DEFS.h"
+#ifdef _THREAD_SAFE
+ENTRY(__thread_sys_setjmp)
+#else
ENTRY(_setjmp)
+#endif
movl 4(%esp),%eax
movl 0(%esp),%edx
movl %edx, 0(%eax) /* rta */
@@ -66,7 +70,11 @@ ENTRY(_setjmp)
xorl %eax,%eax
ret
+#ifdef _THREAD_SAFE
+ENTRY(__thread_sys_longjmp)
+#else
ENTRY(_longjmp)
+#endif
movl 4(%esp),%edx
movl 8(%esp),%eax
movl 0(%edx),%ecx
diff --git a/lib/libc/amd64/gen/setjmp.S b/lib/libc/amd64/gen/setjmp.S
index fa52b830ea1a..89efa92ccf85 100644
--- a/lib/libc/amd64/gen/setjmp.S
+++ b/lib/libc/amd64/gen/setjmp.S
@@ -33,12 +33,12 @@
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
- * $Id$
+ * $Id: setjmp.S,v 1.3 1995/01/23 01:27:08 davidg Exp $
*/
#if defined(LIBC_RCS) && !defined(lint)
.text
- .asciz "$Id$"
+ .asciz "$Id: setjmp.S,v 1.3 1995/01/23 01:27:08 davidg Exp $"
#endif /* LIBC_RCS and not lint */
/*
@@ -54,9 +54,17 @@
#include "DEFS.h"
#include "SYS.h"
+#ifdef _THREAD_SAFE
+ENTRY(_thread_sys_setjmp)
+#else
ENTRY(setjmp)
+#endif
pushl $0
+#ifdef _THREAD_SAFE
+ call PIC_PLT(__thread_sys_sigblock)
+#else
call PIC_PLT(_sigblock)
+#endif
popl %edx
movl 4(%esp),%ecx
movl 0(%esp),%edx
@@ -71,10 +79,18 @@ ENTRY(setjmp)
xorl %eax,%eax
ret
+#ifdef _THREAD_SAFE
+ENTRY(_thread_sys_longjmp)
+#else
ENTRY(longjmp)
+#endif
movl 4(%esp),%edx
pushl 24(%edx)
+#ifdef _THREAD_SAFE
+ call PIC_PLT(__thread_sys_sigsetmask)
+#else
call PIC_PLT(_sigsetmask) /* XXX this is not reentrant */
+#endif
popl %eax
movl 4(%esp),%edx
movl 8(%esp),%eax
diff --git a/lib/libc/amd64/gen/sigsetjmp.S b/lib/libc/amd64/gen/sigsetjmp.S
index 4f592a32a113..1e15101bfa33 100644
--- a/lib/libc/amd64/gen/sigsetjmp.S
+++ b/lib/libc/amd64/gen/sigsetjmp.S
@@ -33,12 +33,12 @@
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
- * $Id: sigsetjmp.S,v 1.3 1994/12/27 13:34:04 bde Exp $
+ * $Id: sigsetjmp.S,v 1.4 1995/01/23 01:27:10 davidg Exp $
*/
#if defined(LIBC_RCS) && !defined(lint)
.text
- .asciz "$Id: sigsetjmp.S,v 1.3 1994/12/27 13:34:04 bde Exp $"
+ .asciz "$Id: sigsetjmp.S,v 1.4 1995/01/23 01:27:10 davidg Exp $"
#endif /* LIBC_RCS and not lint */
#include "DEFS.h"
@@ -59,14 +59,22 @@
* use sigreturn() if sigreturn() works.
*/
+#ifdef _THREAD_SAFE
+ENTRY(_thread_sys_sigsetjmp)
+#else
ENTRY(sigsetjmp)
+#endif
movl 8(%esp),%eax
movl 4(%esp),%ecx
movl %eax,32(%ecx)
testl %eax,%eax
jz 1f
pushl $0
+#ifdef _THREAD_SAFE
+ call PIC_PLT(__thread_sys_sigblock)
+#else
call PIC_PLT(_sigblock)
+#endif
addl $4,%esp
movl 4(%esp),%ecx
movl %eax,24(%ecx)
@@ -81,12 +89,20 @@ ENTRY(sigsetjmp)
xorl %eax,%eax
ret
+#ifdef _THREAD_SAFE
+ENTRY(_thread_sys_siglongjmp)
+#else
ENTRY(siglongjmp)
+#endif
movl 4(%esp),%edx
cmpl $0,32(%edx)
jz 1f
pushl 24(%edx)
+#ifdef _THREAD_SAFE
+ call PIC_PLT(_thread_sys_sigsetmask)
+#else
call PIC_PLT(_sigsetmask)
+#endif
addl $4,%esp
1: movl 4(%esp),%edx
movl 8(%esp),%eax
diff --git a/lib/libc/amd64/sys/cerror.S b/lib/libc/amd64/sys/cerror.S
index 875f6db37219..2cbb0f94ab5b 100644
--- a/lib/libc/amd64/sys/cerror.S
+++ b/lib/libc/amd64/sys/cerror.S
@@ -33,16 +33,39 @@
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
- * $Id: cerror.S,v 1.2 1994/08/13 14:00:26 davidg Exp $
+ * $Id: cerror.S,v 1.3 1995/01/23 01:29:43 davidg Exp $
*/
#if defined(SYSLIBC_RCS) && !defined(lint)
.text
- .asciz "$Id$"
+ .asciz "$Id: cerror.S,v 1.3 1995/01/23 01:29:43 davidg Exp $"
#endif /* SYSLIBC_RCS and not lint */
#include "SYS.h"
+#ifdef _THREAD_SAFE
+ /*
+ * Threaded version using __error().
+ */
+ .globl ___error
+ .type ___error,@function
+cerror:
+ pushl %eax
+#ifdef PIC
+ call PIC_PLT(___error)
+#else
+ call ___error
+#endif
+ popl %ecx
+ movl %ecx,(%eax)
+ movl $-1,%eax
+ movl $-1,%edx
+ ret
+
+#else /* _THREAD_SAFE */
+ /*
+ * Non-threaded version using global errno.
+ */
.globl _errno
cerror:
#ifdef PIC
@@ -56,3 +79,4 @@ cerror:
movl $-1,%eax
movl $-1,%edx
ret
+#endif /* _THREAD_SAFE */
diff --git a/lib/libc/amd64/sys/pipe.S b/lib/libc/amd64/sys/pipe.S
index cf3264c9c495..809445f0bec7 100644
--- a/lib/libc/amd64/sys/pipe.S
+++ b/lib/libc/amd64/sys/pipe.S
@@ -33,17 +33,17 @@
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
- * $Id: pipe.S,v 1.1 1994/08/05 01:18:46 wollman Exp $
+ * $Id: pipe.S,v 1.2 1995/01/23 01:29:57 davidg Exp $
*/
#if defined(SYSLIBC_RCS) && !defined(lint)
.text
- .asciz "$Id$"
+ .asciz "$Id: pipe.S,v 1.2 1995/01/23 01:29:57 davidg Exp $"
#endif /* SYSLIBC_RCS and not lint */
#include "SYS.h"
-SYSCALL(pipe)
+PSYSCALL(pipe)
movl 4(%esp),%ecx
movl %eax,(%ecx)
movl %edx,4(%ecx)
diff --git a/lib/libc/amd64/sys/sigreturn.S b/lib/libc/amd64/sys/sigreturn.S
index ac0ffd653471..6f3f571c616e 100644
--- a/lib/libc/amd64/sys/sigreturn.S
+++ b/lib/libc/amd64/sys/sigreturn.S
@@ -33,12 +33,12 @@
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
- * $Id: sigreturn.S,v 1.1 1994/08/05 01:18:53 wollman Exp $
+ * $Id: sigreturn.S,v 1.2 1995/01/23 01:30:16 davidg Exp $
*/
#if defined(SYSLIBC_RCS) && !defined(lint)
.text
- .asciz "$Id$"
+ .asciz "$Id: sigreturn.S,v 1.2 1995/01/23 01:30:16 davidg Exp $"
#endif /* SYSLIBC_RCS and not lint */
#include "SYS.h"
@@ -53,5 +53,5 @@
.data; 1:; .long 0; .text; movl $1b,%eax; call mcount; popa ; nop
#endif /* PROF */
-SYSCALL(sigreturn)
+PSYSCALL(sigreturn)
ret
diff --git a/lib/libc/amd64/sys/vfork.S b/lib/libc/amd64/sys/vfork.S
index 06e3eb6a4812..341b75c97381 100644
--- a/lib/libc/amd64/sys/vfork.S
+++ b/lib/libc/amd64/sys/vfork.S
@@ -33,12 +33,12 @@
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
- * $Id: Ovfork.S,v 1.1 1994/08/05 01:18:38 wollman Exp $
+ * $Id: Ovfork.S,v 1.2 1995/01/23 01:29:37 davidg Exp $
*/
#if defined(SYSLIBC_RCS) && !defined(lint)
.text
- .asciz "$Id$"
+ .asciz "$Id: Ovfork.S,v 1.2 1995/01/23 01:29:37 davidg Exp $"
#endif /* SYSLIBC_RCS and not lint */
#include "SYS.h"
@@ -63,7 +63,28 @@ vforkok:
cmpl $0,%edx /* child process? */
jne child /* yes */
jmp parent
-.globl _errno
+#ifdef _THREAD_SAFE
+ /*
+ * Threaded version using __error().
+ */
+ .globl ___error
+ .type ___error,@function
+verror:
+ pushl %eax
+#ifdef PIC
+ call PIC_PLT(___error)
+#else
+ call ___error
+#endif
+ popl %ecx
+ movl %ecx,(%eax)
+ movl $-1,%eax
+ movl $-1,%edx
+#else /* !_THREAD_SAFE */
+ /*
+ * Non-threaded version using global errno.
+ */
+ .globl _errno
verror:
#ifdef PIC
PIC_PROLOGUE
@@ -74,6 +95,7 @@ verror:
movl %eax,_errno
#endif
movl $-1,%eax
+#endif /* !_THREAD_SAFE */
jmp %ecx
child:
movl $0,%eax
diff --git a/lib/libc/db/hash/hash.c b/lib/libc/db/hash/hash.c
index 6a23f3d801cb..76da99c055aa 100644
--- a/lib/libc/db/hash/hash.c
+++ b/lib/libc/db/hash/hash.c
@@ -505,7 +505,7 @@ flush_meta(hashp)
else
if (wsize != sizeof(HASHHDR)) {
errno = EFTYPE;
- hashp->errno = errno;
+ hashp->error = errno;
return (-1);
}
for (i = 0; i < NCACHED; i++)
@@ -536,7 +536,7 @@ hash_get(dbp, key, data, flag)
hashp = (HTAB *)dbp->internal;
if (flag) {
- hashp->errno = errno = EINVAL;
+ hashp->error = errno = EINVAL;
return (ERROR);
}
return (hash_access(hashp, HASH_GET, (DBT *)key, data));
@@ -553,11 +553,11 @@ hash_put(dbp, key, data, flag)
hashp = (HTAB *)dbp->internal;
if (flag && flag != R_NOOVERWRITE) {
- hashp->errno = errno = EINVAL;
+ hashp->error = errno = EINVAL;
return (ERROR);
}
if ((hashp->flags & O_ACCMODE) == O_RDONLY) {
- hashp->errno = errno = EPERM;
+ hashp->error = errno = EPERM;
return (ERROR);
}
return (hash_access(hashp, flag == R_NOOVERWRITE ?
@@ -574,11 +574,11 @@ hash_delete(dbp, key, flag)
hashp = (HTAB *)dbp->internal;
if (flag && flag != R_CURSOR) {
- hashp->errno = errno = EINVAL;
+ hashp->error = errno = EINVAL;
return (ERROR);
}
if ((hashp->flags & O_ACCMODE) == O_RDONLY) {
- hashp->errno = errno = EPERM;
+ hashp->error = errno = EPERM;
return (ERROR);
}
return (hash_access(hashp, HASH_DELETE, (DBT *)key, NULL));
@@ -729,7 +729,7 @@ hash_seq(dbp, key, data, flag)
hashp = (HTAB *)dbp->internal;
if (flag && flag != R_FIRST && flag != R_NEXT) {
- hashp->errno = errno = EINVAL;
+ hashp->error = errno = EINVAL;
return (ERROR);
}
#ifdef HASH_STATISTICS
diff --git a/lib/libc/db/hash/hash.h b/lib/libc/db/hash/hash.h
index 1c80f83c69d5..8664bd4816d9 100644
--- a/lib/libc/db/hash/hash.h
+++ b/lib/libc/db/hash/hash.h
@@ -98,7 +98,7 @@ typedef struct htab { /* Memory resident data structure */
BUFHEAD *cpage; /* Current page */
int cbucket; /* Current bucket */
int cndx; /* Index of next item on cpage */
- int errno; /* Error Number -- for DBM compatability */
+ int error; /* Error Number -- for DBM compatability */
int new_file; /* Indicates if fd is backing store or no */
int save_file; /* Indicates whether we need to flush file at
* exit */
diff --git a/lib/libc/db/hash/ndbm.c b/lib/libc/db/hash/ndbm.c
index 89b9916566b2..2b54402ae2f7 100644
--- a/lib/libc/db/hash/ndbm.c
+++ b/lib/libc/db/hash/ndbm.c
@@ -180,7 +180,7 @@ dbm_error(db)
HTAB *hp;
hp = (HTAB *)db->internal;
- return (hp->errno);
+ return (hp->error);
}
extern int
@@ -190,7 +190,7 @@ dbm_clearerr(db)
HTAB *hp;
hp = (HTAB *)db->internal;
- hp->errno = 0;
+ hp->error = 0;
return (0);
}
diff --git a/lib/libc/gen/Makefile.inc b/lib/libc/gen/Makefile.inc
index 69a434d85daa..3809f449f571 100644
--- a/lib/libc/gen/Makefile.inc
+++ b/lib/libc/gen/Makefile.inc
@@ -1,5 +1,5 @@
# From: @(#)Makefile.inc 8.3 (Berkeley) 4/16/94
-# $Id: Makefile.inc,v 1.15 1994/12/18 14:06:38 guido Exp $
+# $Id: Makefile.inc,v 1.16 1995/05/30 05:40:08 rgrimes Exp $
# machine-independent gen sources
.PATH: ${.CURDIR}/${MACHINE}/gen ${.CURDIR}/gen
@@ -19,7 +19,7 @@ SRCS+= alarm.c assert.c clock.c closedir.c config.c confstr.c crypt.c \
sigsetops.c sleep.c sysconf.c sysctl.c syslog.c \
telldir.c termios.c time.c times.c timezone.c ttyname.c ttyslot.c \
ualarm.c uname.c unvis.c usleep.c utime.c valloc.c vis.c wait.c \
- wait3.c waitpid.c
+ wait3.c waitpid.c _thread_init.c
# *rand48 family, from 1.1.5
SRCS+= _rand48.c drand48.c erand48.c jrand48.c lcong48.c lrand48.c \
diff --git a/lib/libc/gen/isatty.c b/lib/libc/gen/isatty.c
index f6bb04b86316..c8356c710342 100644
--- a/lib/libc/gen/isatty.c
+++ b/lib/libc/gen/isatty.c
@@ -37,12 +37,27 @@ static char sccsid[] = "@(#)isatty.c 8.1 (Berkeley) 6/4/93";
#include <termios.h>
#include <unistd.h>
+#ifdef _THREAD_SAFE
+#include <pthread.h>
+#include "pthread_private.h"
+#endif
int
isatty(fd)
int fd;
{
+ int retval;
struct termios t;
- return(tcgetattr(fd, &t) != -1);
+#ifdef _THREAD_SAFE
+ if (_thread_fd_lock(fd, FD_READ, NULL,__FILE__,__LINE__) == 0) {
+#endif
+ retval = (tcgetattr(fd, &t) != -1);
+#ifdef _THREAD_SAFE
+ _thread_fd_unlock(fd, FD_READ);
+ } else {
+ retval = 0;
+ }
+#endif
+ return(retval);
}
diff --git a/lib/libc/gen/sleep.c b/lib/libc/gen/sleep.c
index 98d997d8b046..b06475d392a5 100644
--- a/lib/libc/gen/sleep.c
+++ b/lib/libc/gen/sleep.c
@@ -38,16 +38,33 @@ static char sccsid[] = "@(#)sleep.c 8.1 (Berkeley) 6/4/93";
#include <sys/time.h>
#include <signal.h>
#include <unistd.h>
+#ifdef _THREAD_SAFE
+#include <pthread.h>
+#include "pthread_private.h"
+#else
#define setvec(vec, a) \
vec.sv_handler = a; vec.sv_mask = vec.sv_onstack = 0
static int ringring;
+#endif
unsigned int
sleep(seconds)
unsigned int seconds;
{
+#ifdef _THREAD_SAFE
+ struct timespec time_to_sleep;
+ struct timespec time_remaining;
+
+ if (seconds) {
+ time_to_sleep.ts_sec = seconds;
+ time_to_sleep.ts_nsec = 0;
+ nanosleep(&time_to_sleep,&time_remaining);
+ seconds = time_remaining.ts_sec;
+ }
+ return(seconds);
+#else
register struct itimerval *itp;
struct itimerval itv, oitv;
struct sigvec vec, ovec;
@@ -88,10 +105,13 @@ sleep(seconds)
(void) sigsetmask(omask);
(void) setitimer(ITIMER_REAL, &oitv, (struct itimerval *)0);
return 0;
+#endif
}
+#ifndef _THREAD_SAFE
static void
sleephandler()
{
ringring = 1;
}
+#endif
diff --git a/lib/libc/gen/ttyname.c b/lib/libc/gen/ttyname.c
index f024f52e20ca..39c640ee5eae 100644
--- a/lib/libc/gen/ttyname.c
+++ b/lib/libc/gen/ttyname.c
@@ -39,11 +39,121 @@ static char sccsid[] = "@(#)ttyname.c 8.2 (Berkeley) 1/27/94";
#include <sys/stat.h>
#include <fcntl.h>
#include <dirent.h>
+#include <stdlib.h>
#include <termios.h>
+#include <unistd.h>
#include <db.h>
#include <string.h>
#include <paths.h>
+#ifdef _THREAD_SAFE
+#include <pthread.h>
+#include "pthread_private.h"
+static pthread_mutex_t ttyname_lock = PTHREAD_MUTEX_INITIALIZER;
+static pthread_key_t ttyname_key;
+static int ttyname_init = 0;
+
+char *
+ttyname(int fd)
+{
+ char *ret;
+
+ if (_thread_fd_lock(fd, FD_READ, NULL, __FILE__, __LINE__) == 0) {
+ ret = __ttyname_basic(fd);
+ _thread_fd_unlock(fd, FD_READ);
+ } else {
+ ret = NULL;
+ }
+
+ return (ret);
+}
+
+char *
+__ttyname_r_basic(int fd, char *buf, size_t len)
+{
+ register struct dirent *dirp;
+ register DIR *dp;
+ struct stat dsb;
+ struct stat sb;
+ char *rval;
+ int minlen;
+
+ rval = NULL;
+
+ /* Must be a terminal. */
+ if (!isatty(fd))
+ return (rval);
+ /* Must be a character device. */
+ if (_thread_sys_fstat(fd, &sb) || !S_ISCHR(sb.st_mode))
+ return (rval);
+ /* Must have enough room */
+ if (len <= sizeof(_PATH_DEV))
+ return (rval);
+
+ if ((dp = opendir(_PATH_DEV)) != NULL) {
+ memcpy(buf, _PATH_DEV, sizeof(_PATH_DEV));
+ for (rval = NULL; (dirp = readdir(dp)) != NULL;) {
+ if (dirp->d_fileno != sb.st_ino)
+ continue;
+ minlen = (len - (sizeof(_PATH_DEV) - 1)) < (dirp->d_namlen + 1) ?
+ (len - (sizeof(_PATH_DEV) - 1)) : (dirp->d_namlen + 1);
+ memcpy(buf + sizeof(_PATH_DEV) - 1, dirp->d_name, minlen);
+ if (stat(buf, &dsb) || sb.st_dev != dsb.st_dev ||
+ sb.st_ino != dsb.st_ino)
+ continue;
+ rval = buf;
+ break;
+ }
+ (void) closedir(dp);
+ }
+ return (rval);
+}
+
+char *
+__ttyname_basic(int fd)
+{
+ char *buf;
+
+ pthread_mutex_lock(&ttyname_lock);
+ if (ttyname_init == 0) {
+ if (pthread_keycreate(&ttyname_key, free)) {
+ pthread_mutex_unlock(&ttyname_lock);
+ return (NULL);
+ }
+ ttyname_init = 1;
+ }
+ pthread_mutex_unlock(&ttyname_lock);
+
+ /* Must have thread specific data field to put data */
+ if (pthread_getspecific(ttyname_key, (void **) &buf) != 0) {
+ return (NULL);
+ } else if (buf == NULL) {
+ if ((buf = malloc(sizeof(_PATH_DEV) + MAXNAMLEN)) != NULL) {
+ if (pthread_setspecific(ttyname_key, buf) != 0) {
+ free(buf);
+ return (NULL);
+ }
+ } else {
+ return (NULL);
+ }
+ }
+ return (__ttyname_r_basic(fd, buf, sizeof(_PATH_DEV) + MAXNAMLEN));
+}
+
+char *
+ttyname_r(int fd, char *buf, size_t len)
+{
+ char *ret;
+
+ if (_thread_fd_lock(fd, FD_READ, NULL, __FILE__, __LINE__) == 0) {
+ ret = __ttyname_r_basic(fd, buf, len);
+ _thread_fd_unlock(fd, FD_READ);
+ } else {
+ ret = NULL;
+ }
+ return (ret);
+}
+#else
static char buf[sizeof(_PATH_DEV) + MAXNAMLEN] = _PATH_DEV;
static char *oldttyname __P((int, struct stat *));
@@ -110,3 +220,4 @@ oldttyname(fd, sb)
(void)closedir(dp);
return (NULL);
}
+#endif
diff --git a/lib/libc/gen/usleep.c b/lib/libc/gen/usleep.c
index 3f4a7f538b45..9e29f314d959 100644
--- a/lib/libc/gen/usleep.c
+++ b/lib/libc/gen/usleep.c
@@ -38,7 +38,10 @@ static char sccsid[] = "@(#)usleep.c 8.1 (Berkeley) 6/4/93";
#include <sys/time.h>
#include <signal.h>
#include <unistd.h>
-
+#ifdef _THREAD_SAFE
+#include <pthread.h>
+#include "pthread_private.h"
+#else
#define TICK 10000 /* system clock resolution in microseconds */
#define USPS 1000000 /* number of microseconds in a second */
@@ -46,11 +49,22 @@ static char sccsid[] = "@(#)usleep.c 8.1 (Berkeley) 6/4/93";
vec.sv_handler = a; vec.sv_mask = vec.sv_onstack = 0
static int ringring;
+#endif
+
void
usleep(useconds)
unsigned int useconds;
{
+#ifdef _THREAD_SAFE
+ struct timespec time_to_sleep;
+
+ if (useconds) {
+ time_to_sleep.ts_nsec = (useconds % 1000000) * 1000;
+ time_to_sleep.ts_sec = useconds / 1000000;
+ nanosleep(&time_to_sleep,NULL);
+ }
+#else
register struct itimerval *itp;
struct itimerval itv, oitv;
struct sigvec vec, ovec;
@@ -90,10 +104,13 @@ usleep(useconds)
(void) sigvec(SIGALRM, &ovec, (struct sigvec *)0);
(void) sigsetmask(omask);
(void) setitimer(ITIMER_REAL, &oitv, (struct itimerval *)0);
+#endif
}
+#ifndef _THREAD_SAFE
static void
sleephandler()
{
ringring = 1;
}
+#endif
diff --git a/lib/libc/i386/SYS.h b/lib/libc/i386/SYS.h
index 53837ab541f5..9e989e5116af 100644
--- a/lib/libc/i386/SYS.h
+++ b/lib/libc/i386/SYS.h
@@ -35,7 +35,7 @@
*
* from: @(#)SYS.h 5.5 (Berkeley) 5/7/91
*
- * $Id: SYS.h,v 1.3 1993/11/04 00:01:17 paul Exp $
+ * $Id: SYS.h,v 1.2 1994/08/05 01:17:57 wollman Exp $
*/
#include <sys/syscall.h>
@@ -63,6 +63,21 @@
#define SYSCALL(x) 2: jmp cerror; ENTRY(x); lea SYS_/**/x,%eax; LCALL(7,0); jb 2b
#define RSYSCALL(x) SYSCALL(x); ret
+
+#ifdef _THREAD_SAFE
+/*
+ * Support for user-space threads which require that some syscalls be
+ * private to the threaded library.
+ */
+#define PSYSCALL(x) 2: jmp cerror; ENTRY(_thread_sys_/**/x); lea SYS_/**/x,%eax; LCALL(7,0); jb 2b
+#else
+/*
+ * The non-threaded library defaults to traditional syscalls where
+ * the function name matches the syscall name.
+ */
+#define PSYSCALL(x) SYSCALL(x)
+#endif
+#define PRSYSCALL(x) PSYSCALL(x); ret
#define PSEUDO(x,y) ENTRY(x); lea SYS_/**/y, %eax; ; LCALL(7,0); ret
#define CALL(x,y) call _/**/y; addl $4*x,%esp
/* gas fucks up offset -- although we don't currently need it, do for BCS */
diff --git a/lib/libc/i386/gen/_setjmp.S b/lib/libc/i386/gen/_setjmp.S
index abd268486565..23a2cdea0a03 100644
--- a/lib/libc/i386/gen/_setjmp.S
+++ b/lib/libc/i386/gen/_setjmp.S
@@ -33,12 +33,12 @@
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
- * $Id$
+ * $Id: _setjmp.S,v 1.3 1995/01/23 01:26:41 davidg Exp $
*/
#if defined(LIBC_RCS) && !defined(lint)
.text
- .asciz "$Id$"
+ .asciz "$Id: _setjmp.S,v 1.3 1995/01/23 01:26:41 davidg Exp $"
#endif /* LIBC_RCS and not lint */
/*
@@ -53,7 +53,11 @@
#include "DEFS.h"
+#ifdef _THREAD_SAFE
+ENTRY(__thread_sys_setjmp)
+#else
ENTRY(_setjmp)
+#endif
movl 4(%esp),%eax
movl 0(%esp),%edx
movl %edx, 0(%eax) /* rta */
@@ -66,7 +70,11 @@ ENTRY(_setjmp)
xorl %eax,%eax
ret
+#ifdef _THREAD_SAFE
+ENTRY(__thread_sys_longjmp)
+#else
ENTRY(_longjmp)
+#endif
movl 4(%esp),%edx
movl 8(%esp),%eax
movl 0(%edx),%ecx
diff --git a/lib/libc/i386/gen/setjmp.S b/lib/libc/i386/gen/setjmp.S
index fa52b830ea1a..89efa92ccf85 100644
--- a/lib/libc/i386/gen/setjmp.S
+++ b/lib/libc/i386/gen/setjmp.S
@@ -33,12 +33,12 @@
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
- * $Id$
+ * $Id: setjmp.S,v 1.3 1995/01/23 01:27:08 davidg Exp $
*/
#if defined(LIBC_RCS) && !defined(lint)
.text
- .asciz "$Id$"
+ .asciz "$Id: setjmp.S,v 1.3 1995/01/23 01:27:08 davidg Exp $"
#endif /* LIBC_RCS and not lint */
/*
@@ -54,9 +54,17 @@
#include "DEFS.h"
#include "SYS.h"
+#ifdef _THREAD_SAFE
+ENTRY(_thread_sys_setjmp)
+#else
ENTRY(setjmp)
+#endif
pushl $0
+#ifdef _THREAD_SAFE
+ call PIC_PLT(__thread_sys_sigblock)
+#else
call PIC_PLT(_sigblock)
+#endif
popl %edx
movl 4(%esp),%ecx
movl 0(%esp),%edx
@@ -71,10 +79,18 @@ ENTRY(setjmp)
xorl %eax,%eax
ret
+#ifdef _THREAD_SAFE
+ENTRY(_thread_sys_longjmp)
+#else
ENTRY(longjmp)
+#endif
movl 4(%esp),%edx
pushl 24(%edx)
+#ifdef _THREAD_SAFE
+ call PIC_PLT(__thread_sys_sigsetmask)
+#else
call PIC_PLT(_sigsetmask) /* XXX this is not reentrant */
+#endif
popl %eax
movl 4(%esp),%edx
movl 8(%esp),%eax
diff --git a/lib/libc/i386/gen/sigsetjmp.S b/lib/libc/i386/gen/sigsetjmp.S
index 4f592a32a113..1e15101bfa33 100644
--- a/lib/libc/i386/gen/sigsetjmp.S
+++ b/lib/libc/i386/gen/sigsetjmp.S
@@ -33,12 +33,12 @@
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
- * $Id: sigsetjmp.S,v 1.3 1994/12/27 13:34:04 bde Exp $
+ * $Id: sigsetjmp.S,v 1.4 1995/01/23 01:27:10 davidg Exp $
*/
#if defined(LIBC_RCS) && !defined(lint)
.text
- .asciz "$Id: sigsetjmp.S,v 1.3 1994/12/27 13:34:04 bde Exp $"
+ .asciz "$Id: sigsetjmp.S,v 1.4 1995/01/23 01:27:10 davidg Exp $"
#endif /* LIBC_RCS and not lint */
#include "DEFS.h"
@@ -59,14 +59,22 @@
* use sigreturn() if sigreturn() works.
*/
+#ifdef _THREAD_SAFE
+ENTRY(_thread_sys_sigsetjmp)
+#else
ENTRY(sigsetjmp)
+#endif
movl 8(%esp),%eax
movl 4(%esp),%ecx
movl %eax,32(%ecx)
testl %eax,%eax
jz 1f
pushl $0
+#ifdef _THREAD_SAFE
+ call PIC_PLT(__thread_sys_sigblock)
+#else
call PIC_PLT(_sigblock)
+#endif
addl $4,%esp
movl 4(%esp),%ecx
movl %eax,24(%ecx)
@@ -81,12 +89,20 @@ ENTRY(sigsetjmp)
xorl %eax,%eax
ret
+#ifdef _THREAD_SAFE
+ENTRY(_thread_sys_siglongjmp)
+#else
ENTRY(siglongjmp)
+#endif
movl 4(%esp),%edx
cmpl $0,32(%edx)
jz 1f
pushl 24(%edx)
+#ifdef _THREAD_SAFE
+ call PIC_PLT(_thread_sys_sigsetmask)
+#else
call PIC_PLT(_sigsetmask)
+#endif
addl $4,%esp
1: movl 4(%esp),%edx
movl 8(%esp),%eax
diff --git a/lib/libc/i386/sys/Ovfork.S b/lib/libc/i386/sys/Ovfork.S
index 06e3eb6a4812..341b75c97381 100644
--- a/lib/libc/i386/sys/Ovfork.S
+++ b/lib/libc/i386/sys/Ovfork.S
@@ -33,12 +33,12 @@
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
- * $Id: Ovfork.S,v 1.1 1994/08/05 01:18:38 wollman Exp $
+ * $Id: Ovfork.S,v 1.2 1995/01/23 01:29:37 davidg Exp $
*/
#if defined(SYSLIBC_RCS) && !defined(lint)
.text
- .asciz "$Id$"
+ .asciz "$Id: Ovfork.S,v 1.2 1995/01/23 01:29:37 davidg Exp $"
#endif /* SYSLIBC_RCS and not lint */
#include "SYS.h"
@@ -63,7 +63,28 @@ vforkok:
cmpl $0,%edx /* child process? */
jne child /* yes */
jmp parent
-.globl _errno
+#ifdef _THREAD_SAFE
+ /*
+ * Threaded version using __error().
+ */
+ .globl ___error
+ .type ___error,@function
+verror:
+ pushl %eax
+#ifdef PIC
+ call PIC_PLT(___error)
+#else
+ call ___error
+#endif
+ popl %ecx
+ movl %ecx,(%eax)
+ movl $-1,%eax
+ movl $-1,%edx
+#else /* !_THREAD_SAFE */
+ /*
+ * Non-threaded version using global errno.
+ */
+ .globl _errno
verror:
#ifdef PIC
PIC_PROLOGUE
@@ -74,6 +95,7 @@ verror:
movl %eax,_errno
#endif
movl $-1,%eax
+#endif /* !_THREAD_SAFE */
jmp %ecx
child:
movl $0,%eax
diff --git a/lib/libc/i386/sys/cerror.S b/lib/libc/i386/sys/cerror.S
index 875f6db37219..2cbb0f94ab5b 100644
--- a/lib/libc/i386/sys/cerror.S
+++ b/lib/libc/i386/sys/cerror.S
@@ -33,16 +33,39 @@
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
- * $Id: cerror.S,v 1.2 1994/08/13 14:00:26 davidg Exp $
+ * $Id: cerror.S,v 1.3 1995/01/23 01:29:43 davidg Exp $
*/
#if defined(SYSLIBC_RCS) && !defined(lint)
.text
- .asciz "$Id$"
+ .asciz "$Id: cerror.S,v 1.3 1995/01/23 01:29:43 davidg Exp $"
#endif /* SYSLIBC_RCS and not lint */
#include "SYS.h"
+#ifdef _THREAD_SAFE
+ /*
+ * Threaded version using __error().
+ */
+ .globl ___error
+ .type ___error,@function
+cerror:
+ pushl %eax
+#ifdef PIC
+ call PIC_PLT(___error)
+#else
+ call ___error
+#endif
+ popl %ecx
+ movl %ecx,(%eax)
+ movl $-1,%eax
+ movl $-1,%edx
+ ret
+
+#else /* _THREAD_SAFE */
+ /*
+ * Non-threaded version using global errno.
+ */
.globl _errno
cerror:
#ifdef PIC
@@ -56,3 +79,4 @@ cerror:
movl $-1,%eax
movl $-1,%edx
ret
+#endif /* _THREAD_SAFE */
diff --git a/lib/libc/i386/sys/fork.S b/lib/libc/i386/sys/fork.S
index fe4c36d58011..567aa4c9dd39 100644
--- a/lib/libc/i386/sys/fork.S
+++ b/lib/libc/i386/sys/fork.S
@@ -33,17 +33,17 @@
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
- * $Id: fork.S,v 1.1 1994/08/05 01:18:44 wollman Exp $
+ * $Id: fork.S,v 1.2 1995/01/23 01:29:48 davidg Exp $
*/
#if defined(SYSLIBC_RCS) && !defined(lint)
.text
- .asciz "$Id$"
+ .asciz "$Id: fork.S,v 1.2 1995/01/23 01:29:48 davidg Exp $"
#endif /* SYSLIBC_RCS and not lint */
#include "SYS.h"
-SYSCALL(fork)
+PSYSCALL(fork)
cmpl $0,%edx /* parent, since %edx == 0 in parent, 1 in child */
je 1f
movl $0,%eax
diff --git a/lib/libc/i386/sys/pipe.S b/lib/libc/i386/sys/pipe.S
index cf3264c9c495..809445f0bec7 100644
--- a/lib/libc/i386/sys/pipe.S
+++ b/lib/libc/i386/sys/pipe.S
@@ -33,17 +33,17 @@
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
- * $Id: pipe.S,v 1.1 1994/08/05 01:18:46 wollman Exp $
+ * $Id: pipe.S,v 1.2 1995/01/23 01:29:57 davidg Exp $
*/
#if defined(SYSLIBC_RCS) && !defined(lint)
.text
- .asciz "$Id$"
+ .asciz "$Id: pipe.S,v 1.2 1995/01/23 01:29:57 davidg Exp $"
#endif /* SYSLIBC_RCS and not lint */
#include "SYS.h"
-SYSCALL(pipe)
+PSYSCALL(pipe)
movl 4(%esp),%ecx
movl %eax,(%ecx)
movl %edx,4(%ecx)
diff --git a/lib/libc/i386/sys/sigpending.S b/lib/libc/i386/sys/sigpending.S
index fdc1e9fb3603..dba82eef8c6f 100644
--- a/lib/libc/i386/sys/sigpending.S
+++ b/lib/libc/i386/sys/sigpending.S
@@ -33,17 +33,17 @@
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
- * $Id: sigpending.S,v 1.1 1994/08/05 01:18:51 wollman Exp $
+ * $Id: sigpending.S,v 1.2 1995/01/23 01:30:08 davidg Exp $
*/
#if defined(SYSLIBC_RCS) && !defined(lint)
.text
- .asciz "$Id$"
+ .asciz "$Id: sigpending.S,v 1.2 1995/01/23 01:30:08 davidg Exp $"
#endif /* SYSLIBC_RCS and not lint */
#include "SYS.h"
-SYSCALL(sigpending)
+PSYSCALL(sigpending)
movl 4(%esp),%ecx # fetch pointer to...
movl %eax,(%ecx) # store old mask
xorl %eax,%eax
diff --git a/lib/libc/i386/sys/sigprocmask.S b/lib/libc/i386/sys/sigprocmask.S
index 1757a3ab3944..69c50a407472 100644
--- a/lib/libc/i386/sys/sigprocmask.S
+++ b/lib/libc/i386/sys/sigprocmask.S
@@ -33,12 +33,12 @@
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
- * $Id: sigprocmask.S,v 1.1 1994/08/05 01:18:52 wollman Exp $
+ * $Id: sigprocmask.S,v 1.2 1995/01/23 01:30:11 davidg Exp $
*/
#if defined(SYSLIBC_RCS) && !defined(lint)
.text
- .asciz "$Id$"
+ .asciz "$Id: sigprocmask.S,v 1.2 1995/01/23 01:30:11 davidg Exp $"
#endif /* SYSLIBC_RCS and not lint */
#include "SYS.h"
@@ -46,7 +46,11 @@
err:
jmp cerror
+#ifdef _THREAD_SAFE
+ENTRY(_thread_sys_sigprocmask)
+#else
ENTRY(sigprocmask)
+#endif
movl 8(%esp),%ecx # fetch new sigset pointer
cmpl $0,%ecx # check new sigset pointer
jne 1f # if not null, indirect
diff --git a/lib/libc/i386/sys/sigreturn.S b/lib/libc/i386/sys/sigreturn.S
index ac0ffd653471..6f3f571c616e 100644
--- a/lib/libc/i386/sys/sigreturn.S
+++ b/lib/libc/i386/sys/sigreturn.S
@@ -33,12 +33,12 @@
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
- * $Id: sigreturn.S,v 1.1 1994/08/05 01:18:53 wollman Exp $
+ * $Id: sigreturn.S,v 1.2 1995/01/23 01:30:16 davidg Exp $
*/
#if defined(SYSLIBC_RCS) && !defined(lint)
.text
- .asciz "$Id$"
+ .asciz "$Id: sigreturn.S,v 1.2 1995/01/23 01:30:16 davidg Exp $"
#endif /* SYSLIBC_RCS and not lint */
#include "SYS.h"
@@ -53,5 +53,5 @@
.data; 1:; .long 0; .text; movl $1b,%eax; call mcount; popa ; nop
#endif /* PROF */
-SYSCALL(sigreturn)
+PSYSCALL(sigreturn)
ret
diff --git a/lib/libc/i386/sys/sigsuspend.S b/lib/libc/i386/sys/sigsuspend.S
index a72154a38610..4d70ea693d9b 100644
--- a/lib/libc/i386/sys/sigsuspend.S
+++ b/lib/libc/i386/sys/sigsuspend.S
@@ -33,12 +33,12 @@
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
- * $Id$
+ * $Id: sigsuspend.S,v 1.2 1995/01/23 01:30:20 davidg Exp $
*/
#if defined(SYSLIBC_RCS) && !defined(lint)
.text
- .asciz "$Id$"
+ .asciz "$Id: sigsuspend.S,v 1.2 1995/01/23 01:30:20 davidg Exp $"
#endif /* SYSLIBC_RCS and not lint */
#include "SYS.h"
@@ -46,7 +46,11 @@
err:
jmp cerror
+#ifdef _THREAD_SAFE
+ENTRY(_thread_sys_sigsuspend)
+#else
ENTRY(sigsuspend)
+#endif
movl 4(%esp),%eax # fetch mask arg
movl (%eax),%eax # indirect to mask arg
movl %eax,4(%esp)
diff --git a/lib/libc/stdio/clrerr.c b/lib/libc/stdio/clrerr.c
index de4526e0a7dc..a597b7b0baf3 100644
--- a/lib/libc/stdio/clrerr.c
+++ b/lib/libc/stdio/clrerr.c
@@ -40,10 +40,20 @@ static char sccsid[] = "@(#)clrerr.c 8.1 (Berkeley) 6/4/93";
#include <stdio.h>
#undef clearerr
+#ifdef _THREAD_SAFE
+#include <pthread.h>
+#include "pthread_private.h"
+#endif
void
clearerr(fp)
FILE *fp;
{
+#ifdef _THREAD_SAFE
+ _thread_flockfile(fp,__FILE__,__LINE__);
+#endif
__sclearerr(fp);
+#ifdef _THREAD_SAFE
+ _thread_funlockfile(fp);
+#endif
}
diff --git a/lib/libc/stdio/fclose.c b/lib/libc/stdio/fclose.c
index 8315c3cf41ea..be9210801b50 100644
--- a/lib/libc/stdio/fclose.c
+++ b/lib/libc/stdio/fclose.c
@@ -42,7 +42,12 @@ static char sccsid[] = "@(#)fclose.c 8.1 (Berkeley) 6/4/93";
#include <stdio.h>
#include <stdlib.h>
#include "local.h"
+#ifdef _THREAD_SAFE
+#include <pthread.h>
+#include "pthread_private.h"
+#endif
+int
fclose(fp)
register FILE *fp;
{
@@ -52,6 +57,9 @@ fclose(fp)
errno = EBADF;
return (EOF);
}
+#ifdef _THREAD_SAFE
+ _thread_flockfile(fp,__FILE__,__LINE__);
+#endif
r = fp->_flags & __SWR ? __sflush(fp) : 0;
if (fp->_close != NULL && (*fp->_close)(fp->_cookie) < 0)
r = EOF;
@@ -61,7 +69,11 @@ fclose(fp)
FREEUB(fp);
if (HASLB(fp))
FREELB(fp);
+#ifdef _THREAD_SAFE
+ _thread_funlockfile(fp);
+#endif
fp->_flags = 0; /* Release this FILE for reuse. */
+ fp->_file = -1;
fp->_r = fp->_w = 0; /* Mess up if reaccessed. */
return (r);
}
diff --git a/lib/libc/stdio/fflush.c b/lib/libc/stdio/fflush.c
index 4a5cf0f43084..fce893292e60 100644
--- a/lib/libc/stdio/fflush.c
+++ b/lib/libc/stdio/fflush.c
@@ -41,21 +41,36 @@ static char sccsid[] = "@(#)fflush.c 8.1 (Berkeley) 6/4/93";
#include <errno.h>
#include <stdio.h>
#include "local.h"
+#ifdef _THREAD_SAFE
+#include <pthread.h>
+#include "pthread_private.h"
+#endif
/* Flush a single file, or (if fp is NULL) all files. */
+int
fflush(fp)
register FILE *fp;
{
+ int retval;
if (fp == NULL)
return (_fwalk(__sflush));
+#ifdef _THREAD_SAFE
+ _thread_flockfile(fp,__FILE__,__LINE__);
+#endif
if ((fp->_flags & (__SWR | __SRW)) == 0) {
errno = EBADF;
- return (EOF);
+ retval = EOF;
+ } else {
+ retval = __sflush(fp);
}
- return (__sflush(fp));
+#ifdef _THREAD_SAFE
+ _thread_funlockfile(fp);
+#endif
+ return (retval);
}
+int
__sflush(fp)
register FILE *fp;
{
diff --git a/lib/libc/stdio/fgetc.c b/lib/libc/stdio/fgetc.c
index 800846cda974..7e2738f6c48f 100644
--- a/lib/libc/stdio/fgetc.c
+++ b/lib/libc/stdio/fgetc.c
@@ -39,9 +39,22 @@ static char sccsid[] = "@(#)fgetc.c 8.1 (Berkeley) 6/4/93";
#endif /* LIBC_SCCS and not lint */
#include <stdio.h>
+#ifdef _THREAD_SAFE
+#include <pthread.h>
+#include "pthread_private.h"
+#endif
+int
fgetc(fp)
FILE *fp;
{
- return (__sgetc(fp));
+ int retval;
+#ifdef _THREAD_SAFE
+ _thread_flockfile(fp,__FILE__,__LINE__);
+#endif
+ retval = __sgetc(fp);
+#ifdef _THREAD_SAFE
+ _thread_funlockfile(fp);
+#endif
+ return (retval);
}
diff --git a/lib/libc/stdio/fgetpos.c b/lib/libc/stdio/fgetpos.c
index 1f4ec1de23d6..4ac0be4ed3e2 100644
--- a/lib/libc/stdio/fgetpos.c
+++ b/lib/libc/stdio/fgetpos.c
@@ -39,10 +39,23 @@ static char sccsid[] = "@(#)fgetpos.c 8.1 (Berkeley) 6/4/93";
#endif /* LIBC_SCCS and not lint */
#include <stdio.h>
+#ifdef _THREAD_SAFE
+#include <pthread.h>
+#include "pthread_private.h"
+#endif
+int
fgetpos(fp, pos)
FILE *fp;
fpos_t *pos;
{
- return((*pos = ftell(fp)) == (fpos_t)-1);
+ int retval;
+#ifdef _THREAD_SAFE
+ _thread_flockfile(fp,__FILE__,__LINE__);
+#endif
+ retval = (*pos = ftell(fp)) == (fpos_t)-1;
+#ifdef _THREAD_SAFE
+ _thread_funlockfile(fp);
+#endif
+ return(retval);
}
diff --git a/lib/libc/stdio/fgets.c b/lib/libc/stdio/fgets.c
index 09f68772818d..c4782674943a 100644
--- a/lib/libc/stdio/fgets.c
+++ b/lib/libc/stdio/fgets.c
@@ -40,6 +40,11 @@ static char sccsid[] = "@(#)fgets.c 8.2 (Berkeley) 12/22/93";
#include <stdio.h>
#include <string.h>
+#include "local.h"
+#ifdef _THREAD_SAFE
+#include <pthread.h>
+#include "pthread_private.h"
+#endif
/*
* Read at most n-1 characters from the given file.
@@ -59,6 +64,9 @@ fgets(buf, n, fp)
if (n == 0) /* sanity check */
return (NULL);
+#ifdef _THREAD_SAFE
+ _thread_flockfile(fp,__FILE__,__LINE__);
+#endif
s = buf;
n--; /* leave space for NUL */
while (n != 0) {
@@ -68,8 +76,12 @@ fgets(buf, n, fp)
if ((len = fp->_r) <= 0) {
if (__srefill(fp)) {
/* EOF/error: stop with partial or no line */
- if (s == buf)
+ if (s == buf) {
+#ifdef _THREAD_SAFE
+ _thread_funlockfile(fp);
+#endif
return (NULL);
+ }
break;
}
len = fp->_r;
@@ -91,6 +103,9 @@ fgets(buf, n, fp)
fp->_p = t;
(void)memcpy((void *)s, (void *)p, len);
s[len] = 0;
+#ifdef _THREAD_SAFE
+ _thread_funlockfile(fp);
+#endif
return (buf);
}
fp->_r -= len;
@@ -100,5 +115,8 @@ fgets(buf, n, fp)
n -= len;
}
*s = 0;
+#ifdef _THREAD_SAFE
+ _thread_funlockfile(fp);
+#endif
return (buf);
}
diff --git a/lib/libc/stdio/fpurge.c b/lib/libc/stdio/fpurge.c
index 3bee5132aa57..7cf54ffb2e38 100644
--- a/lib/libc/stdio/fpurge.c
+++ b/lib/libc/stdio/fpurge.c
@@ -42,6 +42,10 @@ static char sccsid[] = "@(#)fpurge.c 8.1 (Berkeley) 6/4/93";
#include <stdio.h>
#include <stdlib.h>
#include "local.h"
+#ifdef _THREAD_SAFE
+#include <pthread.h>
+#include "pthread_private.h"
+#endif
/*
* fpurge: like fflush, but without writing anything: leave the
@@ -51,15 +55,23 @@ int
fpurge(fp)
register FILE *fp;
{
+ int retval;
+#ifdef _THREAD_SAFE
+ _thread_flockfile(fp,__FILE__,__LINE__);
+#endif
if (!fp->_flags) {
errno = EBADF;
- return(EOF);
+ retval = EOF;
+ } else {
+ if (HASUB(fp))
+ FREEUB(fp);
+ fp->_p = fp->_bf._base;
+ fp->_r = 0;
+ fp->_w = fp->_flags & (__SLBF|__SNBF) ? 0 : fp->_bf._size;
+ retval = 0;
}
-
- if (HASUB(fp))
- FREEUB(fp);
- fp->_p = fp->_bf._base;
- fp->_r = 0;
- fp->_w = fp->_flags & (__SLBF|__SNBF) ? 0 : fp->_bf._size;
- return (0);
+#ifdef _THREAD_SAFE
+ _thread_funlockfile(fp);
+#endif
+ return (retval);
}
diff --git a/lib/libc/stdio/fputc.c b/lib/libc/stdio/fputc.c
index c86f71161fc4..09b55d59a58e 100644
--- a/lib/libc/stdio/fputc.c
+++ b/lib/libc/stdio/fputc.c
@@ -39,10 +39,23 @@ static char sccsid[] = "@(#)fputc.c 8.1 (Berkeley) 6/4/93";
#endif /* LIBC_SCCS and not lint */
#include <stdio.h>
+#ifdef _THREAD_SAFE
+#include <pthread.h>
+#include "pthread_private.h"
+#endif
+int
fputc(c, fp)
int c;
register FILE *fp;
{
- return (putc(c, fp));
+ int retval;
+#ifdef _THREAD_SAFE
+ _thread_flockfile(fp,__FILE__,__LINE__);
+#endif
+ retval = putc(c, fp);
+#ifdef _THREAD_SAFE
+ _thread_funlockfile(fp);
+#endif
+ return (retval);
}
diff --git a/lib/libc/stdio/fputs.c b/lib/libc/stdio/fputs.c
index 9f9be2e2feee..92fcc303a690 100644
--- a/lib/libc/stdio/fputs.c
+++ b/lib/libc/stdio/fputs.c
@@ -41,14 +41,20 @@ static char sccsid[] = "@(#)fputs.c 8.1 (Berkeley) 6/4/93";
#include <stdio.h>
#include <string.h>
#include "fvwrite.h"
+#ifdef _THREAD_SAFE
+#include <pthread.h>
+#include "pthread_private.h"
+#endif
/*
* Write the given string to the given file.
*/
+int
fputs(s, fp)
const char *s;
FILE *fp;
{
+ int retval;
struct __suio uio;
struct __siov iov;
@@ -56,5 +62,12 @@ fputs(s, fp)
iov.iov_len = uio.uio_resid = strlen(s);
uio.uio_iov = &iov;
uio.uio_iovcnt = 1;
- return (__sfvwrite(fp, &uio));
+#ifdef _THREAD_SAFE
+ _thread_flockfile(fp,__FILE__,__LINE__);
+#endif
+ retval = __sfvwrite(fp, &uio);
+#ifdef _THREAD_SAFE
+ _thread_funlockfile(fp);
+#endif
+ return (retval);
}
diff --git a/lib/libc/stdio/fread.c b/lib/libc/stdio/fread.c
index 22436ec8dcc1..7132e8544c01 100644
--- a/lib/libc/stdio/fread.c
+++ b/lib/libc/stdio/fread.c
@@ -40,6 +40,11 @@ static char sccsid[] = "@(#)fread.c 8.2 (Berkeley) 12/11/93";
#include <stdio.h>
#include <string.h>
+#include "local.h"
+#ifdef _THREAD_SAFE
+#include <pthread.h>
+#include "pthread_private.h"
+#endif
size_t
fread(buf, size, count, fp)
@@ -59,6 +64,9 @@ fread(buf, size, count, fp)
*/
if ((resid = count * size) == 0)
return (0);
+#ifdef _THREAD_SAFE
+ _thread_flockfile(fp,__FILE__,__LINE__);
+#endif
if (fp->_r < 0)
fp->_r = 0;
total = resid;
@@ -77,5 +85,8 @@ fread(buf, size, count, fp)
(void)memcpy((void *)p, (void *)fp->_p, resid);
fp->_r -= resid;
fp->_p += resid;
+#ifdef _THREAD_SAFE
+ _thread_funlockfile(fp);
+#endif
return (count);
}
diff --git a/lib/libc/stdio/fscanf.c b/lib/libc/stdio/fscanf.c
index f0e726af8490..bbb3155f94ad 100644
--- a/lib/libc/stdio/fscanf.c
+++ b/lib/libc/stdio/fscanf.c
@@ -44,14 +44,20 @@ static char sccsid[] = "@(#)fscanf.c 8.1 (Berkeley) 6/4/93";
#else
#include <varargs.h>
#endif
+#ifdef _THREAD_SAFE
+#include <pthread.h>
+#include "pthread_private.h"
+#endif
#if __STDC__
+int
fscanf(FILE *fp, char const *fmt, ...) {
int ret;
va_list ap;
va_start(ap, fmt);
#else
+int
fscanf(fp, fmt, va_alist)
FILE *fp;
char *fmt;
@@ -62,7 +68,13 @@ fscanf(fp, fmt, va_alist)
va_start(ap);
#endif
+#ifdef _THREAD_SAFE
+ _thread_flockfile(fp,__FILE__,__LINE__);
+#endif
ret = __svfscanf(fp, fmt, ap);
va_end(ap);
+#ifdef _THREAD_SAFE
+ _thread_funlockfile(fp);
+#endif
return (ret);
}
diff --git a/lib/libc/stdio/fseek.c b/lib/libc/stdio/fseek.c
index 9cb04ad03787..1e99de9db2cc 100644
--- a/lib/libc/stdio/fseek.c
+++ b/lib/libc/stdio/fseek.c
@@ -45,6 +45,10 @@ static char sccsid[] = "@(#)fseek.c 8.3 (Berkeley) 1/2/94";
#include <stdlib.h>
#include <errno.h>
#include "local.h"
+#ifdef _THREAD_SAFE
+#include <pthread.h>
+#include "pthread_private.h"
+#endif
#define POS_ERR (-(fpos_t)1)
@@ -68,6 +72,9 @@ fseek(fp, offset, whence)
if (!__sdidinit)
__sinit();
+#ifdef _THREAD_SAFE
+ _thread_flockfile(fp,__FILE__,__LINE__);
+#endif
/*
* Have to be able to seek.
*/
@@ -92,8 +99,12 @@ fseek(fp, offset, whence)
curoff = fp->_offset;
else {
curoff = (*seekfn)(fp->_cookie, (fpos_t)0, SEEK_CUR);
- if (curoff == -1L)
+ if (curoff == -1L) {
+#ifdef _THREAD_SAFE
+ _thread_funlockfile(fp);
+#endif
return (EOF);
+ }
}
if (fp->_flags & __SRD) {
curoff -= fp->_r;
@@ -115,6 +126,9 @@ fseek(fp, offset, whence)
default:
errno = EINVAL;
+#ifdef _THREAD_SAFE
+ _thread_funlockfile(fp);
+#endif
return (EOF);
}
@@ -198,6 +212,9 @@ fseek(fp, offset, whence)
if (HASUB(fp))
FREEUB(fp);
fp->_flags &= ~__SEOF;
+#ifdef _THREAD_SAFE
+ _thread_funlockfile(fp);
+#endif
return (0);
}
@@ -224,6 +241,9 @@ fseek(fp, offset, whence)
fp->_p += n;
fp->_r -= n;
}
+#ifdef _THREAD_SAFE
+ _thread_funlockfile(fp);
+#endif
return (0);
/*
@@ -233,6 +253,9 @@ fseek(fp, offset, whence)
dumb:
if (__sflush(fp) ||
(*seekfn)(fp->_cookie, (fpos_t)offset, whence) == POS_ERR) {
+#ifdef _THREAD_SAFE
+ _thread_funlockfile(fp);
+#endif
return (EOF);
}
/* success: clear EOF indicator and discard ungetc() data */
@@ -242,5 +265,8 @@ dumb:
fp->_r = 0;
/* fp->_w = 0; */ /* unnecessary (I think...) */
fp->_flags &= ~__SEOF;
+#ifdef _THREAD_SAFE
+ _thread_funlockfile(fp);
+#endif
return (0);
}
diff --git a/lib/libc/stdio/ftell.c b/lib/libc/stdio/ftell.c
index 724e5437812b..271490aa1b5d 100644
--- a/lib/libc/stdio/ftell.c
+++ b/lib/libc/stdio/ftell.c
@@ -41,6 +41,10 @@ static char sccsid[] = "@(#)ftell.c 8.1 (Berkeley) 6/4/93";
#include <stdio.h>
#include <errno.h>
#include "local.h"
+#ifdef _THREAD_SAFE
+#include <pthread.h>
+#include "pthread_private.h"
+#endif
/*
* ftell: return current offset.
@@ -56,6 +60,9 @@ ftell(fp)
return (-1L);
}
+#ifdef _THREAD_SAFE
+ _thread_flockfile((FILE *) fp,__FILE__,__LINE__);
+#endif
/*
* Find offset of underlying I/O object, then
* adjust for buffered bytes.
@@ -64,8 +71,12 @@ ftell(fp)
pos = fp->_offset;
else {
pos = (*fp->_seek)(fp->_cookie, (fpos_t)0, SEEK_CUR);
- if (pos == -1L)
+ if (pos == -1L) {
+#ifdef _THREAD_SAFE
+ _thread_funlockfile((FILE *) fp);
+#endif
return (pos);
+ }
}
if (fp->_flags & __SRD) {
/*
@@ -84,5 +95,8 @@ ftell(fp)
*/
pos += fp->_p - fp->_bf._base;
}
+#ifdef _THREAD_SAFE
+ _thread_funlockfile((FILE *) fp);
+#endif
return (pos);
}
diff --git a/lib/libc/stdio/fwrite.c b/lib/libc/stdio/fwrite.c
index dbc2e978d7d0..7efb0ac4e277 100644
--- a/lib/libc/stdio/fwrite.c
+++ b/lib/libc/stdio/fwrite.c
@@ -41,6 +41,10 @@ static char sccsid[] = "@(#)fwrite.c 8.1 (Berkeley) 6/4/93";
#include <stdio.h>
#include "local.h"
#include "fvwrite.h"
+#ifdef _THREAD_SAFE
+#include <pthread.h>
+#include "pthread_private.h"
+#endif
/*
* Write `count' objects (each size `size') from memory to the given file.
@@ -61,12 +65,18 @@ fwrite(buf, size, count, fp)
uio.uio_iov = &iov;
uio.uio_iovcnt = 1;
+#ifdef _THREAD_SAFE
+ _thread_flockfile(fp,__FILE__,__LINE__);
+#endif
/*
* The usual case is success (__sfvwrite returns 0);
* skip the divide if this happens, since divides are
* generally slow and since this occurs whenever size==0.
*/
- if (__sfvwrite(fp, &uio) == 0)
- return (count);
- return ((n - uio.uio_resid) / size);
+ if (__sfvwrite(fp, &uio) != 0)
+ count = (n - uio.uio_resid) / size;
+#ifdef _THREAD_SAFE
+ _thread_funlockfile(fp);
+#endif
+ return (count);
}
diff --git a/lib/libc/stdio/getc.c b/lib/libc/stdio/getc.c
index 1e900cd6e64a..c0726ee2db64 100644
--- a/lib/libc/stdio/getc.c
+++ b/lib/libc/stdio/getc.c
@@ -39,14 +39,27 @@ static char sccsid[] = "@(#)getc.c 8.1 (Berkeley) 6/4/93";
#endif /* LIBC_SCCS and not lint */
#include <stdio.h>
+#ifdef _THREAD_SAFE
+#include <pthread.h>
+#include "pthread_private.h"
+#endif
/*
* A subroutine version of the macro getc.
*/
#undef getc
+int
getc(fp)
register FILE *fp;
{
- return (__sgetc(fp));
+ int retval;
+#ifdef _THREAD_SAFE
+ _thread_flockfile(fp,__FILE__,__LINE__);
+#endif
+ retval = __sgetc(fp);
+#ifdef _THREAD_SAFE
+ _thread_funlockfile(fp);
+#endif
+ return (retval);
}
diff --git a/lib/libc/stdio/getchar.c b/lib/libc/stdio/getchar.c
index 20e52b79193e..7aeef8af645f 100644
--- a/lib/libc/stdio/getchar.c
+++ b/lib/libc/stdio/getchar.c
@@ -42,10 +42,23 @@ static char sccsid[] = "@(#)getchar.c 8.1 (Berkeley) 6/4/93";
* A subroutine version of the macro getchar.
*/
#include <stdio.h>
+#ifdef _THREAD_SAFE
+#include <pthread.h>
+#include "pthread_private.h"
+#endif
#undef getchar
+int
getchar()
{
- return (getc(stdin));
+ int retval;
+#ifdef _THREAD_SAFE
+ _thread_flockfile(stdin,__FILE__,__LINE__);
+#endif
+ retval = getc(stdin);
+#ifdef _THREAD_SAFE
+ _thread_funlockfile(stdin);
+#endif
+ return (retval);
}
diff --git a/lib/libc/stdio/putc.c b/lib/libc/stdio/putc.c
index c18353b7044a..f1d42b11454b 100644
--- a/lib/libc/stdio/putc.c
+++ b/lib/libc/stdio/putc.c
@@ -39,15 +39,28 @@ static char sccsid[] = "@(#)putc.c 8.1 (Berkeley) 6/4/93";
#endif /* LIBC_SCCS and not lint */
#include <stdio.h>
+#ifdef _THREAD_SAFE
+#include <pthread.h>
+#include "pthread_private.h"
+#endif
/*
* A subroutine version of the macro putc.
*/
#undef putc
+int
putc(c, fp)
int c;
register FILE *fp;
{
- return (__sputc(c, fp));
+ int retval;
+#ifdef _THREAD_SAFE
+ _thread_flockfile(fp,__FILE__,__LINE__);
+#endif
+ retval = __sputc(c, fp);
+#ifdef _THREAD_SAFE
+ _thread_funlockfile(fp);
+#endif
+ return (retval);
}
diff --git a/lib/libc/stdio/putchar.c b/lib/libc/stdio/putchar.c
index 036b8970772c..5e04a6c72f2c 100644
--- a/lib/libc/stdio/putchar.c
+++ b/lib/libc/stdio/putchar.c
@@ -39,16 +39,29 @@ static char sccsid[] = "@(#)putchar.c 8.1 (Berkeley) 6/4/93";
#endif /* LIBC_SCCS and not lint */
#include <stdio.h>
+#ifdef _THREAD_SAFE
+#include <pthread.h>
+#include "pthread_private.h"
+#endif
#undef putchar
/*
* A subroutine version of the macro putchar
*/
+int
putchar(c)
int c;
{
+ int retval;
register FILE *so = stdout;
- return (__sputc(c, so));
+#ifdef _THREAD_SAFE
+ _thread_flockfile(so,__FILE__,__LINE__);
+#endif
+ retval = __sputc(c, so);
+#ifdef _THREAD_SAFE
+ _thread_funlockfile(so);
+#endif
+ return (retval);
}
diff --git a/lib/libc/stdio/puts.c b/lib/libc/stdio/puts.c
index 96a81842b86f..e8a35c533a51 100644
--- a/lib/libc/stdio/puts.c
+++ b/lib/libc/stdio/puts.c
@@ -41,13 +41,19 @@ static char sccsid[] = "@(#)puts.c 8.1 (Berkeley) 6/4/93";
#include <stdio.h>
#include <string.h>
#include "fvwrite.h"
+#ifdef _THREAD_SAFE
+#include <pthread.h>
+#include "pthread_private.h"
+#endif
/*
* Write the given string to stdout, appending a newline.
*/
+int
puts(s)
char const *s;
{
+ int retval;
size_t c = strlen(s);
struct __suio uio;
struct __siov iov[2];
@@ -59,5 +65,12 @@ puts(s)
uio.uio_resid = c + 1;
uio.uio_iov = &iov[0];
uio.uio_iovcnt = 2;
- return (__sfvwrite(stdout, &uio) ? EOF : '\n');
+#ifdef _THREAD_SAFE
+ _thread_flockfile(stdout,__FILE__,__LINE__);
+#endif
+ retval = __sfvwrite(stdout, &uio) ? EOF : '\n';
+#ifdef _THREAD_SAFE
+ _thread_funlockfile(stdout);
+#endif
+ return (retval);
}
diff --git a/lib/libc/stdio/putw.c b/lib/libc/stdio/putw.c
index 4ba898207f1e..604bed0b7925 100644
--- a/lib/libc/stdio/putw.c
+++ b/lib/libc/stdio/putw.c
@@ -40,11 +40,17 @@ static char sccsid[] = "@(#)putw.c 8.1 (Berkeley) 6/4/93";
#include <stdio.h>
#include "fvwrite.h"
+#ifdef _THREAD_SAFE
+#include <pthread.h>
+#include "pthread_private.h"
+#endif
+int
putw(w, fp)
int w;
FILE *fp;
{
+ int retval;
struct __suio uio;
struct __siov iov;
@@ -52,5 +58,12 @@ putw(w, fp)
iov.iov_len = uio.uio_resid = sizeof(w);
uio.uio_iov = &iov;
uio.uio_iovcnt = 1;
- return (__sfvwrite(fp, &uio));
+#ifdef _THREAD_SAFE
+ _thread_flockfile(fp,__FILE__,__LINE__);
+#endif
+ retval = __sfvwrite(fp, &uio);
+#ifdef _THREAD_SAFE
+ _thread_funlockfile(fp);
+#endif
+ return (retval);
}
diff --git a/lib/libc/stdio/rewind.c b/lib/libc/stdio/rewind.c
index 4f8391b5030f..f20f6197f977 100644
--- a/lib/libc/stdio/rewind.c
+++ b/lib/libc/stdio/rewind.c
@@ -40,12 +40,22 @@ static char sccsid[] = "@(#)rewind.c 8.1 (Berkeley) 6/4/93";
#include <errno.h>
#include <stdio.h>
+#ifdef _THREAD_SAFE
+#include <pthread.h>
+#include "pthread_private.h"
+#endif
void
rewind(fp)
register FILE *fp;
{
+#ifdef _THREAD_SAFE
+ _thread_flockfile(fp,__FILE__,__LINE__);
+#endif
(void) fseek(fp, 0L, SEEK_SET);
clearerr(fp);
+#ifdef _THREAD_SAFE
+ _thread_funlockfile(fp);
+#endif
errno = 0; /* not required, but seems reasonable */
}
diff --git a/lib/libc/stdio/scanf.c b/lib/libc/stdio/scanf.c
index d36b13a9ed55..5faf018711d3 100644
--- a/lib/libc/stdio/scanf.c
+++ b/lib/libc/stdio/scanf.c
@@ -44,10 +44,16 @@ static char sccsid[] = "@(#)scanf.c 8.1 (Berkeley) 6/4/93";
#else
#include <varargs.h>
#endif
+#ifdef _THREAD_SAFE
+#include <pthread.h>
+#include "pthread_private.h"
+#endif
#if __STDC__
+int
scanf(char const *fmt, ...)
#else
+int
scanf(fmt, va_alist)
char *fmt;
va_dcl
@@ -61,7 +67,13 @@ scanf(fmt, va_alist)
#else
va_start(ap);
#endif
+#ifdef _THREAD_SAFE
+ _thread_flockfile(stdin,__FILE__,__LINE__);
+#endif
ret = __svfscanf(stdin, fmt, ap);
va_end(ap);
+#ifdef _THREAD_SAFE
+ _thread_funlockfile(stdin);
+#endif
return (ret);
}
diff --git a/lib/libc/stdio/setvbuf.c b/lib/libc/stdio/setvbuf.c
index 867f9b4951f6..c6c037d7e293 100644
--- a/lib/libc/stdio/setvbuf.c
+++ b/lib/libc/stdio/setvbuf.c
@@ -41,11 +41,16 @@ static char sccsid[] = "@(#)setvbuf.c 8.2 (Berkeley) 11/16/93";
#include <stdio.h>
#include <stdlib.h>
#include "local.h"
+#ifdef _THREAD_SAFE
+#include <pthread.h>
+#include "pthread_private.h"
+#endif
/*
* Set one of the three kinds of buffering, optionally including
* a buffer.
*/
+int
setvbuf(fp, buf, mode, size)
register FILE *fp;
char *buf;
@@ -65,6 +70,9 @@ setvbuf(fp, buf, mode, size)
if ((mode != _IOFBF && mode != _IOLBF) || (int)size < 0)
return (EOF);
+#ifdef _THREAD_SAFE
+ _thread_flockfile(fp,__FILE__,__LINE__);
+#endif
/*
* Write current buffer, if any. Discard unread input (including
* ungetc data), cancel line buffering, and free old buffer if
@@ -116,6 +124,9 @@ nbf:
fp->_w = 0;
fp->_bf._base = fp->_p = fp->_nbuf;
fp->_bf._size = 1;
+#ifdef _THREAD_SAFE
+ _thread_funlockfile(fp);
+#endif
return (ret);
}
flags |= __SMBF;
@@ -156,5 +167,8 @@ nbf:
}
__cleanup = _cleanup;
+#ifdef _THREAD_SAFE
+ _thread_funlockfile(fp);
+#endif
return (ret);
}
diff --git a/lib/libc/stdio/snprintf.c b/lib/libc/stdio/snprintf.c
index 3c3cf7d8169b..82fad1a75904 100644
--- a/lib/libc/stdio/snprintf.c
+++ b/lib/libc/stdio/snprintf.c
@@ -46,8 +46,10 @@ static char sccsid[] = "@(#)snprintf.c 8.1 (Berkeley) 6/4/93";
#endif
#if __STDC__
+int
snprintf(char *str, size_t n, char const *fmt, ...)
#else
+int
snprintf(str, n, fmt, va_alist)
char *str;
size_t n;
@@ -66,6 +68,7 @@ snprintf(str, n, fmt, va_alist)
#else
va_start(ap);
#endif
+ f._file = -1;
f._flags = __SWR | __SSTR;
f._bf._base = f._p = (unsigned char *)str;
f._bf._size = f._w = n - 1;
diff --git a/lib/libc/stdio/sprintf.c b/lib/libc/stdio/sprintf.c
index 254064fabd54..e71f7d091bc2 100644
--- a/lib/libc/stdio/sprintf.c
+++ b/lib/libc/stdio/sprintf.c
@@ -48,8 +48,10 @@ static char sccsid[] = "@(#)sprintf.c 8.1 (Berkeley) 6/4/93";
#include "local.h"
#if __STDC__
+int
sprintf(char *str, char const *fmt, ...)
#else
+int
sprintf(str, fmt, va_alist)
char *str;
char *fmt;
@@ -60,6 +62,7 @@ sprintf(str, fmt, va_alist)
va_list ap;
FILE f;
+ f._file = -1;
f._flags = __SWR | __SSTR;
f._bf._base = f._p = (unsigned char *)str;
f._bf._size = f._w = INT_MAX;
diff --git a/lib/libc/stdio/sscanf.c b/lib/libc/stdio/sscanf.c
index bb7274437802..dc96312a5635 100644
--- a/lib/libc/stdio/sscanf.c
+++ b/lib/libc/stdio/sscanf.c
@@ -59,8 +59,10 @@ eofread(cookie, buf, len)
}
#if __STDC__
+int
sscanf(const char *str, char const *fmt, ...)
#else
+int
sscanf(str, fmt, va_alist)
char *str;
char *fmt;
@@ -71,6 +73,7 @@ sscanf(str, fmt, va_alist)
va_list ap;
FILE f;
+ f._file = -1;
f._flags = __SRD;
f._bf._base = f._p = (unsigned char *)str;
f._bf._size = f._r = strlen(str);
diff --git a/lib/libc/stdio/ungetc.c b/lib/libc/stdio/ungetc.c
index deaed759992f..25f59d7420fb 100644
--- a/lib/libc/stdio/ungetc.c
+++ b/lib/libc/stdio/ungetc.c
@@ -42,6 +42,10 @@ static char sccsid[] = "@(#)ungetc.c 8.2 (Berkeley) 11/3/93";
#include <stdlib.h>
#include <string.h>
#include "local.h"
+#ifdef _THREAD_SAFE
+#include <pthread.h>
+#include "pthread_private.h"
+#endif
/*
* Expand the ungetc buffer `in place'. That is, adjust fp->_p when
@@ -49,7 +53,7 @@ static char sccsid[] = "@(#)ungetc.c 8.2 (Berkeley) 11/3/93";
* and move the bytes in the buffer around as necessary so that they
* are all at the end (stack-style).
*/
-static
+static int
__submore(fp)
register FILE *fp;
{
@@ -82,6 +86,7 @@ __submore(fp)
return (0);
}
+int
ungetc(c, fp)
int c;
register FILE *fp;
@@ -90,16 +95,27 @@ ungetc(c, fp)
return (EOF);
if (!__sdidinit)
__sinit();
+#ifdef _THREAD_SAFE
+ _thread_flockfile(fp,__FILE__,__LINE__);
+#endif
if ((fp->_flags & __SRD) == 0) {
/*
* Not already reading: no good unless reading-and-writing.
* Otherwise, flush any current write stuff.
*/
- if ((fp->_flags & __SRW) == 0)
+ if ((fp->_flags & __SRW) == 0) {
+#ifdef _THREAD_SAFE
+ _thread_funlockfile(fp);
+#endif
return (EOF);
+ }
if (fp->_flags & __SWR) {
- if (__sflush(fp))
+ if (__sflush(fp)) {
+#ifdef _THREAD_SAFE
+ _thread_funlockfile(fp);
+#endif
return (EOF);
+ }
fp->_flags &= ~__SWR;
fp->_w = 0;
fp->_lbfsize = 0;
@@ -113,10 +129,17 @@ ungetc(c, fp)
* This may require expanding the current ungetc buffer.
*/
if (HASUB(fp)) {
- if (fp->_r >= fp->_ub._size && __submore(fp))
+ if (fp->_r >= fp->_ub._size && __submore(fp)) {
+#ifdef _THREAD_SAFE
+ _thread_funlockfile(fp);
+#endif
return (EOF);
+ }
*--fp->_p = c;
fp->_r++;
+#ifdef _THREAD_SAFE
+ _thread_funlockfile(fp);
+#endif
return (c);
}
fp->_flags &= ~__SEOF;
@@ -130,6 +153,9 @@ ungetc(c, fp)
fp->_p[-1] == c) {
fp->_p--;
fp->_r++;
+#ifdef _THREAD_SAFE
+ _thread_funlockfile(fp);
+#endif
return (c);
}
@@ -144,5 +170,8 @@ ungetc(c, fp)
fp->_ubuf[sizeof(fp->_ubuf) - 1] = c;
fp->_p = &fp->_ubuf[sizeof(fp->_ubuf) - 1];
fp->_r = 1;
+#ifdef _THREAD_SAFE
+ _thread_funlockfile(fp);
+#endif
return (c);
}
diff --git a/lib/libc/stdio/vfprintf.c b/lib/libc/stdio/vfprintf.c
index f53db612ff60..3c3d4d3d718e 100644
--- a/lib/libc/stdio/vfprintf.c
+++ b/lib/libc/stdio/vfprintf.c
@@ -59,6 +59,10 @@ static char sccsid[] = "@(#)vfprintf.c 8.1 (Berkeley) 6/4/93";
#include "local.h"
#include "fvwrite.h"
+#ifdef _THREAD_SAFE
+#include <pthread.h>
+#include "pthread_private.h"
+#endif
/* Define FLOATING_POINT to get floating point. */
#define FLOATING_POINT
@@ -366,14 +370,25 @@ vfprintf(fp, fmt0, ap)
flags&SHORTINT ? (u_long)(u_short)va_arg(ap, int) : \
(u_long)va_arg(ap, u_int))
+#ifdef _THREAD_SAFE
+ _thread_flockfile(fp,__FILE__,__LINE__);
+#endif
/* sorry, fprintf(read_only_file, "") returns EOF, not 0 */
- if (cantwrite(fp))
+ if (cantwrite(fp)) {
+#ifdef _THREAD_SAFE
+ _thread_funlockfile(fp);
+#endif
return (EOF);
+ }
/* optimise fprintf(stderr) (and other unbuffered Unix files) */
if ((fp->_flags & (__SNBF|__SWR|__SRW)) == (__SNBF|__SWR) &&
- fp->_file >= 0)
+ fp->_file >= 0) {
+#ifdef _THREAD_SAFE
+ _thread_funlockfile(fp);
+#endif
return (__sbprintf(fp, fmt0, ap));
+ }
fmt = (char *)fmt0;
uio.uio_iov = iovp = iov;
@@ -782,7 +797,12 @@ number: if ((dprec = prec) >= 0)
done:
FLUSH();
error:
- return (__sferror(fp) ? EOF : ret);
+ if (__sferror(fp))
+ ret = EOF;
+#ifdef _THREAD_SAFE
+ _thread_funlockfile(fp);
+#endif
+ return (ret);
/* NOTREACHED */
}
diff --git a/lib/libc/stdio/vscanf.c b/lib/libc/stdio/vscanf.c
index 5d128650b54b..677039ecc8e4 100644
--- a/lib/libc/stdio/vscanf.c
+++ b/lib/libc/stdio/vscanf.c
@@ -39,11 +39,24 @@ static char sccsid[] = "@(#)vscanf.c 8.1 (Berkeley) 6/4/93";
#endif /* LIBC_SCCS and not lint */
#include <stdio.h>
+#ifdef _THREAD_SAFE
+#include <pthread.h>
+#include "pthread_private.h"
+#endif
+int
vscanf(fmt, ap)
const char *fmt;
_BSD_VA_LIST_ ap;
{
+ int retval;
- return (__svfscanf(stdin, fmt, ap));
+#ifdef _THREAD_SAFE
+ _thread_flockfile(stdin,__FILE__,__LINE__);
+#endif
+ retval = __svfscanf(stdin, fmt, ap);
+#ifdef _THREAD_SAFE
+ _thread_funlockfile(stdin);
+#endif
+ return (retval);
}
diff --git a/lib/libc/stdio/vsnprintf.c b/lib/libc/stdio/vsnprintf.c
index ccc8af63f355..1bff18bb8d3d 100644
--- a/lib/libc/stdio/vsnprintf.c
+++ b/lib/libc/stdio/vsnprintf.c
@@ -40,6 +40,7 @@ static char sccsid[] = "@(#)vsnprintf.c 8.1 (Berkeley) 6/4/93";
#include <stdio.h>
+int
vsnprintf(str, n, fmt, ap)
char *str;
size_t n;
@@ -51,6 +52,7 @@ vsnprintf(str, n, fmt, ap)
if ((int)n < 1)
return (EOF);
+ f._file = -1;
f._flags = __SWR | __SSTR;
f._bf._base = f._p = (unsigned char *)str;
f._bf._size = f._w = n - 1;
diff --git a/lib/libc/stdio/vsprintf.c b/lib/libc/stdio/vsprintf.c
index c6e192ae07c6..cdfb9ebb91f5 100644
--- a/lib/libc/stdio/vsprintf.c
+++ b/lib/libc/stdio/vsprintf.c
@@ -41,6 +41,7 @@ static char sccsid[] = "@(#)vsprintf.c 8.1 (Berkeley) 6/4/93";
#include <stdio.h>
#include <limits.h>
+int
vsprintf(str, fmt, ap)
char *str;
const char *fmt;
@@ -49,6 +50,7 @@ vsprintf(str, fmt, ap)
int ret;
FILE f;
+ f._file = -1;
f._flags = __SWR | __SSTR;
f._bf._base = f._p = (unsigned char *)str;
f._bf._size = f._w = INT_MAX;
diff --git a/lib/libc/stdio/vsscanf.c b/lib/libc/stdio/vsscanf.c
index e776689f9a0e..0d4d05a10a4f 100644
--- a/lib/libc/stdio/vsscanf.c
+++ b/lib/libc/stdio/vsscanf.c
@@ -52,6 +52,7 @@ eofread(cookie, buf, len)
return (0);
}
+int
vsscanf(str, fmt, ap)
const char *str;
const char *fmt;
@@ -59,6 +60,7 @@ vsscanf(str, fmt, ap)
{
FILE f;
+ f._file = -1;
f._flags = __SRD;
f._bf._base = f._p = (unsigned char *)str;
f._bf._size = f._r = strlen(str);
diff --git a/lib/libc/stdlib/abort.c b/lib/libc/stdlib/abort.c
index 690bdf5e48eb..f41500739fec 100644
--- a/lib/libc/stdlib/abort.c
+++ b/lib/libc/stdlib/abort.c
@@ -39,6 +39,10 @@ static char sccsid[] = "@(#)abort.c 8.1 (Berkeley) 6/4/93";
#include <stdlib.h>
#include <stddef.h>
#include <unistd.h>
+#ifdef _THREAD_SAFE
+#include <pthread.h>
+#include "pthread_private.h"
+#endif
void
abort()
@@ -51,15 +55,24 @@ abort()
* any errors -- X311J doesn't allow abort to return anyway.
*/
sigdelset(&mask, SIGABRT);
+#ifdef _THREAD_SAFE
+ (void) _thread_sys_sigprocmask(SIG_SETMASK, &mask, (sigset_t *)NULL);
+#else
(void)sigprocmask(SIG_SETMASK, &mask, (sigset_t *)NULL);
+#endif
(void)kill(getpid(), SIGABRT);
/*
* if SIGABRT ignored, or caught and the handler returns, do
* it again, only harder.
*/
+#ifdef _THREAD_SAFE
+ (void) _thread_sys_signal(SIGABRT, SIG_DFL);
+ (void) _thread_sys_sigprocmask(SIG_SETMASK, &mask, (sigset_t *)NULL);
+#else
(void)signal(SIGABRT, SIG_DFL);
(void)sigprocmask(SIG_SETMASK, &mask, (sigset_t *)NULL);
+#endif
(void)kill(getpid(), SIGABRT);
exit(1);
}
diff --git a/lib/libc/stdlib/malloc.c b/lib/libc/stdlib/malloc.c
index 429902868c40..caa12d12630c 100644
--- a/lib/libc/stdlib/malloc.c
+++ b/lib/libc/stdlib/malloc.c
@@ -6,7 +6,7 @@
* this stuff is worth it, you can buy me a beer in return. Poul-Henning Kamp
* ----------------------------------------------------------------------------
*
- * $Id: malloc.c,v 1.8 1995/12/18 12:03:54 phk Exp $
+ * $Id: malloc.c,v 1.9 1996/01/05 23:30:41 phk Exp $
*
*/
@@ -51,6 +51,10 @@
#include <err.h>
#include <sys/types.h>
#include <sys/mman.h>
+#ifdef _THREAD_SAFE
+#include <pthread.h>
+#include "pthread_private.h"
+#endif
/*
* This structure describes a page worth of chunks.
@@ -806,6 +810,9 @@ void *
malloc(size_t size)
{
void *result;
+#ifdef _THREAD_SAFE
+ int status;
+#endif
if (!initialized)
malloc_init();
@@ -813,6 +820,9 @@ malloc(size_t size)
if (suicide)
abort();
+#ifdef _THREAD_SAFE
+ _thread_kern_sig_block(&status);
+#endif
if (size <= malloc_maxsize)
result = malloc_bytes(size);
else
@@ -824,6 +834,9 @@ malloc(size_t size)
if (malloc_zero)
memset(result,0,size);
+#ifdef _THREAD_SAFE
+ _thread_kern_sig_unblock(status);
+#endif
return result;
}
@@ -837,6 +850,9 @@ realloc(void *ptr, size_t size)
u_long osize,index;
struct pginfo **mp;
int i;
+#ifdef _THREAD_SAFE
+ int status;
+#endif
if (suicide)
return 0;
@@ -854,15 +870,24 @@ realloc(void *ptr, size_t size)
return 0;
}
+#ifdef _THREAD_SAFE
+ _thread_kern_sig_block(&status);
+#endif
index = ptr2index(ptr);
if (index < malloc_pageshift) {
wrtwarning("realloc(): junk pointer (too low)\n");
+#ifdef _THREAD_SAFE
+ _thread_kern_sig_unblock(status);
+#endif
return 0;
}
if (index > last_index) {
wrtwarning("realloc(): junk pointer (too high)\n");
+#ifdef _THREAD_SAFE
+ _thread_kern_sig_unblock(status);
+#endif
return 0;
}
@@ -873,6 +898,9 @@ realloc(void *ptr, size_t size)
/* Check the pointer */
if ((u_long)ptr & malloc_pagemask) {
wrtwarning("realloc(): modified page pointer.\n");
+#ifdef _THREAD_SAFE
+ _thread_kern_sig_unblock(status);
+#endif
return 0;
}
@@ -882,14 +910,21 @@ realloc(void *ptr, size_t size)
if (!malloc_realloc && /* unless we have to, */
size <= osize && /* .. or are too small, */
- size > (osize - malloc_pagesize)) /* .. or can free a page, */
+ size > (osize - malloc_pagesize)) { /* .. or can free a page, */
+#ifdef _THREAD_SAFE
+ _thread_kern_sig_unblock(status);
+#endif
return ptr; /* don't do anything. */
+ }
} else if (*mp >= MALLOC_MAGIC) { /* Chunk allocation */
/* Check the pointer for sane values */
if (((u_long)ptr & ((*mp)->size-1))) {
wrtwarning("realloc(): modified chunk pointer.\n");
+#ifdef _THREAD_SAFE
+ _thread_kern_sig_unblock(status);
+#endif
return 0;
}
@@ -899,6 +934,9 @@ realloc(void *ptr, size_t size)
/* Verify that it isn't a free chunk already */
if (tst_bit(*mp,i)) {
wrtwarning("realloc(): already free chunk.\n");
+#ifdef _THREAD_SAFE
+ _thread_kern_sig_unblock(status);
+#endif
return 0;
}
@@ -907,11 +945,18 @@ realloc(void *ptr, size_t size)
if (!malloc_realloc && /* Unless we have to, */
size < osize && /* ..or are too small, */
(size > osize/2 || /* ..or could use a smaller size, */
- osize == malloc_minsize)) /* ..(if there is one) */
+ osize == malloc_minsize)) { /* ..(if there is one) */
+#ifdef _THREAD_SAFE
+ _thread_kern_sig_unblock(status);
+#endif
return ptr; /* ..Don't do anything */
+ }
} else {
wrtwarning("realloc(): wrong page pointer.\n");
+#ifdef _THREAD_SAFE
+ _thread_kern_sig_unblock(status);
+#endif
return 0;
}
@@ -925,6 +970,9 @@ realloc(void *ptr, size_t size)
memcpy(p,ptr,size);
free(ptr);
}
+#ifdef _THREAD_SAFE
+ _thread_kern_sig_unblock(status);
+#endif
return p;
}
@@ -1119,6 +1167,9 @@ free(void *ptr)
{
struct pginfo *info;
int index;
+#ifdef _THREAD_SAFE
+ int status;
+#endif
/* This is legal */
if (!ptr)
@@ -1133,15 +1184,24 @@ free(void *ptr)
if (suicide)
return;
+#ifdef _THREAD_SAFE
+ _thread_kern_sig_block(&status);
+#endif
index = ptr2index(ptr);
if (index < malloc_pageshift) {
wrtwarning("free(): junk pointer (too low)\n");
+#ifdef _THREAD_SAFE
+ _thread_kern_sig_unblock(status);
+#endif
return;
}
if (index > last_index) {
wrtwarning("free(): junk pointer (too high)\n");
+#ifdef _THREAD_SAFE
+ _thread_kern_sig_unblock(status);
+#endif
return;
}
@@ -1151,5 +1211,8 @@ free(void *ptr)
free_pages(ptr,index,info);
else
free_bytes(ptr,index,info);
+#ifdef _THREAD_SAFE
+ _thread_kern_sig_unblock(status);
+#endif
return;
}
diff --git a/lib/libc/stdtime/localtime.c b/lib/libc/stdtime/localtime.c
index d6337ff8055d..35076417c8ec 100644
--- a/lib/libc/stdtime/localtime.c
+++ b/lib/libc/stdtime/localtime.c
@@ -15,6 +15,10 @@ static char elsieid[] = "@(#)localtime.c 7.44";
#include "private.h"
#include "tzfile.h"
#include "fcntl.h"
+#ifdef _THREAD_SAFE
+#include <pthread.h>
+#include "pthread_private.h"
+#endif
/*
** SunOS 4.1.1 headers lack O_BINARY.
@@ -158,6 +162,10 @@ static struct state gmtmem;
static char lcl_TZname[TZ_STRLEN_MAX + 1];
static int lcl_is_set;
static int gmt_is_set;
+#ifdef _THREAD_SAFE
+static pthread_mutex_t lcl_mutex = PTHREAD_MUTEX_INITIALIZER;
+static pthread_mutex_t gmt_mutex = PTHREAD_MUTEX_INITIALIZER;
+#endif
char * tzname[2] = {
wildabbr,
@@ -906,8 +914,13 @@ struct state * const sp;
*/
static
#endif /* !defined STD_INSPIRED */
+#ifdef _THREAD_SAFE
+void
+tzsetwall_basic P((void))
+#else
void
tzsetwall P((void))
+#endif
{
if (lcl_is_set < 0)
return;
@@ -927,8 +940,23 @@ tzsetwall P((void))
settzname();
}
+#ifdef _THREAD_SAFE
+void
+tzsetwall P((void))
+{
+ pthread_mutex_lock(&lcl_mutex);
+ tzsetwall_basic();
+ pthread_mutex_unlock(&lcl_mutex);
+}
+#endif
+
+#ifdef _THREAD_SAFE
+static void
+tzset_basic P((void))
+#else
void
tzset P((void))
+#endif
{
register const char * name;
@@ -968,6 +996,16 @@ tzset P((void))
settzname();
}
+#ifdef _THREAD_SAFE
+void
+tzset P((void))
+{
+ pthread_mutex_lock(&lcl_mutex);
+ tzset_basic();
+ pthread_mutex_unlock(&lcl_mutex);
+}
+#endif
+
/*
** The easy way to behave "as if no library function calls" localtime
** is to not call it--so we drop its guts into "localsub", which can be
@@ -1024,13 +1062,55 @@ struct tm * const tmp;
#endif /* defined TM_ZONE */
}
+#ifdef _THREAD_SAFE
+int
+localtime_r(timep, p_tm)
+const time_t * const timep;
+struct tm *p_tm;
+{
+ pthread_mutex_lock(&lcl_mutex);
+ tzset();
+ localsub(timep, 0L, p_tm);
+ pthread_mutex_unlock(&lcl_mutex);
+ return(0);
+}
+#endif
+
struct tm *
localtime(timep)
const time_t * const timep;
{
+#ifdef _THREAD_SAFE
+ static pthread_mutex_t localtime_mutex = PTHREAD_MUTEX_INITIALIZER;
+ static pthread_key_t localtime_key = -1;
+ struct tm *p_tm;
+
+ pthread_mutex_lock(&localtime_mutex);
+ if (localtime_key < 0) {
+ if (pthread_keycreate(&localtime_key, free) < 0) {
+ pthread_mutex_unlock(&localtime_mutex);
+ return(NULL);
+ }
+ }
+ pthread_mutex_unlock(&localtime_mutex);
+ if (pthread_getspecific(localtime_key,(void **) &p_tm) != 0) {
+ return(NULL);
+ } else if (p_tm == NULL) {
+ if ((p_tm = (struct tm *)malloc(sizeof(struct tm))) == NULL) {
+ return(NULL);
+ }
+ pthread_setspecific(localtime_key, p_tm);
+ }
+ pthread_mutex_lock(&lcl_mutex);
+ tzset();
+ localsub(timep, 0L, p_tm);
+ pthread_mutex_unlock(&lcl_mutex);
+ return p_tm;
+#else
tzset();
localsub(timep, 0L, &tm);
return &tm;
+#endif
}
/*
@@ -1043,6 +1123,9 @@ const time_t * const timep;
const long offset;
struct tm * const tmp;
{
+#ifdef _THREAD_SAFE
+ pthread_mutex_lock(&gmt_mutex);
+#endif
if (!gmt_is_set) {
gmt_is_set = TRUE;
#ifdef ALL_STATE
@@ -1051,6 +1134,9 @@ struct tm * const tmp;
#endif /* defined ALL_STATE */
gmtload(gmtptr);
}
+#ifdef _THREAD_SAFE
+ pthread_mutex_unlock(&gmt_mutex);
+#endif
timesub(timep, offset, gmtptr, tmp);
#ifdef TM_ZONE
/*
@@ -1077,9 +1163,43 @@ struct tm *
gmtime(timep)
const time_t * const timep;
{
+#ifdef _THREAD_SAFE
+ static pthread_mutex_t gmtime_mutex = PTHREAD_MUTEX_INITIALIZER;
+ static pthread_key_t gmtime_key = -1;
+ struct tm *p_tm;
+
+ pthread_mutex_lock(&gmtime_mutex);
+ if (gmtime_key < 0) {
+ if (pthread_keycreate(&gmtime_key, free) < 0) {
+ pthread_mutex_unlock(&gmtime_mutex);
+ return(NULL);
+ }
+ }
+ pthread_mutex_unlock(&gmtime_mutex);
+ if (pthread_getspecific(gmtime_key,(void **) &p_tm) != 0) {
+ return(NULL);
+ } else if (p_tm == NULL) {
+ if ((p_tm = (struct tm *)malloc(sizeof(struct tm))) == NULL) {
+ return(NULL);
+ }
+ pthread_setspecific(gmtime_key, p_tm);
+ }
+ gmtsub(timep, 0L, p_tm);
+ return(p_tm);
+#else
gmtsub(timep, 0L, &tm);
return &tm;
+#endif
+}
+
+#ifdef _THREAD_SAFE
+int
+gmtime_r(const time_t * timep, struct tm * tm)
+{
+ gmtsub(timep, 0L, tm);
+ return(0);
}
+#endif
#ifdef STD_INSPIRED
@@ -1482,8 +1602,16 @@ time_t
mktime(tmp)
struct tm * const tmp;
{
+ time_t mktime_return_value;
+#ifdef _THREAD_SAFE
+ pthread_mutex_lock(&lcl_mutex);
+#endif
tzset();
- return time1(tmp, localsub, 0L);
+ mktime_return_value = time1(tmp, localsub, 0L);
+#ifdef _THREAD_SAFE
+ pthread_mutex_unlock(&lcl_mutex);
+#endif
+ return(mktime_return_value);
}
#ifdef STD_INSPIRED
diff --git a/lib/libc/sys/accept.2 b/lib/libc/sys/accept.2
index d475e3685b43..126000a2ecb6 100644
--- a/lib/libc/sys/accept.2
+++ b/lib/libc/sys/accept.2
@@ -129,6 +129,31 @@ by issuing a
call with providing only the control information,
or by calling
.Xr setsockopt 2 .
+.Sh IMPLEMENTATION NOTES
+.Pp
+In the non-threaded library
+.Fn accept
+is implemented as the
+.Va accept
+syscall.
+.Pp
+In the threaded library, the
+.Va accept
+syscall is assembled to
+.Fn _thread_sys_accept
+and
+.Fn accept
+is implemented as a function which locks
+.Va s
+for read and write, then calls
+.Fn _thread_sys_accept .
+If the call to
+.Fn _thread_sys_accept
+would block, a context switch is performed. Before returning,
+.Fn accept
+unlocks
+.Va s .
+.Pp
.Sh RETURN VALUES
The call returns \-1 on error. If it succeeds, it returns a non-negative
integer that is a descriptor for the accepted socket.
diff --git a/lib/libc/sys/bind.2 b/lib/libc/sys/bind.2
index 18512e29e5c9..f98631d7939b 100644
--- a/lib/libc/sys/bind.2
+++ b/lib/libc/sys/bind.2
@@ -62,6 +62,28 @@ needed (using
.Pp
The rules used in name binding vary between communication domains.
Consult the manual entries in section 4 for detailed information.
+.Sh IMPLEMENTATION NOTES
+.Pp
+In the non-threaded library
+.Fn bind
+is implemented as the
+.Va bind
+syscall.
+.Pp
+In the threaded library, the
+.Va bind
+syscall is assembled to
+.Fn _thread_sys_bind
+and
+.Fn bind
+is implemented as a function which locks
+.Va s
+for read and write, then calls
+.Fn _thread_sys_bind .
+Before returning,
+.Fn bind
+unlocks
+.Va s .
.Sh RETURN VALUES
If the bind is successful, a 0 value is returned.
A return value of -1 indicates an error, which is
diff --git a/lib/libc/sys/close.2 b/lib/libc/sys/close.2
index 885ac807b693..3cb3d51d3b74 100644
--- a/lib/libc/sys/close.2
+++ b/lib/libc/sys/close.2
@@ -90,6 +90,28 @@ execve; the call
.Dq Li fcntl(d, F_SETFD, 0)
restores the default,
which is to not close the descriptor.
+.Sh IMPLEMENTATION NOTES
+.Pp
+In the non-threaded library
+.Fn close
+is implemented as the
+.Va close
+syscall.
+.Pp
+In the threaded library, the
+.Va close
+syscall is assembled to
+.Fn _thread_sys_close
+and
+.Fn close
+is implemented as a function which locks
+.Va d
+for read and write, then calls
+.Fn _thread_sys_close .
+Before returning,
+.Fn close
+unlocks
+.Va d .
.Sh RETURN VALUES
Upon successful completion, a value of 0 is returned.
Otherwise, a value of -1 is returned and the global integer variable
diff --git a/lib/libc/sys/connect.2 b/lib/libc/sys/connect.2
index eb38ab320b4b..a6d7c7133165 100644
--- a/lib/libc/sys/connect.2
+++ b/lib/libc/sys/connect.2
@@ -68,6 +68,30 @@ only once; datagram sockets may use
multiple times to change their association.
Datagram sockets may dissolve the association
by connecting to an invalid address, such as a null address.
+.Sh IMPLEMENTATION NOTES
+.Pp
+In the non-threaded library
+.Fn connect
+is implemented as the
+.Va connect
+syscall.
+.Pp
+In the threaded library, the
+.Va connect
+syscall is assembled to
+.Fn _thread_sys_connect
+and
+.Fn connect
+is implemented as a function which locks
+.Va s
+for read and write, then calls
+.Fn _thread_sys_connect .
+If the call to
+.Fn _thread_sys_connect
+would block, a context switch is performed. Before returning,
+.Fn connect
+unlocks
+.Va s .
.Sh RETURN VALUES
If the connection or binding succeeds, 0 is returned.
Otherwise a -1 is returned, and a more specific error
@@ -79,10 +103,10 @@ The
call fails if:
.Bl -tag -width EADDRNOTAVAILABB
.It Bq Er EBADF
-.Fa S
+.Fa s
is not a valid descriptor.
.It Bq Er ENOTSOCK
-.Fa S
+.Fa s
is a descriptor for a file, not a socket.
.It Bq Er EADDRNOTAVAIL
The specified address is not available on this machine.
diff --git a/lib/libc/sys/dup.2 b/lib/libc/sys/dup.2
index 898963923e8c..29d1ada27b77 100644
--- a/lib/libc/sys/dup.2
+++ b/lib/libc/sys/dup.2
@@ -95,6 +95,53 @@ is specified. If this descriptor is already
in use, the descriptor is first deallocated as if a
.Xr close 2
call had been done first.
+.Sh IMPLEMENTATION NOTES
+.Pp
+In the non-threaded library
+.Fn dup
+is implemented as the
+.Va dup
+syscall.
+.Pp
+In the threaded library, the
+.Va dup
+syscall is assembled to
+.Fn _thread_sys_dup
+and
+.Fn dup
+is implemented as a function which locks
+.Va oldd
+for read and write, then calls
+.Fn _thread_sys_dup .
+Before returning,
+.Fn dup
+unlocks
+.Va oldd .
+.Pp
+In the non-threaded library
+.Fn dup2
+is implemented as the
+.Va dup2
+syscall.
+.Pp
+In the threaded library, the
+.Va dup2
+syscall is assembled to
+.Fn _thread_sys_dup2
+and
+.Fn dup2
+is implemented as a function which locks both
+.Va oldd
+and
+.Va newd
+for read and write, then calls
+.Fn _thread_sys_dup2 .
+Before returning,
+.Fn dup2
+unlocks
+.Va oldd .
+and
+.Va newd .
.Sh RETURN VALUES
The value -1 is returned if an error occurs in either call.
The external variable
diff --git a/lib/libc/sys/execve.2 b/lib/libc/sys/execve.2
index ba47e6d1833c..2bfb0a2bc254 100644
--- a/lib/libc/sys/execve.2
+++ b/lib/libc/sys/execve.2
@@ -178,6 +178,23 @@ and
.Fa argv
points to the array of character pointers
to the arguments themselves.
+.Sh IMPLEMENTATION NOTES
+.Pp
+In the non-threaded library
+.Fn execve
+is implemented as the
+.Va execve
+syscall.
+.Pp
+In the threaded library, the
+.Va execve
+syscall is assembled to
+.Fn _thread_sys_execve
+and
+.Fn execve
+is implemented as a function which performs user-thread
+library re-initialization and then calls
+.Fn _thread_sys_execve .
.Sh RETURN VALUES
As the
.Fn execve
diff --git a/lib/libc/sys/fcntl.2 b/lib/libc/sys/fcntl.2
index f53c02f2403d..eb752fe2fe96 100644
--- a/lib/libc/sys/fcntl.2
+++ b/lib/libc/sys/fcntl.2
@@ -330,6 +330,29 @@ This implementation detects that sleeping until a locked region is unlocked
would cause a deadlock and fails with an
.Er EDEADLK
error.
+.Sh IMPLEMENTATION NOTES
+.Pp
+In the non-threaded library
+.Fn fcntl
+is implemented as the
+.Va fcntl
+syscall.
+.Pp
+In the threaded library, the
+.Va fcntl
+syscall is assembled to
+.Fn _thread_sys_fcntl
+and
+.Fn fcntl
+is implemented as a function which disables thread resheduling, locks
+.Va fd
+for read and write, then calls
+.Fn _thread_sys_fcntl .
+Before returning,
+.Fn fcntl
+unlocks
+.Va fd
+and enables thread resheduling.
.Sh RETURN VALUES
Upon successful completion, the value returned depends on
.Fa cmd
diff --git a/lib/libc/sys/flock.2 b/lib/libc/sys/flock.2
index bb6abb75fc5b..5ec080c5f5d1 100644
--- a/lib/libc/sys/flock.2
+++ b/lib/libc/sys/flock.2
@@ -109,6 +109,28 @@ forks and the child explicitly unlocks the file, the parent will
lose its lock.
.Pp
Processes blocked awaiting a lock may be awakened by signals.
+.Sh IMPLEMENTATION NOTES
+.Pp
+In the non-threaded library
+.Fn flock
+is implemented as the
+.Va flock
+syscall.
+.Pp
+In the threaded library, the
+.Va flock
+syscall is assembled to
+.Fn _thread_sys_flock
+and
+.Fn flock
+is implemented as a function which locks
+.Va fd
+for read and write, then calls
+.Fn _thread_sys_flock .
+Before returning,
+.Fn flock
+unlocks
+.Va fd .
.Sh RETURN VALUES
Zero is returned if the operation was successful;
on an error a -1 is returned and an error code is left in
diff --git a/lib/libc/sys/fsync.2 b/lib/libc/sys/fsync.2
index 234ea6e996ed..1116cf9b3605 100644
--- a/lib/libc/sys/fsync.2
+++ b/lib/libc/sys/fsync.2
@@ -53,6 +53,28 @@ of buffers for the associated file to be written to a disk.
should be used by programs that require a file to be
in a known state, for example, in building a simple transaction
facility.
+.Sh IMPLEMENTATION NOTES
+.Pp
+In the non-threaded library
+.Fn fsync
+is implemented as the
+.Va fsync
+syscall.
+.Pp
+In the threaded library, the
+.Va fsync
+syscall is assembled to
+.Fn _thread_sys_fsync
+and
+.Fn fsync
+is implemented as a function which locks
+.Va fd
+for read and write, then calls
+.Fn _thread_sys_fsync .
+Before returning,
+.Fn fsync
+unlocks
+.Va fd .
.Sh RETURN VALUES
A 0 value is returned on success. A -1 value indicates
an error.
diff --git a/lib/libc/sys/ftruncate.c b/lib/libc/sys/ftruncate.c
index 2f3ae6d5a024..72a6a9158153 100644
--- a/lib/libc/sys/ftruncate.c
+++ b/lib/libc/sys/ftruncate.c
@@ -37,6 +37,11 @@ static char sccsid[] = "@(#)ftruncate.c 8.1 (Berkeley) 6/17/93";
#include <sys/types.h>
#include <sys/syscall.h>
+#include <unistd.h>
+#ifdef _THREAD_SAFE
+#include <pthread.h>
+#include "pthread_private.h"
+#endif
/*
* This function provides 64-bit offset padding that
@@ -48,5 +53,16 @@ ftruncate(fd, length)
off_t length;
{
+#ifdef _THREAD_SAFE
+ int retval;
+ if (_thread_fd_lock(fd, FD_RDWR, NULL,__FILE__,__LINE__) != 0) {
+ retval = -1;
+ } else {
+ retval = __syscall((quad_t)SYS_ftruncate, fd, 0, length);
+ _thread_fd_unlock(fd, FD_RDWR);
+ }
+ return(retval);
+#else
return(__syscall((quad_t)SYS_ftruncate, fd, 0, length));
+#endif
}
diff --git a/lib/libc/sys/getdirentries.2 b/lib/libc/sys/getdirentries.2
index 6df944420db6..9e6dc508eb89 100644
--- a/lib/libc/sys/getdirentries.2
+++ b/lib/libc/sys/getdirentries.2
@@ -120,6 +120,28 @@ The current position pointer should only be set to a value returned by
a value returned in the location pointed to by
.Fa basep ,
or zero.
+.Sh IMPLEMENTATION NOTES
+.Pp
+In the non-threaded library
+.Fn getdirentries
+is implemented as the
+.Va getdirentries
+syscall.
+.Pp
+In the threaded library, the
+.Va getdirentries
+syscall is assembled to
+.Fn _thread_sys_getdirentries
+and
+.Fn getdirentries
+is implemented as a function which locks
+.Va fd
+for read and write, then calls
+.Fn _thread_sys_getdirentries .
+Before returning,
+.Fn getdirentries
+unlocks
+.Va fd .
.Sh RETURN VALUES
If successful, the number of bytes actually transferred is returned.
Otherwise, -1 is returned and the global variable
diff --git a/lib/libc/sys/getpeername.2 b/lib/libc/sys/getpeername.2
index d89488c3aaf9..5ca0a443c326 100644
--- a/lib/libc/sys/getpeername.2
+++ b/lib/libc/sys/getpeername.2
@@ -53,6 +53,28 @@ the amount of space pointed to by
On return it contains the actual size of the name
returned (in bytes).
The name is truncated if the buffer provided is too small.
+.Sh IMPLEMENTATION NOTES
+.Pp
+In the non-threaded library
+.Fn getpeername
+is implemented as the
+.Va getpeername
+syscall.
+.Pp
+In the threaded library, the
+.Va getpeername
+syscall is assembled to
+.Fn _thread_sys_getpeername
+and
+.Fn getpeername
+is implemented as a function which locks
+.Va s
+for read and write, then calls
+.Fn _thread_sys_getpeername .
+Before returning,
+.Fn getpeername
+unlocks
+.Va s .
.Sh DIAGNOSTICS
A 0 is returned if the call succeeds, -1 if it fails.
.Sh ERRORS
diff --git a/lib/libc/sys/getsockname.2 b/lib/libc/sys/getsockname.2
index d56e40486646..e053b4768e7b 100644
--- a/lib/libc/sys/getsockname.2
+++ b/lib/libc/sys/getsockname.2
@@ -51,6 +51,28 @@ the amount of space pointed to by
.Fa name .
On return it contains the actual size of the name
returned (in bytes).
+.Sh IMPLEMENTATION NOTES
+.Pp
+In the non-threaded library
+.Fn getsockname
+is implemented as the
+.Va getsockname
+syscall.
+.Pp
+In the threaded library, the
+.Va getsockname
+syscall is assembled to
+.Fn _thread_sys_getsockname
+and
+.Fn getsockname
+is implemented as a function which locks
+.Va fd
+for read and write, then calls
+.Fn _thread_sys_getsockname .
+Before returning,
+.Fn getsockname
+unlocks
+.Va fd .
.Sh DIAGNOSTICS
A 0 is returned if the call succeeds, -1 if it fails.
.Sh ERRORS
diff --git a/lib/libc/sys/getsockopt.2 b/lib/libc/sys/getsockopt.2
index 24ae2b8b4660..e2ec25751e95 100644
--- a/lib/libc/sys/getsockopt.2
+++ b/lib/libc/sys/getsockopt.2
@@ -30,7 +30,7 @@
.\" SUCH DAMAGE.
.\"
.\" @(#)getsockopt.2 8.3 (Berkeley) 4/19/94
-.\" $Id$
+.\" $Id: getsockopt.2,v 1.2 1995/11/03 18:34:36 wollman Exp $
.\"
.Dd November 3, 1995
.Dt GETSOCKOPT 2
@@ -313,6 +313,49 @@ returns any pending error on the socket and clears
the error status.
It may be used to check for asynchronous errors on connected
datagram sockets or for other asynchronous errors.
+.Sh IMPLEMENTATION NOTES
+.Pp
+In the non-threaded library
+.Fn getsockopt
+is implemented as the
+.Va getsockopt
+syscall.
+.Pp
+In the threaded library, the
+.Va getsockopt
+syscall is assembled to
+.Fn _thread_sys_getsockopt
+and
+.Fn getsockopt
+is implemented as a function which locks
+.Va s
+for read and write, then calls
+.Fn _thread_sys_getsockopt .
+Before returning,
+.Fn getsockopt
+unlocks
+.Va s .
+.Pp
+In the non-threaded library
+.Fn setsockopt
+is implemented as the
+.Va setsockopt
+syscall.
+.Pp
+In the threaded library, the
+.Va setsockopt
+syscall is assembled to
+.Fn _thread_sys_setsockopt
+and
+.Fn setsockopt
+is implemented as a function which locks
+.Va s
+for read and write, then calls
+.Fn _thread_sys_setsockopt .
+Before returning,
+.Fn setsockopt
+unlocks
+.Va s .
.Sh RETURN VALUES
A 0 is returned if the call succeeds, -1 if it fails.
.Sh ERRORS
diff --git a/lib/libc/sys/intro.2 b/lib/libc/sys/intro.2
index bf4380917e39..a6e735155544 100644
--- a/lib/libc/sys/intro.2
+++ b/lib/libc/sys/intro.2
@@ -47,13 +47,49 @@ their error returns, and other common definitions and concepts.
.\".Pp
.\"<more later...>
.Sh DIAGNOSTICS
-Nearly all of the system calls provide an error number in the external
-variable
-.Va errno ,
-which is defined as:
+Nearly all of the system calls provide an error number referenced via
+the external identifier errno. This identifier is defined in
+.Aq Pa sys/errno.h
+for non-threaded programs as:
.Pp
.Dl extern int errno
.Pp
+and for threaded programs as:
+.Pp
+.Dl extern int * __error();
+.Dl #define errno (* __error())
+.Pp
+A threaded program must be compiled with
+.Va _THREAD_SAFE
+defined so that the preprocessor will output the appropriate errno
+definition to the compiler. Failure to do so will mean that error
+variables will not be thread specific.
+.Pp
+The threaded library implementation of
+.Va __error()
+returns a pointer to a field in the thread specific structure for
+threads other than the initial thread. For the initial thread,
+.Va __error()
+returns a pointer to a global
+.Va errno
+variable that is compatible with that used by non-threaded programs.
+This allows the initial thread to call functions in libraries which have
+not been compiled with
+.Va _THREAD_SAFE .
+Programmers should ensure that threads other than the initial thread only
+call functions in libraries that have been compiled with
+.Va _THREAD_SAFE .
+.Pp
+Programmers should include
+.Aq Pa sys/errno.h to obtain the definition of
+.Va errno
+rather than coding the definition as an external reference directly. It is
+planned that the
+.Va extern int errno
+definition will eventually be replaced by the threaded definition so that
+all libraries will have a thread-aware treatment of
+.Va errno .
+.Pp
When a system call detects an error,
it returns an integer value
indicating failure (usually -1)
diff --git a/lib/libc/sys/ioctl.2 b/lib/libc/sys/ioctl.2
index 36ce6ff47f65..38c58b9dcf59 100644
--- a/lib/libc/sys/ioctl.2
+++ b/lib/libc/sys/ioctl.2
@@ -68,6 +68,28 @@ Macros and defines used in specifying an ioctl
.Fa request
are located in the file
.Ao Pa sys/ioctl.h Ac .
+.Sh IMPLEMENTATION NOTES
+.Pp
+In the non-threaded library
+.Fn ioctl
+is implemented as the
+.Va ioctl
+syscall.
+.Pp
+In the threaded library, the
+.Va ioctl
+syscall is assembled to
+.Fn _thread_sys_ioctl
+and
+.Fn ioctl
+is implemented as a function which locks
+.Va d
+for read and write, then calls
+.Fn _thread_sys_ioctl .
+Before returning,
+.Fn ioctl
+unlocks
+.Va d .
.Sh RETURN VALUES
If an error has occurred, a value of -1 is returned and
.Va errno
diff --git a/lib/libc/sys/listen.2 b/lib/libc/sys/listen.2
index eaa9522d5ee5..6d2a64f14522 100644
--- a/lib/libc/sys/listen.2
+++ b/lib/libc/sys/listen.2
@@ -30,7 +30,7 @@
.\" SUCH DAMAGE.
.\"
.\" From: @(#)listen.2 8.2 (Berkeley) 12/11/93
-.\" $Id$
+.\" $Id: listen.2,v 1.3 1995/11/03 18:34:38 wollman Exp $
.\"
.Dd November 3, 1995
.Dt LISTEN 2
@@ -82,6 +82,28 @@ or less than zero is specified,
.Fa backlog
is silently forced to
.Li kern.somaxconn .
+.Sh IMPLEMENTATION NOTES
+.Pp
+In the non-threaded library
+.Fn listen
+is implemented as the
+.Va listen
+syscall.
+.Pp
+In the threaded library, the
+.Va listen
+syscall is assembled to
+.Fn _thread_sys_listen
+and
+.Fn listen
+is implemented as a function which locks
+.Va s
+for read and write, then calls
+.Fn _thread_sys_listen .
+Before returning,
+.Fn listen
+unlocks
+.Va s .
.Sh RETURN VALUES
A 0 return value indicates success; -1 indicates an error.
.Sh ERRORS
diff --git a/lib/libc/sys/lseek.c b/lib/libc/sys/lseek.c
index 52208d137a93..8896ad8d3567 100644
--- a/lib/libc/sys/lseek.c
+++ b/lib/libc/sys/lseek.c
@@ -37,6 +37,11 @@ static char sccsid[] = "@(#)lseek.c 8.1 (Berkeley) 6/17/93";
#include <sys/types.h>
#include <sys/syscall.h>
+#include <unistd.h>
+#ifdef _THREAD_SAFE
+#include <pthread.h>
+#include "pthread_private.h"
+#endif
/*
* This function provides 64-bit offset padding that
@@ -48,7 +53,17 @@ lseek(fd, offset, whence)
off_t offset;
int whence;
{
- extern off_t __syscall();
+#ifdef _THREAD_SAFE
+ off_t offs;
+ if (_thread_fd_lock(fd, FD_RDWR, NULL,__FILE__,__LINE__) != 0) {
+ offs = -1;
+ } else {
+ offs = __syscall((quad_t) SYS_lseek,fd, 0, offset, whence);
+ _thread_fd_unlock(fd, FD_RDWR);
+ }
+ return(offs);
+#else
return(__syscall((quad_t)SYS_lseek, fd, 0, offset, whence));
+#endif
}
diff --git a/lib/libc/sys/open.2 b/lib/libc/sys/open.2
index dea59fcce346..479a20944ac7 100644
--- a/lib/libc/sys/open.2
+++ b/lib/libc/sys/open.2
@@ -146,6 +146,26 @@ The system imposes a limit on the number of file descriptors
open simultaneously by one process.
.Xr Getdtablesize 2
returns the current system limit.
+.Pp
+.Sh IMPLEMENTATION NOTES
+In the non-threaded library
+.Fn open
+is implemented as the
+.Va open
+syscall.
+.Pp
+In the threaded library, the
+.Va open
+syscall is assembled to
+.Fn _thread_sys_open
+and
+.Fn open
+is implemented as a function which disables thread rescheduling
+and calls
+.Fn _thread_sys_open .
+Before returning,
+.Fn open
+enables thread rescheduling.
.Sh ERRORS
The named file is opened unless:
.Bl -tag -width Er
diff --git a/lib/libc/sys/read.2 b/lib/libc/sys/read.2
index b94341a043c0..ea428fd47a12 100644
--- a/lib/libc/sys/read.2
+++ b/lib/libc/sys/read.2
@@ -107,6 +107,53 @@ The system guarantees to read the number of bytes requested if
the descriptor references a normal file that has that many bytes left
before the end-of-file, but in no other case.
.Pp
+.Sh IMPLEMENTATION NOTES
+.Pp
+In the non-threaded library
+.Fn read
+is implemented as the
+.Va read
+syscall.
+.Pp
+In the threaded library, the
+.Va read
+syscall is assembled to
+.Fn _thread_sys_read
+and
+.Fn read
+is implemented as a function which locks
+.Va d
+for read, then calls
+.Fn _thread_sys_read .
+If the call to
+.Fn _thread_sys_read
+would block, a context switch is performed. Before returning,
+.Fn read
+unlocks
+.Va d .
+.Pp
+In the non-threaded library
+.Fn readv
+is implemented as the
+.Va readv
+syscall.
+.Pp
+In the threaded library, the
+.Va readv
+syscall is assembled to
+.Fn _thread_sys_readv
+and
+.Fn readv
+is implemented as a function which locks
+.Va d
+for read, then calls
+.Fn _thread_sys_readv .
+If the call to
+.Fn _thread_sys_readv
+would block, a context switch is performed. Before returning,
+.Fn readv
+unlocks
+.Va d .
.Sh RETURN VALUES
If successful, the
number of bytes actually read is returned. Upon reading end-of-file,
diff --git a/lib/libc/sys/write.2 b/lib/libc/sys/write.2
index de2d3aef59ab..a1e4a517cbe2 100644
--- a/lib/libc/sys/write.2
+++ b/lib/libc/sys/write.2
@@ -115,6 +115,53 @@ and
may write fewer bytes than requested;
the return value must be noted,
and the remainder of the operation should be retried when possible.
+.Sh IMPLEMENTATION NOTES
+.Pp
+In the non-threaded library
+.Fn write
+is implemented as the
+.Va write
+syscall.
+.Pp
+In the threaded library, the
+.Va write
+syscall is assembled to
+.Fn _thread_sys_write
+and
+.Fn write
+is implemented as a function which locks
+.Va d
+for read and write, then calls
+.Fn _thread_sys_write .
+If the call to
+.Fn _thread_sys_write
+would block, a context switch is performed. Before returning,
+.Fn write
+unlocks
+.Va d .
+.Pp
+In the non-threaded library
+.Fn writev
+is implemented as the
+.Va writev
+syscall.
+.Pp
+In the threaded library, the
+.Va writev
+syscall is assembled to
+.Fn _thread_sys_writev
+and
+.Fn writev
+is implemented as a function which locks
+.Va d
+for read and write, then calls
+.Fn _thread_sys_writev .
+If the call to
+.Fn _thread_sys_writev
+would block, a context switch is performed. Before returning,
+.Fn writev
+unlocks
+.Va d .
.Sh RETURN VALUES
Upon successful completion the number of bytes which were written
is returned. Otherwise a -1 is returned and the global variable
diff --git a/sys/sys/errno.h b/sys/sys/errno.h
index 3bac4ed751de..3dddd456834b 100644
--- a/sys/sys/errno.h
+++ b/sys/sys/errno.h
@@ -36,15 +36,20 @@
* SUCH DAMAGE.
*
* @(#)errno.h 8.5 (Berkeley) 1/21/94
- * $Id: errno.h,v 1.2 1994/08/02 07:52:54 davidg Exp $
+ * $Id: errno.h,v 1.3 1994/08/21 04:41:42 paul Exp $
*/
#ifndef _SYS_ERRNO_H_
#define _SYS_ERRNO_H_
#ifndef KERNEL
+#ifdef _THREAD_SAFE
+extern int * __error();
+#define errno (* __error())
+#else
extern int errno; /* global error number */
#endif
+#endif
#define EPERM 1 /* Operation not permitted */
#define ENOENT 2 /* No such file or directory */