diff options
Diffstat (limited to 'lib')
85 files changed, 1634 insertions, 108 deletions
diff --git a/lib/csu/i386/crt0.c b/lib/csu/i386/crt0.c index ecafd5d..2cd03c3 100644 --- a/lib/csu/i386/crt0.c +++ b/lib/csu/i386/crt0.c @@ -27,7 +27,7 @@ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * - * $Id: crt0.c,v 1.20 1995/10/29 09:49:21 phk Exp $ + * $Id: crt0.c,v 1.21 1995/11/02 12:42:42 ache Exp $ */ #include <sys/param.h> @@ -98,6 +98,7 @@ extern start() asm("start"); extern mcount() asm ("mcount"); extern int main(int argc, char **argv, char **envp); int __syscall(int syscall,...); +void _thread_init(); #ifdef MCRT0 void monstartup(void *low, void *high); #endif /* MCRT0 */ @@ -181,6 +182,13 @@ asm("eprol:"); monstartup(&eprol, &etext); #endif /* MCRT0 */ + /* + * Initialize the initial thread. + * This function might be a stub if libc does not + * contain thread support. + */ + _thread_init(); + asm ("__callmain:"); /* Defined for the benefit of debuggers */ exit(main(kfp->kargc, argv, environ)); } diff --git a/lib/libc/amd64/SYS.h b/lib/libc/amd64/SYS.h index 53837ab..9e989e5 100644 --- a/lib/libc/amd64/SYS.h +++ b/lib/libc/amd64/SYS.h @@ -35,7 +35,7 @@ * * from: @(#)SYS.h 5.5 (Berkeley) 5/7/91 * - * $Id: SYS.h,v 1.3 1993/11/04 00:01:17 paul Exp $ + * $Id: SYS.h,v 1.2 1994/08/05 01:17:57 wollman Exp $ */ #include <sys/syscall.h> @@ -63,6 +63,21 @@ #define SYSCALL(x) 2: jmp cerror; ENTRY(x); lea SYS_/**/x,%eax; LCALL(7,0); jb 2b #define RSYSCALL(x) SYSCALL(x); ret + +#ifdef _THREAD_SAFE +/* + * Support for user-space threads which require that some syscalls be + * private to the threaded library. + */ +#define PSYSCALL(x) 2: jmp cerror; ENTRY(_thread_sys_/**/x); lea SYS_/**/x,%eax; LCALL(7,0); jb 2b +#else +/* + * The non-threaded library defaults to traditional syscalls where + * the function name matches the syscall name. + */ +#define PSYSCALL(x) SYSCALL(x) +#endif +#define PRSYSCALL(x) PSYSCALL(x); ret #define PSEUDO(x,y) ENTRY(x); lea SYS_/**/y, %eax; ; LCALL(7,0); ret #define CALL(x,y) call _/**/y; addl $4*x,%esp /* gas fucks up offset -- although we don't currently need it, do for BCS */ diff --git a/lib/libc/amd64/gen/_setjmp.S b/lib/libc/amd64/gen/_setjmp.S index abd2684..23a2cde 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 fa52b83..89efa92 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 4f592a3..1e15101 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 875f6db..2cbb0f9 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 cf3264c..809445f 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 ac0ffd6..6f3f571 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 06e3eb6..341b75c 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 6a23f3d..76da99c 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 1c80f83..8664bd4 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 89b9916..2b54402 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 69a434d..3809f44 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 f6bb04b..c8356c7 100644 --- a/lib/libc/gen/isatty.c +++ b/lib/libc/gen/isatty.c @@ -37,12 +37,27 @@ static char sccsid[] = "@(#)isatty.c 8.1 (Berkeley) 6/4/93"; #include <termios.h> #include <unistd.h> +#ifdef _THREAD_SAFE +#include <pthread.h> +#include "pthread_private.h" +#endif int isatty(fd) int fd; { + int retval; struct termios t; - return(tcgetattr(fd, &t) != -1); +#ifdef _THREAD_SAFE + if (_thread_fd_lock(fd, FD_READ, NULL,__FILE__,__LINE__) == 0) { +#endif + retval = (tcgetattr(fd, &t) != -1); +#ifdef _THREAD_SAFE + _thread_fd_unlock(fd, FD_READ); + } else { + retval = 0; + } +#endif + return(retval); } diff --git a/lib/libc/gen/sleep.c b/lib/libc/gen/sleep.c index 98d997d..b06475d 100644 --- a/lib/libc/gen/sleep.c +++ b/lib/libc/gen/sleep.c @@ -38,16 +38,33 @@ static char sccsid[] = "@(#)sleep.c 8.1 (Berkeley) 6/4/93"; #include <sys/time.h> #include <signal.h> #include <unistd.h> +#ifdef _THREAD_SAFE +#include <pthread.h> +#include "pthread_private.h" +#else #define setvec(vec, a) \ vec.sv_handler = a; vec.sv_mask = vec.sv_onstack = 0 static int ringring; +#endif unsigned int sleep(seconds) unsigned int seconds; { +#ifdef _THREAD_SAFE + struct timespec time_to_sleep; + struct timespec time_remaining; + + if (seconds) { + time_to_sleep.ts_sec = seconds; + time_to_sleep.ts_nsec = 0; + nanosleep(&time_to_sleep,&time_remaining); + seconds = time_remaining.ts_sec; + } + return(seconds); +#else register struct itimerval *itp; struct itimerval itv, oitv; struct sigvec vec, ovec; @@ -88,10 +105,13 @@ sleep(seconds) (void) sigsetmask(omask); (void) setitimer(ITIMER_REAL, &oitv, (struct itimerval *)0); return 0; +#endif } +#ifndef _THREAD_SAFE static void sleephandler() { ringring = 1; } +#endif diff --git a/lib/libc/gen/ttyname.c b/lib/libc/gen/ttyname.c index f024f52..39c640e 100644 --- a/lib/libc/gen/ttyname.c +++ b/lib/libc/gen/ttyname.c @@ -39,11 +39,121 @@ static char sccsid[] = "@(#)ttyname.c 8.2 (Berkeley) 1/27/94"; #include <sys/stat.h> #include <fcntl.h> #include <dirent.h> +#include <stdlib.h> #include <termios.h> +#include <unistd.h> #include <db.h> #include <string.h> #include <paths.h> +#ifdef _THREAD_SAFE +#include <pthread.h> +#include "pthread_private.h" +static pthread_mutex_t ttyname_lock = PTHREAD_MUTEX_INITIALIZER; +static pthread_key_t ttyname_key; +static int ttyname_init = 0; + +char * +ttyname(int fd) +{ + char *ret; + + if (_thread_fd_lock(fd, FD_READ, NULL, __FILE__, __LINE__) == 0) { + ret = __ttyname_basic(fd); + _thread_fd_unlock(fd, FD_READ); + } else { + ret = NULL; + } + + return (ret); +} + +char * +__ttyname_r_basic(int fd, char *buf, size_t len) +{ + register struct dirent *dirp; + register DIR *dp; + struct stat dsb; + struct stat sb; + char *rval; + int minlen; + + rval = NULL; + + /* Must be a terminal. */ + if (!isatty(fd)) + return (rval); + /* Must be a character device. */ + if (_thread_sys_fstat(fd, &sb) || !S_ISCHR(sb.st_mode)) + return (rval); + /* Must have enough room */ + if (len <= sizeof(_PATH_DEV)) + return (rval); + + if ((dp = opendir(_PATH_DEV)) != NULL) { + memcpy(buf, _PATH_DEV, sizeof(_PATH_DEV)); + for (rval = NULL; (dirp = readdir(dp)) != NULL;) { + if (dirp->d_fileno != sb.st_ino) + continue; + minlen = (len - (sizeof(_PATH_DEV) - 1)) < (dirp->d_namlen + 1) ? + (len - (sizeof(_PATH_DEV) - 1)) : (dirp->d_namlen + 1); + memcpy(buf + sizeof(_PATH_DEV) - 1, dirp->d_name, minlen); + if (stat(buf, &dsb) || sb.st_dev != dsb.st_dev || + sb.st_ino != dsb.st_ino) + continue; + rval = buf; + break; + } + (void) closedir(dp); + } + return (rval); +} + +char * +__ttyname_basic(int fd) +{ + char *buf; + + pthread_mutex_lock(&ttyname_lock); + if (ttyname_init == 0) { + if (pthread_keycreate(&ttyname_key, free)) { + pthread_mutex_unlock(&ttyname_lock); + return (NULL); + } + ttyname_init = 1; + } + pthread_mutex_unlock(&ttyname_lock); + + /* Must have thread specific data field to put data */ + if (pthread_getspecific(ttyname_key, (void **) &buf) != 0) { + return (NULL); + } else if (buf == NULL) { + if ((buf = malloc(sizeof(_PATH_DEV) + MAXNAMLEN)) != NULL) { + if (pthread_setspecific(ttyname_key, buf) != 0) { + free(buf); + return (NULL); + } + } else { + return (NULL); + } + } + return (__ttyname_r_basic(fd, buf, sizeof(_PATH_DEV) + MAXNAMLEN)); +} + +char * +ttyname_r(int fd, char *buf, size_t len) +{ + char *ret; + + if (_thread_fd_lock(fd, FD_READ, NULL, __FILE__, __LINE__) == 0) { + ret = __ttyname_r_basic(fd, buf, len); + _thread_fd_unlock(fd, FD_READ); + } else { + ret = NULL; + } + return (ret); +} +#else static char buf[sizeof(_PATH_DEV) + MAXNAMLEN] = _PATH_DEV; static char *oldttyname __P((int, struct stat *)); @@ -110,3 +220,4 @@ oldttyname(fd, sb) (void)closedir(dp); return (NULL); } +#endif diff --git a/lib/libc/gen/usleep.c b/lib/libc/gen/usleep.c index 3f4a7f5..9e29f31 100644 --- a/lib/libc/gen/usleep.c +++ b/lib/libc/gen/usleep.c @@ -38,7 +38,10 @@ static char sccsid[] = "@(#)usleep.c 8.1 (Berkeley) 6/4/93"; #include <sys/time.h> #include <signal.h> #include <unistd.h> - +#ifdef _THREAD_SAFE +#include <pthread.h> +#include "pthread_private.h" +#else #define TICK 10000 /* system clock resolution in microseconds */ #define USPS 1000000 /* number of microseconds in a second */ @@ -46,11 +49,22 @@ static char sccsid[] = "@(#)usleep.c 8.1 (Berkeley) 6/4/93"; vec.sv_handler = a; vec.sv_mask = vec.sv_onstack = 0 static int ringring; +#endif + void usleep(useconds) unsigned int useconds; { +#ifdef _THREAD_SAFE + struct timespec time_to_sleep; + + if (useconds) { + time_to_sleep.ts_nsec = (useconds % 1000000) * 1000; + time_to_sleep.ts_sec = useconds / 1000000; + nanosleep(&time_to_sleep,NULL); + } +#else register struct itimerval *itp; struct itimerval itv, oitv; struct sigvec vec, ovec; @@ -90,10 +104,13 @@ usleep(useconds) (void) sigvec(SIGALRM, &ovec, (struct sigvec *)0); (void) sigsetmask(omask); (void) setitimer(ITIMER_REAL, &oitv, (struct itimerval *)0); +#endif } +#ifndef _THREAD_SAFE static void sleephandler() { ringring = 1; } +#endif diff --git a/lib/libc/i386/SYS.h b/lib/libc/i386/SYS.h index 53837ab..9e989e5 100644 --- a/lib/libc/i386/SYS.h +++ b/lib/libc/i386/SYS.h @@ -35,7 +35,7 @@ * * from: @(#)SYS.h 5.5 (Berkeley) 5/7/91 * - * $Id: SYS.h,v 1.3 1993/11/04 00:01:17 paul Exp $ + * $Id: SYS.h,v 1.2 1994/08/05 01:17:57 wollman Exp $ */ #include <sys/syscall.h> @@ -63,6 +63,21 @@ #define SYSCALL(x) 2: jmp cerror; ENTRY(x); lea SYS_/**/x,%eax; LCALL(7,0); jb 2b #define RSYSCALL(x) SYSCALL(x); ret + +#ifdef _THREAD_SAFE +/* + * Support for user-space threads which require that some syscalls be + * private to the threaded library. + */ +#define PSYSCALL(x) 2: jmp cerror; ENTRY(_thread_sys_/**/x); lea SYS_/**/x,%eax; LCALL(7,0); jb 2b +#else +/* + * The non-threaded library defaults to traditional syscalls where + * the function name matches the syscall name. + */ +#define PSYSCALL(x) SYSCALL(x) +#endif +#define PRSYSCALL(x) PSYSCALL(x); ret #define PSEUDO(x,y) ENTRY(x); lea SYS_/**/y, %eax; ; LCALL(7,0); ret #define CALL(x,y) call _/**/y; addl $4*x,%esp /* gas fucks up offset -- although we don't currently need it, do for BCS */ diff --git a/lib/libc/i386/gen/_setjmp.S b/lib/libc/i386/gen/_setjmp.S index abd2684..23a2cde 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 fa52b83..89efa92 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 4f592a3..1e15101 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 06e3eb6..341b75c 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 875f6db..2cbb0f9 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 fe4c36d..567aa4c 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 cf3264c..809445f 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 fdc1e9f..dba82ee 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 1757a3a..69c50a4 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 ac0ffd6..6f3f571 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 a72154a..4d70ea6 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 de4526e..a597b7b 100644 --- a/lib/libc/stdio/clrerr.c +++ b/lib/libc/stdio/clrerr.c @@ -40,10 +40,20 @@ static char sccsid[] = "@(#)clrerr.c 8.1 (Berkeley) 6/4/93"; #include <stdio.h> #undef clearerr +#ifdef _THREAD_SAFE +#include <pthread.h> +#include "pthread_private.h" +#endif void clearerr(fp) FILE *fp; { +#ifdef _THREAD_SAFE + _thread_flockfile(fp,__FILE__,__LINE__); +#endif __sclearerr(fp); +#ifdef _THREAD_SAFE + _thread_funlockfile(fp); +#endif } diff --git a/lib/libc/stdio/fclose.c b/lib/libc/stdio/fclose.c index 8315c3c..be92108 100644 --- a/lib/libc/stdio/fclose.c +++ b/lib/libc/stdio/fclose.c @@ -42,7 +42,12 @@ static char sccsid[] = "@(#)fclose.c 8.1 (Berkeley) 6/4/93"; #include <stdio.h> #include <stdlib.h> #include "local.h" +#ifdef _THREAD_SAFE +#include <pthread.h> +#include "pthread_private.h" +#endif +int fclose(fp) register FILE *fp; { @@ -52,6 +57,9 @@ fclose(fp) errno = EBADF; return (EOF); } +#ifdef _THREAD_SAFE + _thread_flockfile(fp,__FILE__,__LINE__); +#endif r = fp->_flags & __SWR ? __sflush(fp) : 0; if (fp->_close != NULL && (*fp->_close)(fp->_cookie) < 0) r = EOF; @@ -61,7 +69,11 @@ fclose(fp) FREEUB(fp); if (HASLB(fp)) FREELB(fp); +#ifdef _THREAD_SAFE + _thread_funlockfile(fp); +#endif fp->_flags = 0; /* Release this FILE for reuse. */ + fp->_file = -1; fp->_r = fp->_w = 0; /* Mess up if reaccessed. */ return (r); } diff --git a/lib/libc/stdio/fflush.c b/lib/libc/stdio/fflush.c index 4a5cf0f..fce8932 100644 --- a/lib/libc/stdio/fflush.c +++ b/lib/libc/stdio/fflush.c @@ -41,21 +41,36 @@ static char sccsid[] = "@(#)fflush.c 8.1 (Berkeley) 6/4/93"; #include <errno.h> #include <stdio.h> #include "local.h" +#ifdef _THREAD_SAFE +#include <pthread.h> +#include "pthread_private.h" +#endif /* Flush a single file, or (if fp is NULL) all files. */ +int fflush(fp) register FILE *fp; { + int retval; if (fp == NULL) return (_fwalk(__sflush)); +#ifdef _THREAD_SAFE + _thread_flockfile(fp,__FILE__,__LINE__); +#endif if ((fp->_flags & (__SWR | __SRW)) == 0) { errno = EBADF; - return (EOF); + retval = EOF; + } else { + retval = __sflush(fp); } - return (__sflush(fp)); +#ifdef _THREAD_SAFE + _thread_funlockfile(fp); +#endif + return (retval); } +int __sflush(fp) register FILE *fp; { diff --git a/lib/libc/stdio/fgetc.c b/lib/libc/stdio/fgetc.c index 800846c..7e2738f 100644 --- a/lib/libc/stdio/fgetc.c +++ b/lib/libc/stdio/fgetc.c @@ -39,9 +39,22 @@ static char sccsid[] = "@(#)fgetc.c 8.1 (Berkeley) 6/4/93"; #endif /* LIBC_SCCS and not lint */ #include <stdio.h> +#ifdef _THREAD_SAFE +#include <pthread.h> +#include "pthread_private.h" +#endif +int fgetc(fp) FILE *fp; { - return (__sgetc(fp)); + int retval; +#ifdef _THREAD_SAFE + _thread_flockfile(fp,__FILE__,__LINE__); +#endif + retval = __sgetc(fp); +#ifdef _THREAD_SAFE + _thread_funlockfile(fp); +#endif + return (retval); } diff --git a/lib/libc/stdio/fgetpos.c b/lib/libc/stdio/fgetpos.c index 1f4ec1d..4ac0be4 100644 --- a/lib/libc/stdio/fgetpos.c +++ b/lib/libc/stdio/fgetpos.c @@ -39,10 +39,23 @@ static char sccsid[] = "@(#)fgetpos.c 8.1 (Berkeley) 6/4/93"; #endif /* LIBC_SCCS and not lint */ #include <stdio.h> +#ifdef _THREAD_SAFE +#include <pthread.h> +#include "pthread_private.h" +#endif +int fgetpos(fp, pos) FILE *fp; fpos_t *pos; { - return((*pos = ftell(fp)) == (fpos_t)-1); + int retval; +#ifdef _THREAD_SAFE + _thread_flockfile(fp,__FILE__,__LINE__); +#endif + retval = (*pos = ftell(fp)) == (fpos_t)-1; +#ifdef _THREAD_SAFE + _thread_funlockfile(fp); +#endif + return(retval); } diff --git a/lib/libc/stdio/fgets.c b/lib/libc/stdio/fgets.c index 09f6877..c478267 100644 --- a/lib/libc/stdio/fgets.c +++ b/lib/libc/stdio/fgets.c @@ -40,6 +40,11 @@ static char sccsid[] = "@(#)fgets.c 8.2 (Berkeley) 12/22/93"; #include <stdio.h> #include <string.h> +#include "local.h" +#ifdef _THREAD_SAFE +#include <pthread.h> +#include "pthread_private.h" +#endif /* * Read at most n-1 characters from the given file. @@ -59,6 +64,9 @@ fgets(buf, n, fp) if (n == 0) /* sanity check */ return (NULL); +#ifdef _THREAD_SAFE + _thread_flockfile(fp,__FILE__,__LINE__); +#endif s = buf; n--; /* leave space for NUL */ while (n != 0) { @@ -68,8 +76,12 @@ fgets(buf, n, fp) if ((len = fp->_r) <= 0) { if (__srefill(fp)) { /* EOF/error: stop with partial or no line */ - if (s == buf) + if (s == buf) { +#ifdef _THREAD_SAFE + _thread_funlockfile(fp); +#endif return (NULL); + } break; } len = fp->_r; @@ -91,6 +103,9 @@ fgets(buf, n, fp) fp->_p = t; (void)memcpy((void *)s, (void *)p, len); s[len] = 0; +#ifdef _THREAD_SAFE + _thread_funlockfile(fp); +#endif return (buf); } fp->_r -= len; @@ -100,5 +115,8 @@ fgets(buf, n, fp) n -= len; } *s = 0; +#ifdef _THREAD_SAFE + _thread_funlockfile(fp); +#endif return (buf); } diff --git a/lib/libc/stdio/fpurge.c b/lib/libc/stdio/fpurge.c index 3bee513..7cf54ff 100644 --- a/lib/libc/stdio/fpurge.c +++ b/lib/libc/stdio/fpurge.c @@ -42,6 +42,10 @@ static char sccsid[] = "@(#)fpurge.c 8.1 (Berkeley) 6/4/93"; #include <stdio.h> #include <stdlib.h> #include "local.h" +#ifdef _THREAD_SAFE +#include <pthread.h> +#include "pthread_private.h" +#endif /* * fpurge: like fflush, but without writing anything: leave the @@ -51,15 +55,23 @@ int fpurge(fp) register FILE *fp; { + int retval; +#ifdef _THREAD_SAFE + _thread_flockfile(fp,__FILE__,__LINE__); +#endif if (!fp->_flags) { errno = EBADF; - return(EOF); + retval = EOF; + } else { + if (HASUB(fp)) + FREEUB(fp); + fp->_p = fp->_bf._base; + fp->_r = 0; + fp->_w = fp->_flags & (__SLBF|__SNBF) ? 0 : fp->_bf._size; + retval = 0; } - - if (HASUB(fp)) - FREEUB(fp); - fp->_p = fp->_bf._base; - fp->_r = 0; - fp->_w = fp->_flags & (__SLBF|__SNBF) ? 0 : fp->_bf._size; - return (0); +#ifdef _THREAD_SAFE + _thread_funlockfile(fp); +#endif + return (retval); } diff --git a/lib/libc/stdio/fputc.c b/lib/libc/stdio/fputc.c index c86f711..09b55d5 100644 --- a/lib/libc/stdio/fputc.c +++ b/lib/libc/stdio/fputc.c @@ -39,10 +39,23 @@ static char sccsid[] = "@(#)fputc.c 8.1 (Berkeley) 6/4/93"; #endif /* LIBC_SCCS and not lint */ #include <stdio.h> +#ifdef _THREAD_SAFE +#include <pthread.h> +#include "pthread_private.h" +#endif +int fputc(c, fp) int c; register FILE *fp; { - return (putc(c, fp)); + int retval; +#ifdef _THREAD_SAFE + _thread_flockfile(fp,__FILE__,__LINE__); +#endif + retval = putc(c, fp); +#ifdef _THREAD_SAFE + _thread_funlockfile(fp); +#endif + return (retval); } diff --git a/lib/libc/stdio/fputs.c b/lib/libc/stdio/fputs.c index 9f9be2e..92fcc30 100644 --- a/lib/libc/stdio/fputs.c +++ b/lib/libc/stdio/fputs.c @@ -41,14 +41,20 @@ static char sccsid[] = "@(#)fputs.c 8.1 (Berkeley) 6/4/93"; #include <stdio.h> #include <string.h> #include "fvwrite.h" +#ifdef _THREAD_SAFE +#include <pthread.h> +#include "pthread_private.h" +#endif /* * Write the given string to the given file. */ +int fputs(s, fp) const char *s; FILE *fp; { + int retval; struct __suio uio; struct __siov iov; @@ -56,5 +62,12 @@ fputs(s, fp) iov.iov_len = uio.uio_resid = strlen(s); uio.uio_iov = &iov; uio.uio_iovcnt = 1; - return (__sfvwrite(fp, &uio)); +#ifdef _THREAD_SAFE + _thread_flockfile(fp,__FILE__,__LINE__); +#endif + retval = __sfvwrite(fp, &uio); +#ifdef _THREAD_SAFE + _thread_funlockfile(fp); +#endif + return (retval); } diff --git a/lib/libc/stdio/fread.c b/lib/libc/stdio/fread.c index 22436ec..7132e85 100644 --- a/lib/libc/stdio/fread.c +++ b/lib/libc/stdio/fread.c @@ -40,6 +40,11 @@ static char sccsid[] = "@(#)fread.c 8.2 (Berkeley) 12/11/93"; #include <stdio.h> #include <string.h> +#include "local.h" +#ifdef _THREAD_SAFE +#include <pthread.h> +#include "pthread_private.h" +#endif size_t fread(buf, size, count, fp) @@ -59,6 +64,9 @@ fread(buf, size, count, fp) */ if ((resid = count * size) == 0) return (0); +#ifdef _THREAD_SAFE + _thread_flockfile(fp,__FILE__,__LINE__); +#endif if (fp->_r < 0) fp->_r = 0; total = resid; @@ -77,5 +85,8 @@ fread(buf, size, count, fp) (void)memcpy((void *)p, (void *)fp->_p, resid); fp->_r -= resid; fp->_p += resid; +#ifdef _THREAD_SAFE + _thread_funlockfile(fp); +#endif return (count); } diff --git a/lib/libc/stdio/fscanf.c b/lib/libc/stdio/fscanf.c index f0e726a..bbb3155 100644 --- a/lib/libc/stdio/fscanf.c +++ b/lib/libc/stdio/fscanf.c @@ -44,14 +44,20 @@ static char sccsid[] = "@(#)fscanf.c 8.1 (Berkeley) 6/4/93"; #else #include <varargs.h> #endif +#ifdef _THREAD_SAFE +#include <pthread.h> +#include "pthread_private.h" +#endif #if __STDC__ +int fscanf(FILE *fp, char const *fmt, ...) { int ret; va_list ap; va_start(ap, fmt); #else +int fscanf(fp, fmt, va_alist) FILE *fp; char *fmt; @@ -62,7 +68,13 @@ fscanf(fp, fmt, va_alist) va_start(ap); #endif +#ifdef _THREAD_SAFE + _thread_flockfile(fp,__FILE__,__LINE__); +#endif ret = __svfscanf(fp, fmt, ap); va_end(ap); +#ifdef _THREAD_SAFE + _thread_funlockfile(fp); +#endif return (ret); } diff --git a/lib/libc/stdio/fseek.c b/lib/libc/stdio/fseek.c index 9cb04ad..1e99de9 100644 --- a/lib/libc/stdio/fseek.c +++ b/lib/libc/stdio/fseek.c @@ -45,6 +45,10 @@ static char sccsid[] = "@(#)fseek.c 8.3 (Berkeley) 1/2/94"; #include <stdlib.h> #include <errno.h> #include "local.h" +#ifdef _THREAD_SAFE +#include <pthread.h> +#include "pthread_private.h" +#endif #define POS_ERR (-(fpos_t)1) @@ -68,6 +72,9 @@ fseek(fp, offset, whence) if (!__sdidinit) __sinit(); +#ifdef _THREAD_SAFE + _thread_flockfile(fp,__FILE__,__LINE__); +#endif /* * Have to be able to seek. */ @@ -92,8 +99,12 @@ fseek(fp, offset, whence) curoff = fp->_offset; else { curoff = (*seekfn)(fp->_cookie, (fpos_t)0, SEEK_CUR); - if (curoff == -1L) + if (curoff == -1L) { +#ifdef _THREAD_SAFE + _thread_funlockfile(fp); +#endif return (EOF); + } } if (fp->_flags & __SRD) { curoff -= fp->_r; @@ -115,6 +126,9 @@ fseek(fp, offset, whence) default: errno = EINVAL; +#ifdef _THREAD_SAFE + _thread_funlockfile(fp); +#endif return (EOF); } @@ -198,6 +212,9 @@ fseek(fp, offset, whence) if (HASUB(fp)) FREEUB(fp); fp->_flags &= ~__SEOF; +#ifdef _THREAD_SAFE + _thread_funlockfile(fp); +#endif return (0); } @@ -224,6 +241,9 @@ fseek(fp, offset, whence) fp->_p += n; fp->_r -= n; } +#ifdef _THREAD_SAFE + _thread_funlockfile(fp); +#endif return (0); /* @@ -233,6 +253,9 @@ fseek(fp, offset, whence) dumb: if (__sflush(fp) || (*seekfn)(fp->_cookie, (fpos_t)offset, whence) == POS_ERR) { +#ifdef _THREAD_SAFE + _thread_funlockfile(fp); +#endif return (EOF); } /* success: clear EOF indicator and discard ungetc() data */ @@ -242,5 +265,8 @@ dumb: fp->_r = 0; /* fp->_w = 0; */ /* unnecessary (I think...) */ fp->_flags &= ~__SEOF; +#ifdef _THREAD_SAFE + _thread_funlockfile(fp); +#endif return (0); } diff --git a/lib/libc/stdio/ftell.c b/lib/libc/stdio/ftell.c index 724e543..271490a 100644 --- a/lib/libc/stdio/ftell.c +++ b/lib/libc/stdio/ftell.c @@ -41,6 +41,10 @@ static char sccsid[] = "@(#)ftell.c 8.1 (Berkeley) 6/4/93"; #include <stdio.h> #include <errno.h> #include "local.h" +#ifdef _THREAD_SAFE +#include <pthread.h> +#include "pthread_private.h" +#endif /* * ftell: return current offset. @@ -56,6 +60,9 @@ ftell(fp) return (-1L); } +#ifdef _THREAD_SAFE + _thread_flockfile((FILE *) fp,__FILE__,__LINE__); +#endif /* * Find offset of underlying I/O object, then * adjust for buffered bytes. @@ -64,8 +71,12 @@ ftell(fp) pos = fp->_offset; else { pos = (*fp->_seek)(fp->_cookie, (fpos_t)0, SEEK_CUR); - if (pos == -1L) + if (pos == -1L) { +#ifdef _THREAD_SAFE + _thread_funlockfile((FILE *) fp); +#endif return (pos); + } } if (fp->_flags & __SRD) { /* @@ -84,5 +95,8 @@ ftell(fp) */ pos += fp->_p - fp->_bf._base; } +#ifdef _THREAD_SAFE + _thread_funlockfile((FILE *) fp); +#endif return (pos); } diff --git a/lib/libc/stdio/fwrite.c b/lib/libc/stdio/fwrite.c index dbc2e97..7efb0ac 100644 --- a/lib/libc/stdio/fwrite.c +++ b/lib/libc/stdio/fwrite.c @@ -41,6 +41,10 @@ static char sccsid[] = "@(#)fwrite.c 8.1 (Berkeley) 6/4/93"; #include <stdio.h> #include "local.h" #include "fvwrite.h" +#ifdef _THREAD_SAFE +#include <pthread.h> +#include "pthread_private.h" +#endif /* * Write `count' objects (each size `size') from memory to the given file. @@ -61,12 +65,18 @@ fwrite(buf, size, count, fp) uio.uio_iov = &iov; uio.uio_iovcnt = 1; +#ifdef _THREAD_SAFE + _thread_flockfile(fp,__FILE__,__LINE__); +#endif /* * The usual case is success (__sfvwrite returns 0); * skip the divide if this happens, since divides are * generally slow and since this occurs whenever size==0. */ - if (__sfvwrite(fp, &uio) == 0) - return (count); - return ((n - uio.uio_resid) / size); + if (__sfvwrite(fp, &uio) != 0) + count = (n - uio.uio_resid) / size; +#ifdef _THREAD_SAFE + _thread_funlockfile(fp); +#endif + return (count); } diff --git a/lib/libc/stdio/getc.c b/lib/libc/stdio/getc.c index 1e900cd..c0726ee 100644 --- a/lib/libc/stdio/getc.c +++ b/lib/libc/stdio/getc.c @@ -39,14 +39,27 @@ static char sccsid[] = "@(#)getc.c 8.1 (Berkeley) 6/4/93"; #endif /* LIBC_SCCS and not lint */ #include <stdio.h> +#ifdef _THREAD_SAFE +#include <pthread.h> +#include "pthread_private.h" +#endif /* * A subroutine version of the macro getc. */ #undef getc +int getc(fp) register FILE *fp; { - return (__sgetc(fp)); + int retval; +#ifdef _THREAD_SAFE + _thread_flockfile(fp,__FILE__,__LINE__); +#endif + retval = __sgetc(fp); +#ifdef _THREAD_SAFE + _thread_funlockfile(fp); +#endif + return (retval); } diff --git a/lib/libc/stdio/getchar.c b/lib/libc/stdio/getchar.c index 20e52b7..7aeef8a 100644 --- a/lib/libc/stdio/getchar.c +++ b/lib/libc/stdio/getchar.c @@ -42,10 +42,23 @@ static char sccsid[] = "@(#)getchar.c 8.1 (Berkeley) 6/4/93"; * A subroutine version of the macro getchar. */ #include <stdio.h> +#ifdef _THREAD_SAFE +#include <pthread.h> +#include "pthread_private.h" +#endif #undef getchar +int getchar() { - return (getc(stdin)); + int retval; +#ifdef _THREAD_SAFE + _thread_flockfile(stdin,__FILE__,__LINE__); +#endif + retval = getc(stdin); +#ifdef _THREAD_SAFE + _thread_funlockfile(stdin); +#endif + return (retval); } diff --git a/lib/libc/stdio/putc.c b/lib/libc/stdio/putc.c index c18353b..f1d42b1 100644 --- a/lib/libc/stdio/putc.c +++ b/lib/libc/stdio/putc.c @@ -39,15 +39,28 @@ static char sccsid[] = "@(#)putc.c 8.1 (Berkeley) 6/4/93"; #endif /* LIBC_SCCS and not lint */ #include <stdio.h> +#ifdef _THREAD_SAFE +#include <pthread.h> +#include "pthread_private.h" +#endif /* * A subroutine version of the macro putc. */ #undef putc +int putc(c, fp) int c; register FILE *fp; { - return (__sputc(c, fp)); + int retval; +#ifdef _THREAD_SAFE + _thread_flockfile(fp,__FILE__,__LINE__); +#endif + retval = __sputc(c, fp); +#ifdef _THREAD_SAFE + _thread_funlockfile(fp); +#endif + return (retval); } diff --git a/lib/libc/stdio/putchar.c b/lib/libc/stdio/putchar.c index 036b897..5e04a6c 100644 --- a/lib/libc/stdio/putchar.c +++ b/lib/libc/stdio/putchar.c @@ -39,16 +39,29 @@ static char sccsid[] = "@(#)putchar.c 8.1 (Berkeley) 6/4/93"; #endif /* LIBC_SCCS and not lint */ #include <stdio.h> +#ifdef _THREAD_SAFE +#include <pthread.h> +#include "pthread_private.h" +#endif #undef putchar /* * A subroutine version of the macro putchar */ +int putchar(c) int c; { + int retval; register FILE *so = stdout; - return (__sputc(c, so)); +#ifdef _THREAD_SAFE + _thread_flockfile(so,__FILE__,__LINE__); +#endif + retval = __sputc(c, so); +#ifdef _THREAD_SAFE + _thread_funlockfile(so); +#endif + return (retval); } diff --git a/lib/libc/stdio/puts.c b/lib/libc/stdio/puts.c index 96a8184..e8a35c5 100644 --- a/lib/libc/stdio/puts.c +++ b/lib/libc/stdio/puts.c @@ -41,13 +41,19 @@ static char sccsid[] = "@(#)puts.c 8.1 (Berkeley) 6/4/93"; #include <stdio.h> #include <string.h> #include "fvwrite.h" +#ifdef _THREAD_SAFE +#include <pthread.h> +#include "pthread_private.h" +#endif /* * Write the given string to stdout, appending a newline. */ +int puts(s) char const *s; { + int retval; size_t c = strlen(s); struct __suio uio; struct __siov iov[2]; @@ -59,5 +65,12 @@ puts(s) uio.uio_resid = c + 1; uio.uio_iov = &iov[0]; uio.uio_iovcnt = 2; - return (__sfvwrite(stdout, &uio) ? EOF : '\n'); +#ifdef _THREAD_SAFE + _thread_flockfile(stdout,__FILE__,__LINE__); +#endif + retval = __sfvwrite(stdout, &uio) ? EOF : '\n'; +#ifdef _THREAD_SAFE + _thread_funlockfile(stdout); +#endif + return (retval); } diff --git a/lib/libc/stdio/putw.c b/lib/libc/stdio/putw.c index 4ba8982..604bed0 100644 --- a/lib/libc/stdio/putw.c +++ b/lib/libc/stdio/putw.c @@ -40,11 +40,17 @@ static char sccsid[] = "@(#)putw.c 8.1 (Berkeley) 6/4/93"; #include <stdio.h> #include "fvwrite.h" +#ifdef _THREAD_SAFE +#include <pthread.h> +#include "pthread_private.h" +#endif +int putw(w, fp) int w; FILE *fp; { + int retval; struct __suio uio; struct __siov iov; @@ -52,5 +58,12 @@ putw(w, fp) iov.iov_len = uio.uio_resid = sizeof(w); uio.uio_iov = &iov; uio.uio_iovcnt = 1; - return (__sfvwrite(fp, &uio)); +#ifdef _THREAD_SAFE + _thread_flockfile(fp,__FILE__,__LINE__); +#endif + retval = __sfvwrite(fp, &uio); +#ifdef _THREAD_SAFE + _thread_funlockfile(fp); +#endif + return (retval); } diff --git a/lib/libc/stdio/rewind.c b/lib/libc/stdio/rewind.c index 4f8391b..f20f619 100644 --- a/lib/libc/stdio/rewind.c +++ b/lib/libc/stdio/rewind.c @@ -40,12 +40,22 @@ static char sccsid[] = "@(#)rewind.c 8.1 (Berkeley) 6/4/93"; #include <errno.h> #include <stdio.h> +#ifdef _THREAD_SAFE +#include <pthread.h> +#include "pthread_private.h" +#endif void rewind(fp) register FILE *fp; { +#ifdef _THREAD_SAFE + _thread_flockfile(fp,__FILE__,__LINE__); +#endif (void) fseek(fp, 0L, SEEK_SET); clearerr(fp); +#ifdef _THREAD_SAFE + _thread_funlockfile(fp); +#endif errno = 0; /* not required, but seems reasonable */ } diff --git a/lib/libc/stdio/scanf.c b/lib/libc/stdio/scanf.c index d36b13a..5faf018 100644 --- a/lib/libc/stdio/scanf.c +++ b/lib/libc/stdio/scanf.c @@ -44,10 +44,16 @@ static char sccsid[] = "@(#)scanf.c 8.1 (Berkeley) 6/4/93"; #else #include <varargs.h> #endif +#ifdef _THREAD_SAFE +#include <pthread.h> +#include "pthread_private.h" +#endif #if __STDC__ +int scanf(char const *fmt, ...) #else +int scanf(fmt, va_alist) char *fmt; va_dcl @@ -61,7 +67,13 @@ scanf(fmt, va_alist) #else va_start(ap); #endif +#ifdef _THREAD_SAFE + _thread_flockfile(stdin,__FILE__,__LINE__); +#endif ret = __svfscanf(stdin, fmt, ap); va_end(ap); +#ifdef _THREAD_SAFE + _thread_funlockfile(stdin); +#endif return (ret); } diff --git a/lib/libc/stdio/setvbuf.c b/lib/libc/stdio/setvbuf.c index 867f9b4..c6c037d 100644 --- a/lib/libc/stdio/setvbuf.c +++ b/lib/libc/stdio/setvbuf.c @@ -41,11 +41,16 @@ static char sccsid[] = "@(#)setvbuf.c 8.2 (Berkeley) 11/16/93"; #include <stdio.h> #include <stdlib.h> #include "local.h" +#ifdef _THREAD_SAFE +#include <pthread.h> +#include "pthread_private.h" +#endif /* * Set one of the three kinds of buffering, optionally including * a buffer. */ +int setvbuf(fp, buf, mode, size) register FILE *fp; char *buf; @@ -65,6 +70,9 @@ setvbuf(fp, buf, mode, size) if ((mode != _IOFBF && mode != _IOLBF) || (int)size < 0) return (EOF); +#ifdef _THREAD_SAFE + _thread_flockfile(fp,__FILE__,__LINE__); +#endif /* * Write current buffer, if any. Discard unread input (including * ungetc data), cancel line buffering, and free old buffer if @@ -116,6 +124,9 @@ nbf: fp->_w = 0; fp->_bf._base = fp->_p = fp->_nbuf; fp->_bf._size = 1; +#ifdef _THREAD_SAFE + _thread_funlockfile(fp); +#endif return (ret); } flags |= __SMBF; @@ -156,5 +167,8 @@ nbf: } __cleanup = _cleanup; +#ifdef _THREAD_SAFE + _thread_funlockfile(fp); +#endif return (ret); } diff --git a/lib/libc/stdio/snprintf.c b/lib/libc/stdio/snprintf.c index 3c3cf7d..82fad1a 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 254064f..e71f7d0 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 bb72744..dc96312 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 deaed75..25f59d7 100644 --- a/lib/libc/stdio/ungetc.c +++ b/lib/libc/stdio/ungetc.c @@ -42,6 +42,10 @@ static char sccsid[] = "@(#)ungetc.c 8.2 (Berkeley) 11/3/93"; #include <stdlib.h> #include <string.h> #include "local.h" +#ifdef _THREAD_SAFE +#include <pthread.h> +#include "pthread_private.h" +#endif /* * Expand the ungetc buffer `in place'. That is, adjust fp->_p when @@ -49,7 +53,7 @@ static char sccsid[] = "@(#)ungetc.c 8.2 (Berkeley) 11/3/93"; * and move the bytes in the buffer around as necessary so that they * are all at the end (stack-style). */ -static +static int __submore(fp) register FILE *fp; { @@ -82,6 +86,7 @@ __submore(fp) return (0); } +int ungetc(c, fp) int c; register FILE *fp; @@ -90,16 +95,27 @@ ungetc(c, fp) return (EOF); if (!__sdidinit) __sinit(); +#ifdef _THREAD_SAFE + _thread_flockfile(fp,__FILE__,__LINE__); +#endif if ((fp->_flags & __SRD) == 0) { /* * Not already reading: no good unless reading-and-writing. * Otherwise, flush any current write stuff. */ - if ((fp->_flags & __SRW) == 0) + if ((fp->_flags & __SRW) == 0) { +#ifdef _THREAD_SAFE + _thread_funlockfile(fp); +#endif return (EOF); + } if (fp->_flags & __SWR) { - if (__sflush(fp)) + if (__sflush(fp)) { +#ifdef _THREAD_SAFE + _thread_funlockfile(fp); +#endif return (EOF); + } fp->_flags &= ~__SWR; fp->_w = 0; fp->_lbfsize = 0; @@ -113,10 +129,17 @@ ungetc(c, fp) * This may require expanding the current ungetc buffer. */ if (HASUB(fp)) { - if (fp->_r >= fp->_ub._size && __submore(fp)) + if (fp->_r >= fp->_ub._size && __submore(fp)) { +#ifdef _THREAD_SAFE + _thread_funlockfile(fp); +#endif return (EOF); + } *--fp->_p = c; fp->_r++; +#ifdef _THREAD_SAFE + _thread_funlockfile(fp); +#endif return (c); } fp->_flags &= ~__SEOF; @@ -130,6 +153,9 @@ ungetc(c, fp) fp->_p[-1] == c) { fp->_p--; fp->_r++; +#ifdef _THREAD_SAFE + _thread_funlockfile(fp); +#endif return (c); } @@ -144,5 +170,8 @@ ungetc(c, fp) fp->_ubuf[sizeof(fp->_ubuf) - 1] = c; fp->_p = &fp->_ubuf[sizeof(fp->_ubuf) - 1]; fp->_r = 1; +#ifdef _THREAD_SAFE + _thread_funlockfile(fp); +#endif return (c); } diff --git a/lib/libc/stdio/vfprintf.c b/lib/libc/stdio/vfprintf.c index f53db61..3c3d4d3 100644 --- a/lib/libc/stdio/vfprintf.c +++ b/lib/libc/stdio/vfprintf.c @@ -59,6 +59,10 @@ static char sccsid[] = "@(#)vfprintf.c 8.1 (Berkeley) 6/4/93"; #include "local.h" #include "fvwrite.h" +#ifdef _THREAD_SAFE +#include <pthread.h> +#include "pthread_private.h" +#endif /* Define FLOATING_POINT to get floating point. */ #define FLOATING_POINT @@ -366,14 +370,25 @@ vfprintf(fp, fmt0, ap) flags&SHORTINT ? (u_long)(u_short)va_arg(ap, int) : \ (u_long)va_arg(ap, u_int)) +#ifdef _THREAD_SAFE + _thread_flockfile(fp,__FILE__,__LINE__); +#endif /* sorry, fprintf(read_only_file, "") returns EOF, not 0 */ - if (cantwrite(fp)) + if (cantwrite(fp)) { +#ifdef _THREAD_SAFE + _thread_funlockfile(fp); +#endif return (EOF); + } /* optimise fprintf(stderr) (and other unbuffered Unix files) */ if ((fp->_flags & (__SNBF|__SWR|__SRW)) == (__SNBF|__SWR) && - fp->_file >= 0) + fp->_file >= 0) { +#ifdef _THREAD_SAFE + _thread_funlockfile(fp); +#endif return (__sbprintf(fp, fmt0, ap)); + } fmt = (char *)fmt0; uio.uio_iov = iovp = iov; @@ -782,7 +797,12 @@ number: if ((dprec = prec) >= 0) done: FLUSH(); error: - return (__sferror(fp) ? EOF : ret); + if (__sferror(fp)) + ret = EOF; +#ifdef _THREAD_SAFE + _thread_funlockfile(fp); +#endif + return (ret); /* NOTREACHED */ } diff --git a/lib/libc/stdio/vscanf.c b/lib/libc/stdio/vscanf.c index 5d12865..677039e 100644 --- a/lib/libc/stdio/vscanf.c +++ b/lib/libc/stdio/vscanf.c @@ -39,11 +39,24 @@ static char sccsid[] = "@(#)vscanf.c 8.1 (Berkeley) 6/4/93"; #endif /* LIBC_SCCS and not lint */ #include <stdio.h> +#ifdef _THREAD_SAFE +#include <pthread.h> +#include "pthread_private.h" +#endif +int vscanf(fmt, ap) const char *fmt; _BSD_VA_LIST_ ap; { + int retval; - return (__svfscanf(stdin, fmt, ap)); +#ifdef _THREAD_SAFE + _thread_flockfile(stdin,__FILE__,__LINE__); +#endif + retval = __svfscanf(stdin, fmt, ap); +#ifdef _THREAD_SAFE + _thread_funlockfile(stdin); +#endif + return (retval); } diff --git a/lib/libc/stdio/vsnprintf.c b/lib/libc/stdio/vsnprintf.c index ccc8af6..1bff18b 100644 --- a/lib/libc/stdio/vsnprintf.c +++ b/lib/libc/stdio/vsnprintf.c @@ -40,6 +40,7 @@ static char sccsid[] = "@(#)vsnprintf.c 8.1 (Berkeley) 6/4/93"; #include <stdio.h> +int vsnprintf(str, n, fmt, ap) char *str; size_t n; @@ -51,6 +52,7 @@ vsnprintf(str, n, fmt, ap) if ((int)n < 1) return (EOF); + f._file = -1; f._flags = __SWR | __SSTR; f._bf._base = f._p = (unsigned char *)str; f._bf._size = f._w = n - 1; diff --git a/lib/libc/stdio/vsprintf.c b/lib/libc/stdio/vsprintf.c index c6e192a..cdfb9eb 100644 --- a/lib/libc/stdio/vsprintf.c +++ b/lib/libc/stdio/vsprintf.c @@ -41,6 +41,7 @@ static char sccsid[] = "@(#)vsprintf.c 8.1 (Berkeley) 6/4/93"; #include <stdio.h> #include <limits.h> +int vsprintf(str, fmt, ap) char *str; const char *fmt; @@ -49,6 +50,7 @@ vsprintf(str, fmt, ap) int ret; FILE f; + f._file = -1; f._flags = __SWR | __SSTR; f._bf._base = f._p = (unsigned char *)str; f._bf._size = f._w = INT_MAX; diff --git a/lib/libc/stdio/vsscanf.c b/lib/libc/stdio/vsscanf.c index e776689..0d4d05a 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 690bdf5..f415007 100644 --- a/lib/libc/stdlib/abort.c +++ b/lib/libc/stdlib/abort.c @@ -39,6 +39,10 @@ static char sccsid[] = "@(#)abort.c 8.1 (Berkeley) 6/4/93"; #include <stdlib.h> #include <stddef.h> #include <unistd.h> +#ifdef _THREAD_SAFE +#include <pthread.h> +#include "pthread_private.h" +#endif void abort() @@ -51,15 +55,24 @@ abort() * any errors -- X311J doesn't allow abort to return anyway. */ sigdelset(&mask, SIGABRT); +#ifdef _THREAD_SAFE + (void) _thread_sys_sigprocmask(SIG_SETMASK, &mask, (sigset_t *)NULL); +#else (void)sigprocmask(SIG_SETMASK, &mask, (sigset_t *)NULL); +#endif (void)kill(getpid(), SIGABRT); /* * if SIGABRT ignored, or caught and the handler returns, do * it again, only harder. */ +#ifdef _THREAD_SAFE + (void) _thread_sys_signal(SIGABRT, SIG_DFL); + (void) _thread_sys_sigprocmask(SIG_SETMASK, &mask, (sigset_t *)NULL); +#else (void)signal(SIGABRT, SIG_DFL); (void)sigprocmask(SIG_SETMASK, &mask, (sigset_t *)NULL); +#endif (void)kill(getpid(), SIGABRT); exit(1); } diff --git a/lib/libc/stdlib/malloc.c b/lib/libc/stdlib/malloc.c index 4299028..caa12d1 100644 --- a/lib/libc/stdlib/malloc.c +++ b/lib/libc/stdlib/malloc.c @@ -6,7 +6,7 @@ * this stuff is worth it, you can buy me a beer in return. Poul-Henning Kamp * ---------------------------------------------------------------------------- * - * $Id: malloc.c,v 1.8 1995/12/18 12:03:54 phk Exp $ + * $Id: malloc.c,v 1.9 1996/01/05 23:30:41 phk Exp $ * */ @@ -51,6 +51,10 @@ #include <err.h> #include <sys/types.h> #include <sys/mman.h> +#ifdef _THREAD_SAFE +#include <pthread.h> +#include "pthread_private.h" +#endif /* * This structure describes a page worth of chunks. @@ -806,6 +810,9 @@ void * malloc(size_t size) { void *result; +#ifdef _THREAD_SAFE + int status; +#endif if (!initialized) malloc_init(); @@ -813,6 +820,9 @@ malloc(size_t size) if (suicide) abort(); +#ifdef _THREAD_SAFE + _thread_kern_sig_block(&status); +#endif if (size <= malloc_maxsize) result = malloc_bytes(size); else @@ -824,6 +834,9 @@ malloc(size_t size) if (malloc_zero) memset(result,0,size); +#ifdef _THREAD_SAFE + _thread_kern_sig_unblock(status); +#endif return result; } @@ -837,6 +850,9 @@ realloc(void *ptr, size_t size) u_long osize,index; struct pginfo **mp; int i; +#ifdef _THREAD_SAFE + int status; +#endif if (suicide) return 0; @@ -854,15 +870,24 @@ realloc(void *ptr, size_t size) return 0; } +#ifdef _THREAD_SAFE + _thread_kern_sig_block(&status); +#endif index = ptr2index(ptr); if (index < malloc_pageshift) { wrtwarning("realloc(): junk pointer (too low)\n"); +#ifdef _THREAD_SAFE + _thread_kern_sig_unblock(status); +#endif return 0; } if (index > last_index) { wrtwarning("realloc(): junk pointer (too high)\n"); +#ifdef _THREAD_SAFE + _thread_kern_sig_unblock(status); +#endif return 0; } @@ -873,6 +898,9 @@ realloc(void *ptr, size_t size) /* Check the pointer */ if ((u_long)ptr & malloc_pagemask) { wrtwarning("realloc(): modified page pointer.\n"); +#ifdef _THREAD_SAFE + _thread_kern_sig_unblock(status); +#endif return 0; } @@ -882,14 +910,21 @@ realloc(void *ptr, size_t size) if (!malloc_realloc && /* unless we have to, */ size <= osize && /* .. or are too small, */ - size > (osize - malloc_pagesize)) /* .. or can free a page, */ + size > (osize - malloc_pagesize)) { /* .. or can free a page, */ +#ifdef _THREAD_SAFE + _thread_kern_sig_unblock(status); +#endif return ptr; /* don't do anything. */ + } } else if (*mp >= MALLOC_MAGIC) { /* Chunk allocation */ /* Check the pointer for sane values */ if (((u_long)ptr & ((*mp)->size-1))) { wrtwarning("realloc(): modified chunk pointer.\n"); +#ifdef _THREAD_SAFE + _thread_kern_sig_unblock(status); +#endif return 0; } @@ -899,6 +934,9 @@ realloc(void *ptr, size_t size) /* Verify that it isn't a free chunk already */ if (tst_bit(*mp,i)) { wrtwarning("realloc(): already free chunk.\n"); +#ifdef _THREAD_SAFE + _thread_kern_sig_unblock(status); +#endif return 0; } @@ -907,11 +945,18 @@ realloc(void *ptr, size_t size) if (!malloc_realloc && /* Unless we have to, */ size < osize && /* ..or are too small, */ (size > osize/2 || /* ..or could use a smaller size, */ - osize == malloc_minsize)) /* ..(if there is one) */ + osize == malloc_minsize)) { /* ..(if there is one) */ +#ifdef _THREAD_SAFE + _thread_kern_sig_unblock(status); +#endif return ptr; /* ..Don't do anything */ + } } else { wrtwarning("realloc(): wrong page pointer.\n"); +#ifdef _THREAD_SAFE + _thread_kern_sig_unblock(status); +#endif return 0; } @@ -925,6 +970,9 @@ realloc(void *ptr, size_t size) memcpy(p,ptr,size); free(ptr); } +#ifdef _THREAD_SAFE + _thread_kern_sig_unblock(status); +#endif return p; } @@ -1119,6 +1167,9 @@ free(void *ptr) { struct pginfo *info; int index; +#ifdef _THREAD_SAFE + int status; +#endif /* This is legal */ if (!ptr) @@ -1133,15 +1184,24 @@ free(void *ptr) if (suicide) return; +#ifdef _THREAD_SAFE + _thread_kern_sig_block(&status); +#endif index = ptr2index(ptr); if (index < malloc_pageshift) { wrtwarning("free(): junk pointer (too low)\n"); +#ifdef _THREAD_SAFE + _thread_kern_sig_unblock(status); +#endif return; } if (index > last_index) { wrtwarning("free(): junk pointer (too high)\n"); +#ifdef _THREAD_SAFE + _thread_kern_sig_unblock(status); +#endif return; } @@ -1151,5 +1211,8 @@ free(void *ptr) free_pages(ptr,index,info); else free_bytes(ptr,index,info); +#ifdef _THREAD_SAFE + _thread_kern_sig_unblock(status); +#endif return; } diff --git a/lib/libc/stdtime/localtime.c b/lib/libc/stdtime/localtime.c index d6337ff..3507641 100644 --- a/lib/libc/stdtime/localtime.c +++ b/lib/libc/stdtime/localtime.c @@ -15,6 +15,10 @@ static char elsieid[] = "@(#)localtime.c 7.44"; #include "private.h" #include "tzfile.h" #include "fcntl.h" +#ifdef _THREAD_SAFE +#include <pthread.h> +#include "pthread_private.h" +#endif /* ** SunOS 4.1.1 headers lack O_BINARY. @@ -158,6 +162,10 @@ static struct state gmtmem; static char lcl_TZname[TZ_STRLEN_MAX + 1]; static int lcl_is_set; static int gmt_is_set; +#ifdef _THREAD_SAFE +static pthread_mutex_t lcl_mutex = PTHREAD_MUTEX_INITIALIZER; +static pthread_mutex_t gmt_mutex = PTHREAD_MUTEX_INITIALIZER; +#endif char * tzname[2] = { wildabbr, @@ -906,8 +914,13 @@ struct state * const sp; */ static #endif /* !defined STD_INSPIRED */ +#ifdef _THREAD_SAFE +void +tzsetwall_basic P((void)) +#else void tzsetwall P((void)) +#endif { if (lcl_is_set < 0) return; @@ -927,8 +940,23 @@ tzsetwall P((void)) settzname(); } +#ifdef _THREAD_SAFE +void +tzsetwall P((void)) +{ + pthread_mutex_lock(&lcl_mutex); + tzsetwall_basic(); + pthread_mutex_unlock(&lcl_mutex); +} +#endif + +#ifdef _THREAD_SAFE +static void +tzset_basic P((void)) +#else void tzset P((void)) +#endif { register const char * name; @@ -968,6 +996,16 @@ tzset P((void)) settzname(); } +#ifdef _THREAD_SAFE +void +tzset P((void)) +{ + pthread_mutex_lock(&lcl_mutex); + tzset_basic(); + pthread_mutex_unlock(&lcl_mutex); +} +#endif + /* ** The easy way to behave "as if no library function calls" localtime ** is to not call it--so we drop its guts into "localsub", which can be @@ -1024,13 +1062,55 @@ struct tm * const tmp; #endif /* defined TM_ZONE */ } +#ifdef _THREAD_SAFE +int +localtime_r(timep, p_tm) +const time_t * const timep; +struct tm *p_tm; +{ + pthread_mutex_lock(&lcl_mutex); + tzset(); + localsub(timep, 0L, p_tm); + pthread_mutex_unlock(&lcl_mutex); + return(0); +} +#endif + struct tm * localtime(timep) const time_t * const timep; { +#ifdef _THREAD_SAFE + static pthread_mutex_t localtime_mutex = PTHREAD_MUTEX_INITIALIZER; + static pthread_key_t localtime_key = -1; + struct tm *p_tm; + + pthread_mutex_lock(&localtime_mutex); + if (localtime_key < 0) { + if (pthread_keycreate(&localtime_key, free) < 0) { + pthread_mutex_unlock(&localtime_mutex); + return(NULL); + } + } + pthread_mutex_unlock(&localtime_mutex); + if (pthread_getspecific(localtime_key,(void **) &p_tm) != 0) { + return(NULL); + } else if (p_tm == NULL) { + if ((p_tm = (struct tm *)malloc(sizeof(struct tm))) == NULL) { + return(NULL); + } + pthread_setspecific(localtime_key, p_tm); + } + pthread_mutex_lock(&lcl_mutex); + tzset(); + localsub(timep, 0L, p_tm); + pthread_mutex_unlock(&lcl_mutex); + return p_tm; +#else tzset(); localsub(timep, 0L, &tm); return &tm; +#endif } /* @@ -1043,6 +1123,9 @@ const time_t * const timep; const long offset; struct tm * const tmp; { +#ifdef _THREAD_SAFE + pthread_mutex_lock(&gmt_mutex); +#endif if (!gmt_is_set) { gmt_is_set = TRUE; #ifdef ALL_STATE @@ -1051,6 +1134,9 @@ struct tm * const tmp; #endif /* defined ALL_STATE */ gmtload(gmtptr); } +#ifdef _THREAD_SAFE + pthread_mutex_unlock(&gmt_mutex); +#endif timesub(timep, offset, gmtptr, tmp); #ifdef TM_ZONE /* @@ -1077,9 +1163,43 @@ struct tm * gmtime(timep) const time_t * const timep; { +#ifdef _THREAD_SAFE + static pthread_mutex_t gmtime_mutex = PTHREAD_MUTEX_INITIALIZER; + static pthread_key_t gmtime_key = -1; + struct tm *p_tm; + + pthread_mutex_lock(&gmtime_mutex); + if (gmtime_key < 0) { + if (pthread_keycreate(&gmtime_key, free) < 0) { + pthread_mutex_unlock(&gmtime_mutex); + return(NULL); + } + } + pthread_mutex_unlock(&gmtime_mutex); + if (pthread_getspecific(gmtime_key,(void **) &p_tm) != 0) { + return(NULL); + } else if (p_tm == NULL) { + if ((p_tm = (struct tm *)malloc(sizeof(struct tm))) == NULL) { + return(NULL); + } + pthread_setspecific(gmtime_key, p_tm); + } + gmtsub(timep, 0L, p_tm); + return(p_tm); +#else gmtsub(timep, 0L, &tm); return &tm; +#endif +} + +#ifdef _THREAD_SAFE +int +gmtime_r(const time_t * timep, struct tm * tm) +{ + gmtsub(timep, 0L, tm); + return(0); } +#endif #ifdef STD_INSPIRED @@ -1482,8 +1602,16 @@ time_t mktime(tmp) struct tm * const tmp; { + time_t mktime_return_value; +#ifdef _THREAD_SAFE + pthread_mutex_lock(&lcl_mutex); +#endif tzset(); - return time1(tmp, localsub, 0L); + mktime_return_value = time1(tmp, localsub, 0L); +#ifdef _THREAD_SAFE + pthread_mutex_unlock(&lcl_mutex); +#endif + return(mktime_return_value); } #ifdef STD_INSPIRED diff --git a/lib/libc/sys/accept.2 b/lib/libc/sys/accept.2 index d475e36..126000a 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 18512e2..f98631d 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 885ac80..3cb3d51 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 eb38ab3..a6d7c71 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 8989639..29d1ada 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 ba47e6d..2bfb0a2 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 f53c02f..eb752fe 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 bb6abb7..5ec080c 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 234ea6e..1116cf9 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 2f3ae6d..72a6a91 100644 --- a/lib/libc/sys/ftruncate.c +++ b/lib/libc/sys/ftruncate.c @@ -37,6 +37,11 @@ static char sccsid[] = "@(#)ftruncate.c 8.1 (Berkeley) 6/17/93"; #include <sys/types.h> #include <sys/syscall.h> +#include <unistd.h> +#ifdef _THREAD_SAFE +#include <pthread.h> +#include "pthread_private.h" +#endif /* * This function provides 64-bit offset padding that @@ -48,5 +53,16 @@ ftruncate(fd, length) off_t length; { +#ifdef _THREAD_SAFE + int retval; + if (_thread_fd_lock(fd, FD_RDWR, NULL,__FILE__,__LINE__) != 0) { + retval = -1; + } else { + retval = __syscall((quad_t)SYS_ftruncate, fd, 0, length); + _thread_fd_unlock(fd, FD_RDWR); + } + return(retval); +#else return(__syscall((quad_t)SYS_ftruncate, fd, 0, length)); +#endif } diff --git a/lib/libc/sys/getdirentries.2 b/lib/libc/sys/getdirentries.2 index 6df9444..9e6dc50 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 d89488c..5ca0a44 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 d56e404..e053b47 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 24ae2b8b..e2ec257 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 bf43809..a6e7351 100644 --- a/lib/libc/sys/intro.2 +++ b/lib/libc/sys/intro.2 @@ -47,13 +47,49 @@ their error returns, and other common definitions and concepts. .\".Pp .\"<more later...> .Sh DIAGNOSTICS -Nearly all of the system calls provide an error number in the external -variable -.Va errno , -which is defined as: +Nearly all of the system calls provide an error number referenced via +the external identifier errno. This identifier is defined in +.Aq Pa sys/errno.h +for non-threaded programs as: .Pp .Dl extern int errno .Pp +and for threaded programs as: +.Pp +.Dl extern int * __error(); +.Dl #define errno (* __error()) +.Pp +A threaded program must be compiled with +.Va _THREAD_SAFE +defined so that the preprocessor will output the appropriate errno +definition to the compiler. Failure to do so will mean that error +variables will not be thread specific. +.Pp +The threaded library implementation of +.Va __error() +returns a pointer to a field in the thread specific structure for +threads other than the initial thread. For the initial thread, +.Va __error() +returns a pointer to a global +.Va errno +variable that is compatible with that used by non-threaded programs. +This allows the initial thread to call functions in libraries which have +not been compiled with +.Va _THREAD_SAFE . +Programmers should ensure that threads other than the initial thread only +call functions in libraries that have been compiled with +.Va _THREAD_SAFE . +.Pp +Programmers should include +.Aq Pa sys/errno.h to obtain the definition of +.Va errno +rather than coding the definition as an external reference directly. It is +planned that the +.Va extern int errno +definition will eventually be replaced by the threaded definition so that +all libraries will have a thread-aware treatment of +.Va errno . +.Pp When a system call detects an error, it returns an integer value indicating failure (usually -1) diff --git a/lib/libc/sys/ioctl.2 b/lib/libc/sys/ioctl.2 index 36ce6ff..38c58b9 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 eaa9522..6d2a64f 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 52208d1..8896ad8 100644 --- a/lib/libc/sys/lseek.c +++ b/lib/libc/sys/lseek.c @@ -37,6 +37,11 @@ static char sccsid[] = "@(#)lseek.c 8.1 (Berkeley) 6/17/93"; #include <sys/types.h> #include <sys/syscall.h> +#include <unistd.h> +#ifdef _THREAD_SAFE +#include <pthread.h> +#include "pthread_private.h" +#endif /* * This function provides 64-bit offset padding that @@ -48,7 +53,17 @@ lseek(fd, offset, whence) off_t offset; int whence; { - extern off_t __syscall(); +#ifdef _THREAD_SAFE + off_t offs; + if (_thread_fd_lock(fd, FD_RDWR, NULL,__FILE__,__LINE__) != 0) { + offs = -1; + } else { + offs = __syscall((quad_t) SYS_lseek,fd, 0, offset, whence); + _thread_fd_unlock(fd, FD_RDWR); + } + return(offs); +#else return(__syscall((quad_t)SYS_lseek, fd, 0, offset, whence)); +#endif } diff --git a/lib/libc/sys/open.2 b/lib/libc/sys/open.2 index dea59fc..479a209 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 b94341a..ea428fd 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 de2d3ae..a1e4a51 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 |