diff options
| author | Julian Elischer <julian@FreeBSD.org> | 1996-01-22 00:02:33 +0000 | 
|---|---|---|
| committer | Julian Elischer <julian@FreeBSD.org> | 1996-01-22 00:02:33 +0000 | 
| commit | f70177e76e605ec6e6cd5b938fa77ade5d380e87 (patch) | |
| tree | a89c7f50ec371cef4418259b9dccdd31ebb2f61f | |
| parent | 61de51cad66df0d565233915f856932159d33a4a (diff) | |
Notes
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 */ | 
