From f70177e76e605ec6e6cd5b938fa77ade5d380e87 Mon Sep 17 00:00:00 2001 From: Julian Elischer Date: Mon, 22 Jan 1996 00:02:33 +0000 Subject: Reviewed by: julian and (hsu?) Submitted by: John Birrel(L?) changes for threadsafe operations --- include/Makefile | 8 +-- include/time.h | 7 +++ include/unistd.h | 1 + lib/csu/i386/crt0.c | 10 +++- lib/libc/amd64/SYS.h | 17 +++++- lib/libc/amd64/gen/_setjmp.S | 12 +++- lib/libc/amd64/gen/setjmp.S | 20 ++++++- lib/libc/amd64/gen/sigsetjmp.S | 20 ++++++- lib/libc/amd64/sys/cerror.S | 28 ++++++++- lib/libc/amd64/sys/pipe.S | 6 +- lib/libc/amd64/sys/sigreturn.S | 6 +- lib/libc/amd64/sys/vfork.S | 28 ++++++++- lib/libc/db/hash/hash.c | 14 ++--- lib/libc/db/hash/hash.h | 2 +- lib/libc/db/hash/ndbm.c | 4 +- lib/libc/gen/Makefile.inc | 4 +- lib/libc/gen/isatty.c | 17 +++++- lib/libc/gen/sleep.c | 20 +++++++ lib/libc/gen/ttyname.c | 111 ++++++++++++++++++++++++++++++++++ lib/libc/gen/usleep.c | 19 +++++- lib/libc/i386/SYS.h | 17 +++++- lib/libc/i386/gen/_setjmp.S | 12 +++- lib/libc/i386/gen/setjmp.S | 20 ++++++- lib/libc/i386/gen/sigsetjmp.S | 20 ++++++- lib/libc/i386/sys/Ovfork.S | 28 ++++++++- lib/libc/i386/sys/cerror.S | 28 ++++++++- lib/libc/i386/sys/fork.S | 6 +- lib/libc/i386/sys/pipe.S | 6 +- lib/libc/i386/sys/sigpending.S | 6 +- lib/libc/i386/sys/sigprocmask.S | 8 ++- lib/libc/i386/sys/sigreturn.S | 6 +- lib/libc/i386/sys/sigsuspend.S | 8 ++- lib/libc/stdio/clrerr.c | 10 ++++ lib/libc/stdio/fclose.c | 12 ++++ lib/libc/stdio/fflush.c | 19 +++++- lib/libc/stdio/fgetc.c | 15 ++++- lib/libc/stdio/fgetpos.c | 15 ++++- lib/libc/stdio/fgets.c | 20 ++++++- lib/libc/stdio/fpurge.c | 28 ++++++--- lib/libc/stdio/fputc.c | 15 ++++- lib/libc/stdio/fputs.c | 15 ++++- lib/libc/stdio/fread.c | 11 ++++ lib/libc/stdio/fscanf.c | 12 ++++ lib/libc/stdio/fseek.c | 28 ++++++++- lib/libc/stdio/ftell.c | 16 ++++- lib/libc/stdio/fwrite.c | 16 ++++- lib/libc/stdio/getc.c | 15 ++++- lib/libc/stdio/getchar.c | 15 ++++- lib/libc/stdio/putc.c | 15 ++++- lib/libc/stdio/putchar.c | 15 ++++- lib/libc/stdio/puts.c | 15 ++++- lib/libc/stdio/putw.c | 15 ++++- lib/libc/stdio/rewind.c | 10 ++++ lib/libc/stdio/scanf.c | 12 ++++ lib/libc/stdio/setvbuf.c | 14 +++++ lib/libc/stdio/snprintf.c | 3 + lib/libc/stdio/sprintf.c | 3 + lib/libc/stdio/sscanf.c | 3 + lib/libc/stdio/ungetc.c | 37 ++++++++++-- lib/libc/stdio/vfprintf.c | 26 +++++++- lib/libc/stdio/vscanf.c | 15 ++++- lib/libc/stdio/vsnprintf.c | 2 + lib/libc/stdio/vsprintf.c | 2 + lib/libc/stdio/vsscanf.c | 2 + lib/libc/stdlib/abort.c | 13 ++++ lib/libc/stdlib/malloc.c | 69 ++++++++++++++++++++- lib/libc/stdtime/localtime.c | 130 +++++++++++++++++++++++++++++++++++++++- lib/libc/sys/accept.2 | 25 ++++++++ lib/libc/sys/bind.2 | 22 +++++++ lib/libc/sys/close.2 | 22 +++++++ lib/libc/sys/connect.2 | 28 ++++++++- lib/libc/sys/dup.2 | 47 +++++++++++++++ lib/libc/sys/execve.2 | 17 ++++++ lib/libc/sys/fcntl.2 | 23 +++++++ lib/libc/sys/flock.2 | 22 +++++++ lib/libc/sys/fsync.2 | 22 +++++++ lib/libc/sys/ftruncate.c | 16 +++++ lib/libc/sys/getdirentries.2 | 22 +++++++ lib/libc/sys/getpeername.2 | 22 +++++++ lib/libc/sys/getsockname.2 | 22 +++++++ lib/libc/sys/getsockopt.2 | 45 +++++++++++++- lib/libc/sys/intro.2 | 44 ++++++++++++-- lib/libc/sys/ioctl.2 | 22 +++++++ lib/libc/sys/listen.2 | 24 +++++++- lib/libc/sys/lseek.c | 17 +++++- lib/libc/sys/open.2 | 20 +++++++ lib/libc/sys/read.2 | 47 +++++++++++++++ lib/libc/sys/write.2 | 47 +++++++++++++++ sys/sys/errno.h | 7 ++- 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 @@ -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 @@ -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 #include +#ifdef _THREAD_SAFE +#include +#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 #include #include +#ifdef _THREAD_SAFE +#include +#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 #include #include +#include #include +#include #include #include #include +#ifdef _THREAD_SAFE +#include +#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 #include #include - +#ifdef _THREAD_SAFE +#include +#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 @@ -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 #undef clearerr +#ifdef _THREAD_SAFE +#include +#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 #include #include "local.h" +#ifdef _THREAD_SAFE +#include +#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 #include #include "local.h" +#ifdef _THREAD_SAFE +#include +#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 +#ifdef _THREAD_SAFE +#include +#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 +#ifdef _THREAD_SAFE +#include +#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 #include +#include "local.h" +#ifdef _THREAD_SAFE +#include +#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 #include #include "local.h" +#ifdef _THREAD_SAFE +#include +#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 +#ifdef _THREAD_SAFE +#include +#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 #include #include "fvwrite.h" +#ifdef _THREAD_SAFE +#include +#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 #include +#include "local.h" +#ifdef _THREAD_SAFE +#include +#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 #endif +#ifdef _THREAD_SAFE +#include +#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; @@ -61,8 +67,14 @@ fscanf(fp, fmt, va_alist) va_list ap; 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 #include #include "local.h" +#ifdef _THREAD_SAFE +#include +#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 #include #include "local.h" +#ifdef _THREAD_SAFE +#include +#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 #include "local.h" #include "fvwrite.h" +#ifdef _THREAD_SAFE +#include +#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 +#ifdef _THREAD_SAFE +#include +#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 +#ifdef _THREAD_SAFE +#include +#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 +#ifdef _THREAD_SAFE +#include +#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 +#ifdef _THREAD_SAFE +#include +#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 #include #include "fvwrite.h" +#ifdef _THREAD_SAFE +#include +#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 #include "fvwrite.h" +#ifdef _THREAD_SAFE +#include +#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 #include +#ifdef _THREAD_SAFE +#include +#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 #endif +#ifdef _THREAD_SAFE +#include +#include "pthread_private.h" +#endif #if __STDC__ +int scanf(char const *fmt, ...) #else +int scanf(fmt, va_alist) char *fmt; va_dcl @@ -60,8 +66,14 @@ scanf(fmt, va_alist) va_start(ap, fmt); #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 #include #include "local.h" +#ifdef _THREAD_SAFE +#include +#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 #include #include "local.h" +#ifdef _THREAD_SAFE +#include +#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 +#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 +#ifdef _THREAD_SAFE +#include +#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 +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 #include +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 #include #include +#ifdef _THREAD_SAFE +#include +#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 #include #include +#ifdef _THREAD_SAFE +#include +#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 +#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 #include +#include +#ifdef _THREAD_SAFE +#include +#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 .\" .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 #include +#include +#ifdef _THREAD_SAFE +#include +#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 */ -- cgit v1.2.3