Index: head/lib/libc/gen/_pthread_stubs.c =================================================================== --- head/lib/libc/gen/_pthread_stubs.c (revision 72372) +++ head/lib/libc/gen/_pthread_stubs.c (revision 72373) @@ -1,131 +1,143 @@ /* * Copyright (c) 2001 Daniel Eischen . * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * * THIS SOFTWARE IS PROVIDED BY DANIEL EISCHEN AND CONTRIBUTORS ``AS IS'' * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. * * $FreeBSD$ */ #include /* * Weak symbols: All libc internal usage of these functions should * use the weak symbol versions (_pthread_XXX). If libpthread is * linked, it will override these functions with (non-weak) routines. * The _pthread_XXX functions are provided solely for internal libc * usage to avoid unwanted cancellation points and to differentiate * between application locks and libc locks (threads holding the * latter can't be allowed to exit/terminate). */ #pragma weak _pthread_getspecific=_pthread_getspecific_stub #pragma weak _pthread_key_create=_pthread_key_create_stub #pragma weak _pthread_key_delete=_pthread_key_delete_stub #pragma weak _pthread_mutex_destroy=_pthread_mutex_destroy_stub #pragma weak _pthread_mutex_init=_pthread_mutex_init_stub #pragma weak _pthread_mutex_lock=_pthread_mutex_lock_stub #pragma weak _pthread_mutex_trylock=_pthread_mutex_trylock_stub #pragma weak _pthread_mutex_unlock=_pthread_mutex_unlock_stub #pragma weak _pthread_mutexattr_init=_pthread_mutexattr_init_stub #pragma weak _pthread_mutexattr_destroy=_pthread_mutexattr_destroy_stub #pragma weak _pthread_mutexattr_settype=_pthread_mutexattr_settype_stub #pragma weak _pthread_once=_pthread_once_stub +#pragma weak _pthread_self=_pthread_self_stub #pragma weak _pthread_setspecific=_pthread_setspecific_stub +struct pthread { +}; +static struct pthread main_thread; + + void * _pthread_getspecific_stub(pthread_key_t key) { return (NULL); } int _pthread_key_create_stub(pthread_key_t *key, void (*destructor) (void *)) { return (0); } int _pthread_key_delete_stub(pthread_key_t key) { return (0); } int _pthread_mutex_destroy_stub(pthread_mutex_t *mattr) { return (0); } int _pthread_mutex_init_stub(pthread_mutex_t *mutex, const pthread_mutexattr_t *mattr) { return (0); } int _pthread_mutex_lock_stub(pthread_mutex_t *mutex) { return (0); } int _pthread_mutex_trylock_stub(pthread_mutex_t *mutex) { return (0); } int _pthread_mutex_unlock_stub(pthread_mutex_t *mutex) { return (0); } int _pthread_mutexattr_init_stub(pthread_mutexattr_t *mattr) { return (0); } int _pthread_mutexattr_destroy_stub(pthread_mutexattr_t *mattr) { return (0); } int _pthread_mutexattr_settype_stub(pthread_mutexattr_t *mattr, int type) { return (0); } int _pthread_once_stub(pthread_once_t *once_control, void (*init_routine) (void)) { return (0); +} + +pthread_t +_pthread_self_stub(void) +{ + return (&main_thread); } int _pthread_setspecific_stub(pthread_key_t key, const void *value) { return (0); } Index: head/lib/libc/include/namespace.h =================================================================== --- head/lib/libc/include/namespace.h (revision 72372) +++ head/lib/libc/include/namespace.h (revision 72373) @@ -1,134 +1,134 @@ /* * Copyright (c) 2001 Daniel Eischen . * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. * * $FreeBSD$ * */ #ifndef _NAMESPACE_H_ #define _NAMESPACE_H_ /* * Prototypes for syscalls/functions that need to be overridden * in libc_r/libpthread. */ #define accept _accept #define bind _bind #define close _close #define connect _connect #define dup _dup #define dup2 _dup2 #define execve _execve #define fcntl _fcntl /*#define flock _flock */ #define flockfile _flockfile #define fstat _fstat #define fstatfs _fstatfs #define fsync _fsync #define funlockfile _funlockfile #define getdirentries _getdirentries #define getlogin _getlogin #define getpeername _getpeername #define getsockname _getsockname #define getsockopt _getsockopt #define ioctl _ioctl /* #define kevent _kevent */ #define listen _listen #define nanosleep _nanosleep #define open _open #define pthread_getspecific _pthread_getspecific #define pthread_key_create _pthread_key_create #define pthread_key_delete _pthread_key_delete #define pthread_mutex_destroy _pthread_mutex_destroy #define pthread_mutex_init _pthread_mutex_init #define pthread_mutex_lock _pthread_mutex_lock #define pthread_mutex_trylock _pthread_mutex_trylock #define pthread_mutex_unlock _pthread_mutex_unlock #define pthread_mutexattr_init _pthread_mutexattr_init #define pthread_mutexattr_destroy _pthread_mutexattr_destroy #define pthread_mutexattr_settype _pthread_mutexattr_settype #define pthread_once _pthread_once +#define pthread_self _pthread_self #define pthread_setspecific _pthread_setspecific #define read _read #define readv _readv #define recvfrom _recvfrom #define recvmsg _recvmsg #define select _select #define sendmsg _sendmsg #define sendto _sendto #define setsockopt _setsockopt /*#define sigaction _sigaction*/ #define sigprocmask _sigprocmask #define sigsuspend _sigsuspend #define socket _socket #define socketpair _socketpair #define wait4 _wait4 #define write _write #define writev _writev /* * Other hidden syscalls/functions that libc_r needs to override * but are not used internally by libc. * * XXX - When modifying libc to use one of the following, remove * the prototype from below and place it in the list above. */ #if 0 #define creat _creat #define fchflags _fchflags #define fchmod _fchmod #define fpathconf _fpathconf #define ftrylockfile _ftrylockfile #define msync _msync #define nfssvc _nfssvc #define pause _pause #define poll _poll #define pthread_rwlock_destroy _pthread_rwlock_destroy #define pthread_rwlock_init _pthread_rwlock_init #define pthread_rwlock_rdlock _pthread_rwlock_rdlock #define pthread_rwlock_tryrdlock _pthread_rwlock_tryrdlock #define pthread_rwlock_trywrlock _pthread_rwlock_trywrlock #define pthread_rwlock_unlock _pthread_rwlock_unlock #define pthread_rwlock_wrlock _pthread_rwlock_wrlock #define pthread_rwlockattr_init _pthread_rwlockattr_init #define pthread_rwlockattr_destroy _pthread_rwlockattr_destroy -#define pthread_self _pthread_self #define sched_yield _sched_yield #define sendfile _sendfile #define shutdown _shutdown #define sigaltstack _sigaltstack #define signanosleep _signanosleep #define sigpending _sigpending #define sigreturn _sigreturn #define sigsetmask _sigsetmask #define sleep _sleep #define system _system #define tcdrain _tcdrain #define wait _wait #define waitpid _waitpid #endif #endif /* _NAMESPACE_H_ */ Index: head/lib/libc/include/un-namespace.h =================================================================== --- head/lib/libc/include/un-namespace.h (revision 72372) +++ head/lib/libc/include/un-namespace.h (revision 72373) @@ -1,134 +1,134 @@ /* * Copyright (c) 2001 Daniel Eischen . * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. * * $FreeBSD$ */ #ifndef _UN_NAMESPACE_H_ #define _UN_NAMESPACE_H_ #undef accept #undef bind #undef close #undef connect #undef dup #undef dup2 #undef execve #undef fcntl #undef flock #undef flockfile #undef fstat #undef fstatfs #undef fsync #undef funlockfile #undef getdirentries #undef getlogin #undef getpeername #undef getsockname #undef getsockopt #undef ioctl #undef kevent #undef listen #undef nanosleep #undef open #undef pthread_getspecific #undef pthread_key_create #undef pthread_key_delete #undef pthread_mutex_destroy #undef pthread_mutex_init #undef pthread_mutex_lock #undef pthread_mutex_trylock #undef pthread_mutex_unlock #undef pthread_mutexattr_init #undef pthread_mutexattr_destroy #undef pthread_mutexattr_settype #undef pthread_once +#undef pthread_self #undef pthread_setspecific #undef read #undef readv #undef recvfrom #undef recvmsg #undef select #undef sendmsg #undef sendto #undef setsockopt #undef sigaction #undef sigprocmask #undef sigsuspend #undef socket #undef socketpair #undef wait4 #undef write #undef writev #if 0 #undef creat #undef fchflags #undef fchmod #undef fpathconf #undef ftrylockfile #undef msync #undef nfssvc #undef pause #undef poll #undef pthread_rwlock_destroy #undef pthread_rwlock_init #undef pthread_rwlock_rdlock #undef pthread_rwlock_tryrdlock #undef pthread_rwlock_trywrlock #undef pthread_rwlock_unlock #undef pthread_rwlock_wrlock #undef pthread_rwlockattr_init #undef pthread_rwlockattr_destroy -#undef pthread_self #undef sched_yield #undef sendfile #undef shutdown #undef sigaltstack #undef signanosleep #undef sigpending #undef sigreturn #undef sigsetmask #undef sleep #undef system #undef tcdrain #undef wait #undef waitpid #endif /* 0 */ #ifdef _SIGNAL_H_ int _sigaction(int, const struct sigaction *, struct sigaction *); #endif #ifdef _SYS_EVENT_H_ int _kevent(int, const struct kevent *, int, struct kevent *, int, const struct timespec *); #endif #ifdef _SYS_FCNTL_H_ int _flock(int, int); #endif #endif /* _UN_NAMESPACE_H_ */ Index: head/lib/libc/stdio/_flock_stub.c =================================================================== --- head/lib/libc/stdio/_flock_stub.c (revision 72372) +++ head/lib/libc/stdio/_flock_stub.c (revision 72373) @@ -1,81 +1,187 @@ /* * Copyright (c) 1998 John Birrell . * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * 3. All advertising materials mentioning features or use of this software * must display the following acknowledgement: * This product includes software developed by John Birrell. * 4. Neither the name of the author nor the names of any co-contributors * may be used to endorse or promote products derived from this software * without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY JOHN BIRRELL AND CONTRIBUTORS ``AS IS'' AND * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. * * $FreeBSD$ * */ +/* + * POSIX stdio FILE locking functions. These assume that the locking + * is only required at FILE structure level, not at file descriptor + * level too. + * + */ + +#include "namespace.h" #include +#include +#include +#include +#include "un-namespace.h" /* - * Declare weak references in case the application is not linked - * with libpthread. + * Weak symbols for externally visible functions in this file: */ -#pragma weak flockfile=_flockfile_stub -#pragma weak _flockfile=_flockfile_stub -#pragma weak _flockfile_debug=_flockfile_debug_stub -#pragma weak ftrylockfile=_ftrylockfile_stub -#pragma weak _ftrylockfile=_ftrylockfile_stub -#pragma weak funlockfile=_funlockfile_stub -#pragma weak _funlockfile=_funlockfile_stub +#pragma weak flockfile=_flockfile +#pragma weak _flockfile_debug=_flockfile_debug_stub +#pragma weak ftrylockfile=_ftrylockfile +#pragma weak funlockfile=_funlockfile +static int init_lock(FILE *); + /* - * This function is a stub for the _flockfile function in libpthread. + * The FILE lock structure. The FILE *fp is locked when the mutex + * is locked. */ +struct __file_lock { + pthread_mutex_t fl_mutex; + pthread_t fl_owner; /* current owner */ + int fl_count; /* recursive lock count */ +}; + +/* + * Allocate and initialize a file lock. + */ +static int +init_lock(FILE *fp) +{ + struct __file_lock *p; + int ret; + + if ((p = malloc(sizeof(struct __file_lock))) == NULL) + ret = -1; + else { + p->fl_mutex = PTHREAD_MUTEX_INITIALIZER; + p->fl_owner = NULL; + p->fl_count = 0; + fp->_lock = p; + ret = 0; + } + return (ret); +} + void -_flockfile_stub(FILE *fp) +_flockfile(FILE *fp) { + pthread_t curthread = _pthread_self(); + + /* + * Check if this is a real file with a valid lock, creating + * the lock if needed: + */ + if ((fp->_file >= 0) && + ((fp->_lock != NULL) || (init_lock(fp) == 0))) { + if (fp->_lock->fl_owner == curthread) + fp->_lock->fl_count++; + else { + /* + * Make sure this mutex is treated as a private + * internal mutex: + */ + _pthread_mutex_lock(&fp->_lock->fl_mutex); + fp->_lock->fl_owner = curthread; + fp->_lock->fl_count = 1; + } + } } /* - * This function is a stub for the _flockfile_debug function in libpthread. + * This can be overriden by the threads library if it is linked in. */ void _flockfile_debug_stub(FILE *fp, char *fname, int lineno) { + _flockfile(fp); } -/* - * This function is a stub for the _ftrylockfile function in libpthread. - */ int -_ftrylockfile_stub(FILE *fp) +_ftrylockfile(FILE *fp) { - return(0); + pthread_t curthread = _pthread_self(); + int ret = 0; + + /* + * Check if this is a real file with a valid lock, creating + * the lock if needed: + */ + if ((fp->_file >= 0) && + ((fp->_lock != NULL) || (init_lock(fp) == 0))) { + if (fp->_lock->fl_owner == curthread) + fp->_lock->fl_count++; + /* + * Make sure this mutex is treated as a private + * internal mutex: + */ + else if (_pthread_mutex_trylock(&fp->_lock->fl_mutex) == 0) { + fp->_lock->fl_owner = curthread; + fp->_lock->fl_count = 1; + } + else + ret = -1; + } + else + ret = -1; + return (ret); } -/* - * This function is a stub for the _funlockfile function in libpthread. - */ -void -_funlockfile_stub(FILE *fp) +void +_funlockfile(FILE *fp) { + pthread_t curthread = _pthread_self(); + + /* + * Check if this is a real file with a valid lock owned + * by the current thread: + */ + if ((fp->_file >= 0) && (fp->_lock != NULL) && + (fp->_lock->fl_owner == curthread)) { + /* + * Check if this thread has locked the FILE + * more than once: + */ + if (fp->_lock->fl_count > 1) + /* + * Decrement the count of the number of + * times the running thread has locked this + * file: + */ + fp->_lock->fl_count--; + else { + /* + * The running thread will release the + * lock now: + */ + fp->_lock->fl_count = 0; + fp->_lock->fl_owner = NULL; + _pthread_mutex_unlock(&fp->_lock->fl_mutex); + } + } } Index: head/lib/libc/stdio/asprintf.c =================================================================== --- head/lib/libc/stdio/asprintf.c (revision 72372) +++ head/lib/libc/stdio/asprintf.c (revision 72373) @@ -1,81 +1,83 @@ /* $OpenBSD: asprintf.c,v 1.4 1998/06/21 22:13:46 millert Exp $ */ /* * Copyright (c) 1997 Todd C. Miller * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * 3. The name of the author may not be used to endorse or promote products * derived from this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY * AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL * THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ #if defined(LIBC_RCS) && !defined(lint) static char rcsid[] = "$FreeBSD$"; #endif /* LIBC_RCS and not lint */ #include #include #include #if __STDC__ #include #else #include #endif +#include "local.h" + int #if __STDC__ asprintf(char **str, char const *fmt, ...) #else asprintf(str, fmt, va_alist) char **str; const char *fmt; va_dcl #endif { int ret; va_list ap; FILE f; #if __STDC__ va_start(ap, fmt); #else va_start(ap); #endif f._file = -1; f._flags = __SWR | __SSTR | __SALC; f._bf._base = f._p = (unsigned char *)malloc(128); if (f._bf._base == NULL) { *str = NULL; errno = ENOMEM; return (-1); } f._bf._size = f._w = 127; /* Leave room for the NULL */ - ret = vfprintf(&f, fmt, ap); + ret = __vfprintf(&f, fmt, ap); /* Use unlocked __vfprintf */ *f._p = '\0'; va_end(ap); f._bf._base = reallocf(f._bf._base, f._bf._size + 1); if (f._bf._base == NULL) { errno = ENOMEM; ret = -1; } *str = (char *)f._bf._base; return (ret); } Index: head/lib/libc/stdio/fclose.c =================================================================== --- head/lib/libc/stdio/fclose.c (revision 72372) +++ head/lib/libc/stdio/fclose.c (revision 72373) @@ -1,84 +1,77 @@ /*- * Copyright (c) 1990, 1993 * The Regents of the University of California. All rights reserved. * * This code is derived from software contributed to Berkeley by * Chris Torek. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * 3. All advertising materials mentioning features or use of this software * must display the following acknowledgement: * This product includes software developed by the University of * California, Berkeley and its contributors. * 4. Neither the name of the University nor the names of its contributors * may be used to endorse or promote products derived from this software * without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. */ #if defined(LIBC_SCCS) && !defined(lint) #if 0 static char sccsid[] = "@(#)fclose.c 8.1 (Berkeley) 6/4/93"; #endif static const char rcsid[] = "$FreeBSD$"; #endif /* LIBC_SCCS and not lint */ #include "namespace.h" #include #include #include #include "un-namespace.h" #include "libc_private.h" #include "local.h" int -fclose(fp) - FILE *fp; +fclose(FILE *fp) { int r; if (fp->_flags == 0) { /* not open! */ errno = EBADF; return (EOF); } FLOCKFILE(fp); r = fp->_flags & __SWR ? __sflush(fp) : 0; if (fp->_close != NULL && (*fp->_close)(fp->_cookie) < 0) r = EOF; if (fp->_flags & __SMBF) free((char *)fp->_bf._base); if (HASUB(fp)) FREEUB(fp); if (HASLB(fp)) FREELB(fp); - FUNLOCKFILE(fp); fp->_file = -1; fp->_r = fp->_w = 0; /* Mess up if reaccessed. */ -#if 0 - if (fp->_lock != NULL) { - _pthread_mutex_destroy((pthread_mutex_t *)&fp->_lock); - fp->_lock = NULL; - } -#endif fp->_flags = 0; /* Release this FILE for reuse. */ + FUNLOCKFILE(fp); return (r); } Index: head/lib/libc/stdio/feof.c =================================================================== --- head/lib/libc/stdio/feof.c (revision 72372) +++ head/lib/libc/stdio/feof.c (revision 72373) @@ -1,57 +1,65 @@ /*- * Copyright (c) 1990, 1993 * The Regents of the University of California. All rights reserved. * * This code is derived from software contributed to Berkeley by * Chris Torek. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * 3. All advertising materials mentioning features or use of this software * must display the following acknowledgement: * This product includes software developed by the University of * California, Berkeley and its contributors. * 4. Neither the name of the University nor the names of its contributors * may be used to endorse or promote products derived from this software * without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. */ #if defined(LIBC_SCCS) && !defined(lint) #if 0 static char sccsid[] = "@(#)feof.c 8.1 (Berkeley) 6/4/93"; #endif static const char rcsid[] = "$FreeBSD$"; #endif /* LIBC_SCCS and not lint */ +#include "namespace.h" #include +#include "un-namespace.h" +#include "libc_private.h" /* - * A subroutine version of the macro feof. + * feof has traditionally been a macro in . That is no + * longer true because it needs to be thread-safe. + * + * #undef feof */ -#undef feof - int -feof(fp) - FILE *fp; +feof(FILE *fp) { - return (__sfeof(fp)); + int ret; + + FLOCKFILE(fp); + ret= __sfeof(fp); + FUNLOCKFILE(fp); + return (ret); } Index: head/lib/libc/stdio/ferror.c =================================================================== --- head/lib/libc/stdio/ferror.c (revision 72372) +++ head/lib/libc/stdio/ferror.c (revision 72373) @@ -1,57 +1,65 @@ /*- * Copyright (c) 1990, 1993 * The Regents of the University of California. All rights reserved. * * This code is derived from software contributed to Berkeley by * Chris Torek. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * 3. All advertising materials mentioning features or use of this software * must display the following acknowledgement: * This product includes software developed by the University of * California, Berkeley and its contributors. * 4. Neither the name of the University nor the names of its contributors * may be used to endorse or promote products derived from this software * without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. */ #if defined(LIBC_SCCS) && !defined(lint) #if 0 static char sccsid[] = "@(#)ferror.c 8.1 (Berkeley) 6/4/93"; #endif static const char rcsid[] = "$FreeBSD$"; #endif /* LIBC_SCCS and not lint */ +#include "namespace.h" #include +#include "un-namespace.h" +#include "libc_private.h" /* - * A subroutine version of the macro ferror. + * ferror has traditionally been a macro in . That is no + * longer true because it needs to be thread-safe. + * + * #undef ferror */ -#undef ferror - int -ferror(fp) - FILE *fp; +ferror(FILE *fp) { - return (__sferror(fp)); + int ret; + + FLOCKFILE(fp); + ret = __sferror(fp); + FUNLOCKFILE(fp); + return (ret); } Index: head/lib/libc/stdio/fflush.c =================================================================== --- head/lib/libc/stdio/fflush.c (revision 72372) +++ head/lib/libc/stdio/fflush.c (revision 72373) @@ -1,122 +1,135 @@ /*- * Copyright (c) 1990, 1993 * The Regents of the University of California. All rights reserved. * * This code is derived from software contributed to Berkeley by * Chris Torek. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * 3. All advertising materials mentioning features or use of this software * must display the following acknowledgement: * This product includes software developed by the University of * California, Berkeley and its contributors. * 4. Neither the name of the University nor the names of its contributors * may be used to endorse or promote products derived from this software * without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. */ #if defined(LIBC_SCCS) && !defined(lint) #if 0 static char sccsid[] = "@(#)fflush.c 8.1 (Berkeley) 6/4/93"; #endif static const char rcsid[] = "$FreeBSD$"; #endif /* LIBC_SCCS and not lint */ #include "namespace.h" #include #include #include "un-namespace.h" #include "libc_private.h" #include "local.h" +static int sflush_locked(FILE *); + /* * Flush a single file, or (if fp is NULL) all files. * MT-safe version */ int fflush(FILE *fp) { int retval; if (fp == NULL) - return (_fwalk(__sflush)); + return (_fwalk(sflush_locked)); FLOCKFILE(fp); if ((fp->_flags & (__SWR | __SRW)) == 0) { errno = EBADF; retval = EOF; } else retval = __sflush(fp); FUNLOCKFILE(fp); return (retval); } /* * Flush a single file, or (if fp is NULL) all files. * Non-MT-safe version */ int __fflush(FILE *fp) { int retval; if (fp == NULL) - return (_fwalk(__sflush)); + return (_fwalk(sflush_locked)); if ((fp->_flags & (__SWR | __SRW)) == 0) { errno = EBADF; retval = EOF; } else retval = __sflush(fp); return (retval); } int __sflush(FILE *fp) { unsigned char *p; int n, t; t = fp->_flags; if ((t & __SWR) == 0) return (0); if ((p = fp->_bf._base) == NULL) return (0); n = fp->_p - p; /* write this much */ /* * Set these immediately to avoid problems with longjmp and to allow * exchange buffering (via setvbuf) in user write function. */ fp->_p = p; fp->_w = t & (__SLBF|__SNBF) ? 0 : fp->_bf._size; for (; n > 0; n -= t, p += t) { t = (*fp->_write)(fp->_cookie, (char *)p, n); if (t <= 0) { fp->_flags |= __SERR; return (EOF); } } return (0); +} + +static int +sflush_locked(FILE *fp) +{ + int ret; + + FLOCKFILE(fp); + ret = __sflush(fp); + FUNLOCKFILE(fp); + return (ret); } Index: head/lib/libc/stdio/fgetc.c =================================================================== --- head/lib/libc/stdio/fgetc.c (revision 72372) +++ head/lib/libc/stdio/fgetc.c (revision 72373) @@ -1,59 +1,60 @@ /*- * Copyright (c) 1990, 1993 * The Regents of the University of California. All rights reserved. * * This code is derived from software contributed to Berkeley by * Chris Torek. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * 3. All advertising materials mentioning features or use of this software * must display the following acknowledgement: * This product includes software developed by the University of * California, Berkeley and its contributors. * 4. Neither the name of the University nor the names of its contributors * may be used to endorse or promote products derived from this software * without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. */ #if defined(LIBC_SCCS) && !defined(lint) #if 0 static char sccsid[] = "@(#)fgetc.c 8.1 (Berkeley) 6/4/93"; #endif static const char rcsid[] = "$FreeBSD$"; #endif /* LIBC_SCCS and not lint */ #include "namespace.h" #include #include "un-namespace.h" #include "libc_private.h" +#include "local.h" int fgetc(fp) FILE *fp; { int retval; FLOCKFILE(fp); retval = __sgetc(fp); FUNLOCKFILE(fp); return (retval); } Index: head/lib/libc/stdio/fgetln.c =================================================================== --- head/lib/libc/stdio/fgetln.c (revision 72372) +++ head/lib/libc/stdio/fgetln.c (revision 72373) @@ -1,165 +1,169 @@ /*- * Copyright (c) 1990, 1993 * The Regents of the University of California. All rights reserved. * * This code is derived from software contributed to Berkeley by * Chris Torek. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * 3. All advertising materials mentioning features or use of this software * must display the following acknowledgement: * This product includes software developed by the University of * California, Berkeley and its contributors. * 4. Neither the name of the University nor the names of its contributors * may be used to endorse or promote products derived from this software * without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. */ #if defined(LIBC_SCCS) && !defined(lint) #if 0 static char sccsid[] = "@(#)fgetln.c 8.2 (Berkeley) 1/2/94"; #endif static const char rcsid[] = "$FreeBSD$"; #endif /* LIBC_SCCS and not lint */ +#include "namespace.h" #include #include #include +#include "un-namespace.h" +#include "libc_private.h" #include "local.h" /* * Expand the line buffer. Return -1 on error. #ifdef notdef * The `new size' does not account for a terminating '\0', * so we add 1 here. #endif */ -int -__slbexpand(fp, newsize) - FILE *fp; - size_t newsize; +static int +slbexpand(FILE *fp, size_t newsize) { void *p; #ifdef notdef ++newsize; #endif if (fp->_lb._size >= newsize) return (0); if ((p = realloc(fp->_lb._base, newsize)) == NULL) return (-1); fp->_lb._base = p; fp->_lb._size = newsize; return (0); } /* * Get an input line. The returned pointer often (but not always) * points into a stdio buffer. Fgetln does not alter the text of * the returned line (which is thus not a C string because it will * not necessarily end with '\0'), but does allow callers to modify * it if they wish. Thus, we set __SMOD in case the caller does. */ char * -fgetln(fp, lenp) - register FILE *fp; - size_t *lenp; +fgetln(FILE *fp, size_t *lenp) { - register unsigned char *p; - register size_t len; + unsigned char *p; + size_t len; size_t off; + FLOCKFILE(fp); /* make sure there is input */ if (fp->_r <= 0 && __srefill(fp)) { *lenp = 0; + FUNLOCKFILE(fp); return (NULL); } /* look for a newline in the input */ if ((p = memchr((void *)fp->_p, '\n', (size_t)fp->_r)) != NULL) { - register char *ret; + char *ret; /* * Found one. Flag buffer as modified to keep fseek from * `optimising' a backward seek, in case the user stomps on * the text. */ p++; /* advance over it */ ret = (char *)fp->_p; *lenp = len = p - fp->_p; fp->_flags |= __SMOD; fp->_r -= len; fp->_p = p; + FUNLOCKFILE(fp); return (ret); } /* * We have to copy the current buffered data to the line buffer. * As a bonus, though, we can leave off the __SMOD. * * OPTIMISTIC is length that we (optimistically) expect will * accomodate the `rest' of the string, on each trip through the * loop below. */ #define OPTIMISTIC 80 for (len = fp->_r, off = 0;; len += fp->_r) { - register size_t diff; + size_t diff; /* * Make sure there is room for more bytes. Copy data from * file buffer to line buffer, refill file and look for * newline. The loop stops only when we find a newline. */ - if (__slbexpand(fp, len + OPTIMISTIC)) + if (slbexpand(fp, len + OPTIMISTIC)) goto error; (void)memcpy((void *)(fp->_lb._base + off), (void *)fp->_p, len - off); off = len; if (__srefill(fp)) break; /* EOF or error: return partial line */ if ((p = memchr((void *)fp->_p, '\n', (size_t)fp->_r)) == NULL) continue; /* got it: finish up the line (like code above) */ p++; diff = p - fp->_p; len += diff; - if (__slbexpand(fp, len)) + if (slbexpand(fp, len)) goto error; (void)memcpy((void *)(fp->_lb._base + off), (void *)fp->_p, diff); fp->_r -= diff; fp->_p = p; break; } *lenp = len; #ifdef notdef fp->_lb._base[len] = 0; #endif + FUNLOCKFILE(fp); return ((char *)fp->_lb._base); error: *lenp = 0; /* ??? */ + FUNLOCKFILE(fp); return (NULL); /* ??? */ } Index: head/lib/libc/stdio/fgetpos.c =================================================================== --- head/lib/libc/stdio/fgetpos.c (revision 72372) +++ head/lib/libc/stdio/fgetpos.c (revision 72373) @@ -1,60 +1,57 @@ /*- * Copyright (c) 1990, 1993 * The Regents of the University of California. All rights reserved. * * This code is derived from software contributed to Berkeley by * Chris Torek. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * 3. All advertising materials mentioning features or use of this software * must display the following acknowledgement: * This product includes software developed by the University of * California, Berkeley and its contributors. * 4. Neither the name of the University nor the names of its contributors * may be used to endorse or promote products derived from this software * without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. */ #if defined(LIBC_SCCS) && !defined(lint) #if 0 static char sccsid[] = "@(#)fgetpos.c 8.1 (Berkeley) 6/4/93"; #endif static const char rcsid[] = "$FreeBSD$"; #endif /* LIBC_SCCS and not lint */ -#include "namespace.h" #include -#include "un-namespace.h" -#include "libc_private.h" int -fgetpos(fp, pos) - FILE *fp; - fpos_t *pos; +fgetpos(FILE *fp, fpos_t *pos) { - int retval; - FLOCKFILE(fp); - retval = (*pos = ftello(fp)) == (fpos_t)-1; - FUNLOCKFILE(fp); - return(retval); + /* + * ftello is thread-safe; no need to lock fp. + */ + if ((*pos = ftello(fp)) == (fpos_t)-1) + return (-1); + else + return (0); } Index: head/lib/libc/stdio/fileno.c =================================================================== --- head/lib/libc/stdio/fileno.c (revision 72372) +++ head/lib/libc/stdio/fileno.c (revision 72373) @@ -1,57 +1,58 @@ /*- * Copyright (c) 1990, 1993 * The Regents of the University of California. All rights reserved. * * This code is derived from software contributed to Berkeley by * Chris Torek. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * 3. All advertising materials mentioning features or use of this software * must display the following acknowledgement: * This product includes software developed by the University of * California, Berkeley and its contributors. * 4. Neither the name of the University nor the names of its contributors * may be used to endorse or promote products derived from this software * without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. */ #if defined(LIBC_SCCS) && !defined(lint) #if 0 static char sccsid[] = "@(#)fileno.c 8.1 (Berkeley) 6/4/93"; #endif static const char rcsid[] = "$FreeBSD$"; #endif /* LIBC_SCCS and not lint */ #include /* - * A subroutine version of the macro fileno. + * fileno has traditionally been a macro in . That is + * no longer true because it needs to be thread-safe. + * + * #undef fileno */ -#undef fileno - int -fileno(fp) - FILE *fp; +fileno(FILE *fp) { + /* ??? - Should probably use atomic_read. */ return (__sfileno(fp)); } Index: head/lib/libc/stdio/findfp.c =================================================================== --- head/lib/libc/stdio/findfp.c (revision 72372) +++ head/lib/libc/stdio/findfp.c (revision 72373) @@ -1,209 +1,209 @@ /*- * Copyright (c) 1990, 1993 * The Regents of the University of California. All rights reserved. * * This code is derived from software contributed to Berkeley by * Chris Torek. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * 3. All advertising materials mentioning features or use of this software * must display the following acknowledgement: * This product includes software developed by the University of * California, Berkeley and its contributors. * 4. Neither the name of the University nor the names of its contributors * may be used to endorse or promote products derived from this software * without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. */ #if defined(LIBC_SCCS) && !defined(lint) #if 0 static char sccsid[] = "@(#)findfp.c 8.2 (Berkeley) 1/4/94"; #endif static const char rcsid[] = "$FreeBSD$"; #endif /* LIBC_SCCS and not lint */ #include #include #include #include #include #include #include #include "libc_private.h" #include "local.h" #include "glue.h" int __sdidinit; #define NDYNAMIC 10 /* add ten more whenever necessary */ #define std(flags, file) \ {0,0,0,flags,file,{0},0,__sF+file,__sclose,__sread,__sseek,__swrite} /* p r w flags file _bf z cookie close read seek write */ /* the usual - (stdin + stdout + stderr) */ static FILE usual[FOPEN_MAX - 3]; static struct glue uglue = { NULL, FOPEN_MAX - 3, usual }; FILE __sF[3] = { std(__SRD, STDIN_FILENO), /* stdin */ std(__SWR, STDOUT_FILENO), /* stdout */ std(__SWR|__SNBF, STDERR_FILENO) /* stderr */ }; struct glue __sglue = { &uglue, 3, __sF }; static struct glue *lastglue = &uglue; static struct glue * moreglue __P((int)); static spinlock_t thread_lock = _SPINLOCK_INITIALIZER; #define THREAD_LOCK() if (__isthreaded) _SPINLOCK(&thread_lock) #define THREAD_UNLOCK() if (__isthreaded) _SPINUNLOCK(&thread_lock) #if NOT_YET -#define SET_GLUE_PTR(ptr, val) atomic_set_ptr(&(ptr), (uintptr_t)(val)) +#define SET_GLUE_PTR(ptr, val) atomic_set_rel_ptr(&(ptr), (uintptr_t)(val)) #else #define SET_GLUE_PTR(ptr, val) ptr = val #endif static struct glue * moreglue(n) int n; { struct glue *g; FILE *p; static FILE empty; g = (struct glue *)malloc(sizeof(*g) + ALIGNBYTES + n * sizeof(FILE)); if (g == NULL) return (NULL); p = (FILE *)ALIGN(g + 1); g->next = NULL; g->niobs = n; g->iobs = p; while (--n >= 0) *p++ = empty; return (g); } /* * Find a free FILE for fopen et al. */ FILE * __sfp() { FILE *fp; int n; struct glue *g; if (!__sdidinit) __sinit(); /* * The list must be locked because a FILE may be updated. */ THREAD_LOCK(); for (g = &__sglue; g != NULL; g = g->next) { for (fp = g->iobs, n = g->niobs; --n >= 0; fp++) if (fp->_flags == 0) goto found; } THREAD_UNLOCK(); /* don't hold lock while malloc()ing. */ if ((g = moreglue(NDYNAMIC)) == NULL) return (NULL); THREAD_LOCK(); /* reacquire the lock */ SET_GLUE_PTR(lastglue->next, g); /* atomically append glue to list */ lastglue = g; /* not atomic; only accessed when locked */ fp = g->iobs; found: fp->_flags = 1; /* reserve this slot; caller sets real flags */ THREAD_UNLOCK(); fp->_p = NULL; /* no current pointer */ fp->_w = 0; /* nothing to read or write */ fp->_r = 0; fp->_bf._base = NULL; /* no buffer */ fp->_bf._size = 0; fp->_lbfsize = 0; /* not line buffered */ fp->_file = -1; /* no file */ /* fp->_cookie = ; */ /* caller sets cookie, _read/_write etc */ fp->_ub._base = NULL; /* no ungetc buffer */ fp->_ub._size = 0; fp->_lb._base = NULL; /* no line buffer */ fp->_lb._size = 0; - /* fp->_lock = NULL; */ +/* fp->_lock = NULL; */ /* once set always set (reused) */ return (fp); } /* * XXX. Force immediate allocation of internal memory. Not used by stdio, * but documented historically for certain applications. Bad applications. */ __warn_references(f_prealloc, "warning: this program uses f_prealloc(), which is stupid."); void f_prealloc() { struct glue *g; int n; n = getdtablesize() - FOPEN_MAX + 20; /* 20 for slop. */ /* * It should be safe to walk the list without locking it; * new nodes are only added to the end and none are ever * removed. */ for (g = &__sglue; (n -= g->niobs) > 0 && g->next; g = g->next) /* void */; if ((n > 0) && ((g = moreglue(n)) != NULL)) { THREAD_LOCK(); SET_GLUE_PTR(lastglue->next, g); lastglue = g; THREAD_UNLOCK(); } } /* * exit() calls _cleanup() through *__cleanup, set whenever we * open or buffer a file. This chicanery is done so that programs * that do not use stdio need not link it all in. * * The name `_cleanup' is, alas, fairly well known outside stdio. */ void _cleanup() { /* (void) _fwalk(fclose); */ (void) _fwalk(__sflush); /* `cheating' */ } /* * __sinit() is called whenever stdio's internal variables must be set up. */ void __sinit() { - /* make sure we clean up on exit */ + /* Make sure we clean up on exit. */ __cleanup = _cleanup; /* conservative */ __sdidinit = 1; } Index: head/lib/libc/stdio/fopen.c =================================================================== --- head/lib/libc/stdio/fopen.c (revision 72372) +++ head/lib/libc/stdio/fopen.c (revision 72373) @@ -1,89 +1,88 @@ /*- * Copyright (c) 1990, 1993 * The Regents of the University of California. All rights reserved. * * This code is derived from software contributed to Berkeley by * Chris Torek. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * 3. All advertising materials mentioning features or use of this software * must display the following acknowledgement: * This product includes software developed by the University of * California, Berkeley and its contributors. * 4. Neither the name of the University nor the names of its contributors * may be used to endorse or promote products derived from this software * without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. * * $FreeBSD$ */ #if defined(LIBC_SCCS) && !defined(lint) static char sccsid[] = "@(#)fopen.c 8.1 (Berkeley) 6/4/93"; #endif /* LIBC_SCCS and not lint */ #include "namespace.h" #include #include #include #include #include #include "un-namespace.h" #include "local.h" FILE * fopen(file, mode) const char *file; const char *mode; { FILE *fp; int f; int flags, oflags; if ((flags = __sflags(mode, &oflags)) == 0) return (NULL); if ((fp = __sfp()) == NULL) return (NULL); if ((f = _open(file, oflags, DEFFILEMODE)) < 0) { fp->_flags = 0; /* release */ return (NULL); } fp->_file = f; fp->_flags = flags; fp->_cookie = fp; fp->_read = __sread; fp->_write = __swrite; fp->_seek = __sseek; fp->_close = __sclose; - /* fp->_lock = NULL; */ /* * When opening in append mode, even though we use O_APPEND, * we need to seek to the end so that ftell() gets the right * answer. If the user then alters the seek pointer, or * the file extends, this will fail, but there is not much * we can do about this. (We could set __SAPP and check in * fseek and ftell.) */ if (oflags & O_APPEND) (void) __sseek((void *)fp, (fpos_t)0, SEEK_END); return (fp); } Index: head/lib/libc/stdio/freopen.c =================================================================== --- head/lib/libc/stdio/freopen.c (revision 72372) +++ head/lib/libc/stdio/freopen.c (revision 72373) @@ -1,166 +1,166 @@ /*- * Copyright (c) 1990, 1993 * The Regents of the University of California. All rights reserved. * * This code is derived from software contributed to Berkeley by * Chris Torek. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * 3. All advertising materials mentioning features or use of this software * must display the following acknowledgement: * This product includes software developed by the University of * California, Berkeley and its contributors. * 4. Neither the name of the University nor the names of its contributors * may be used to endorse or promote products derived from this software * without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. */ #if defined(LIBC_SCCS) && !defined(lint) #if 0 static char sccsid[] = "@(#)freopen.c 8.1 (Berkeley) 6/4/93"; #endif static const char rcsid[] = "$FreeBSD$"; #endif /* LIBC_SCCS and not lint */ #include "namespace.h" #include #include #include #include #include #include #include #include "un-namespace.h" #include "libc_private.h" #include "local.h" /* * Re-direct an existing, open (probably) file to some other file. * ANSI is written such that the original file gets closed if at * all possible, no matter what. */ FILE * freopen(file, mode, fp) const char *file, *mode; - register FILE *fp; + FILE *fp; { - register int f; + int f; int flags, isopen, oflags, sverrno, wantfd; if ((flags = __sflags(mode, &oflags)) == 0) { (void) fclose(fp); return (NULL); } FLOCKFILE(fp); if (!__sdidinit) __sinit(); /* * There are actually programs that depend on being able to "freopen" * descriptors that weren't originally open. Keep this from breaking. * Remember whether the stream was open to begin with, and which file * descriptor (if any) was associated with it. If it was attached to * a descriptor, defer closing it; freopen("/dev/stdin", "r", stdin) * should work. This is unnecessary if it was not a Unix file. */ if (fp->_flags == 0) { fp->_flags = __SEOF; /* hold on to it */ isopen = 0; wantfd = -1; } else { /* flush the stream; ANSI doesn't require this. */ if (fp->_flags & __SWR) (void) __sflush(fp); /* if close is NULL, closing is a no-op, hence pointless */ isopen = fp->_close != NULL; if ((wantfd = fp->_file) < 0 && isopen) { (void) (*fp->_close)(fp->_cookie); isopen = 0; } } /* Get a new descriptor to refer to the new file. */ f = _open(file, oflags, DEFFILEMODE); if (f < 0 && isopen) { /* If out of fd's close the old one and try again. */ if (errno == ENFILE || errno == EMFILE) { (void) (*fp->_close)(fp->_cookie); isopen = 0; f = _open(file, oflags, DEFFILEMODE); } } sverrno = errno; /* * Finish closing fp. Even if the open succeeded above, we cannot * keep fp->_base: it may be the wrong size. This loses the effect * of any setbuffer calls, but stdio has always done this before. */ if (isopen) (void) (*fp->_close)(fp->_cookie); if (fp->_flags & __SMBF) free((char *)fp->_bf._base); fp->_w = 0; fp->_r = 0; fp->_p = NULL; fp->_bf._base = NULL; fp->_bf._size = 0; fp->_lbfsize = 0; if (HASUB(fp)) FREEUB(fp); fp->_ub._size = 0; if (HASLB(fp)) FREELB(fp); fp->_lb._size = 0; if (f < 0) { /* did not get it after all */ fp->_flags = 0; /* set it free */ errno = sverrno; /* restore in case _close clobbered */ FUNLOCKFILE(fp); return (NULL); } /* * If reopening something that was open before on a real file, try * to maintain the descriptor. Various C library routines (perror) * assume stderr is always fd STDERR_FILENO, even if being freopen'd. */ if (wantfd >= 0 && f != wantfd) { if (_dup2(f, wantfd) >= 0) { (void)_close(f); f = wantfd; } } fp->_flags = flags; fp->_file = f; fp->_cookie = fp; fp->_read = __sread; fp->_write = __swrite; fp->_seek = __sseek; fp->_close = __sclose; FUNLOCKFILE(fp); return (fp); } Index: head/lib/libc/stdio/fwalk.c =================================================================== --- head/lib/libc/stdio/fwalk.c (revision 72372) +++ head/lib/libc/stdio/fwalk.c (revision 72373) @@ -1,70 +1,73 @@ /*- * Copyright (c) 1990, 1993 * The Regents of the University of California. All rights reserved. * * This code is derived from software contributed to Berkeley by * Chris Torek. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * 3. All advertising materials mentioning features or use of this software * must display the following acknowledgement: * This product includes software developed by the University of * California, Berkeley and its contributors. * 4. Neither the name of the University nor the names of its contributors * may be used to endorse or promote products derived from this software * without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. */ #if defined(LIBC_SCCS) && !defined(lint) #if 0 static char sccsid[] = "@(#)fwalk.c 8.1 (Berkeley) 6/4/93"; #endif static const char rcsid[] = "$FreeBSD$"; #endif /* LIBC_SCCS and not lint */ #include #include #include #include "local.h" #include "glue.h" int _fwalk(function) int (*function)(FILE *); { FILE *fp; int n, ret; struct glue *g; ret = 0; /* * It should be safe to walk the list without locking it; * new nodes are only added to the end and none are ever * removed. + * + * Avoid locking this list while walking it or else you will + * introduce a potential deadlock in [at least] refill.c. */ for (g = &__sglue; g != NULL; g = g->next) for (fp = g->iobs, n = g->niobs; --n >= 0; fp++) - if (fp->_flags != 0) + if ((fp->_flags != 0) && ((fp->_flags & __SIGN) == 0)) ret |= (*function)(fp); return (ret); } Index: head/lib/libc/stdio/getc.c =================================================================== --- head/lib/libc/stdio/getc.c (revision 72372) +++ head/lib/libc/stdio/getc.c (revision 72373) @@ -1,60 +1,59 @@ /*- * Copyright (c) 1990, 1993 * The Regents of the University of California. All rights reserved. * * This code is derived from software contributed to Berkeley by * Chris Torek. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * 3. All advertising materials mentioning features or use of this software * must display the following acknowledgement: * This product includes software developed by the University of * California, Berkeley and its contributors. * 4. Neither the name of the University nor the names of its contributors * may be used to endorse or promote products derived from this software * without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. */ #if defined(LIBC_SCCS) && !defined(lint) #if 0 static char sccsid[] = "@(#)getc.c 8.1 (Berkeley) 6/4/93"; #endif static const char rcsid[] = "$FreeBSD$"; #endif /* LIBC_SCCS and not lint */ #include "namespace.h" #include #include "un-namespace.h" #include "libc_private.h" +#include "local.h" -#undef getc int -getc(fp) - register FILE *fp; +getc(FILE *fp) { int retval; FLOCKFILE(fp); retval = __sgetc(fp); FUNLOCKFILE(fp); return (retval); } Index: head/lib/libc/stdio/refill.c =================================================================== --- head/lib/libc/stdio/refill.c (revision 72372) +++ head/lib/libc/stdio/refill.c (revision 72373) @@ -1,137 +1,149 @@ /*- * Copyright (c) 1990, 1993 * The Regents of the University of California. All rights reserved. * * This code is derived from software contributed to Berkeley by * Chris Torek. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * 3. All advertising materials mentioning features or use of this software * must display the following acknowledgement: * This product includes software developed by the University of * California, Berkeley and its contributors. * 4. Neither the name of the University nor the names of its contributors * may be used to endorse or promote products derived from this software * without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. */ #if defined(LIBC_SCCS) && !defined(lint) #if 0 static char sccsid[] = "@(#)refill.c 8.1 (Berkeley) 6/4/93"; #endif static const char rcsid[] = "$FreeBSD$"; #endif /* LIBC_SCCS and not lint */ +#include "namespace.h" #include #include #include +#include "un-namespace.h" +#include "libc_private.h" #include "local.h" static int lflush __P((FILE *)); static int -lflush(fp) - FILE *fp; +lflush(FILE *fp) { + int ret = 0; - if ((fp->_flags & (__SLBF|__SWR)) == (__SLBF|__SWR)) - return (__sflush(fp)); - return (0); + if ((fp->_flags & (__SLBF|__SWR)) == (__SLBF|__SWR)) { + FLOCKFILE(fp); + ret = __sflush(fp); + FUNLOCKFILE(fp); + } + return (ret); } /* * Refill a stdio buffer. * Return EOF on eof or error, 0 otherwise. */ int -__srefill(fp) - register FILE *fp; +__srefill(FILE *fp) { - /* make sure stdio is set up */ if (!__sdidinit) __sinit(); fp->_r = 0; /* largely a convenience for callers */ /* SysV does not make this test; take it out for compatibility */ if (fp->_flags & __SEOF) return (EOF); /* if not already reading, have to be reading and writing */ if ((fp->_flags & __SRD) == 0) { if ((fp->_flags & __SRW) == 0) { errno = EBADF; fp->_flags |= __SERR; return (EOF); } /* switch to reading */ if (fp->_flags & __SWR) { if (__sflush(fp)) return (EOF); fp->_flags &= ~__SWR; fp->_w = 0; fp->_lbfsize = 0; } fp->_flags |= __SRD; } else { /* * We were reading. If there is an ungetc buffer, * we must have been reading from that. Drop it, * restoring the previous buffer (if any). If there * is anything in that buffer, return. */ if (HASUB(fp)) { FREEUB(fp); if ((fp->_r = fp->_ur) != 0) { fp->_p = fp->_up; return (0); } } } if (fp->_bf._base == NULL) __smakebuf(fp); /* * Before reading from a line buffered or unbuffered file, * flush all line buffered output files, per the ANSI C * standard. */ - if (fp->_flags & (__SLBF|__SNBF)) + if (fp->_flags & (__SLBF|__SNBF)) { + /* Ignore this file in _fwalk to avoid potential deadlock. */ + fp->_flags |= __SIGN; (void) _fwalk(lflush); + fp->_flags &= ~__SIGN; + + /* Now flush this file without locking it. */ + if ((fp->_flags & (__SLBF|__SWR)) == (__SLBF|__SWR)) + __sflush(fp); + } fp->_p = fp->_bf._base; fp->_r = (*fp->_read)(fp->_cookie, (char *)fp->_p, fp->_bf._size); fp->_flags &= ~__SMOD; /* buffer contents are again pristine */ if (fp->_r <= 0) { if (fp->_r == 0) fp->_flags |= __SEOF; else { fp->_r = 0; fp->_flags |= __SERR; } return (EOF); } return (0); } Index: head/lib/libc/stdio/rget.c =================================================================== --- head/lib/libc/stdio/rget.c (revision 72372) +++ head/lib/libc/stdio/rget.c (revision 72373) @@ -1,64 +1,61 @@ /*- * Copyright (c) 1990, 1993 * The Regents of the University of California. All rights reserved. * * This code is derived from software contributed to Berkeley by * Chris Torek. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * 3. All advertising materials mentioning features or use of this software * must display the following acknowledgement: * This product includes software developed by the University of * California, Berkeley and its contributors. * 4. Neither the name of the University nor the names of its contributors * may be used to endorse or promote products derived from this software * without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. */ #if defined(LIBC_SCCS) && !defined(lint) #if 0 static char sccsid[] = "@(#)rget.c 8.1 (Berkeley) 6/4/93"; #endif static const char rcsid[] = - "$Id"; + "$FreeBSD$"; #endif /* LIBC_SCCS and not lint */ #include #include "local.h" -int -__srefill(FILE *); - /* * Handle getc() when the buffer ran out: * Refill, then return the first character * in the newly-filled buffer. */ -int __srget(fp) - register FILE *fp; +int +__srget(FILE *fp) { if (__srefill(fp) == 0) { fp->_r--; return (*fp->_p++); } return (EOF); } Index: head/lib/libc/stdio/snprintf.c =================================================================== --- head/lib/libc/stdio/snprintf.c (revision 72372) +++ head/lib/libc/stdio/snprintf.c (revision 72373) @@ -1,89 +1,91 @@ /*- * Copyright (c) 1990, 1993 * The Regents of the University of California. All rights reserved. * * This code is derived from software contributed to Berkeley by * Chris Torek. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * 3. All advertising materials mentioning features or use of this software * must display the following acknowledgement: * This product includes software developed by the University of * California, Berkeley and its contributors. * 4. Neither the name of the University nor the names of its contributors * may be used to endorse or promote products derived from this software * without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. */ #if defined(LIBC_SCCS) && !defined(lint) #if 0 static char sccsid[] = "@(#)snprintf.c 8.1 (Berkeley) 6/4/93"; #endif static const char rcsid[] = "$FreeBSD$"; #endif /* LIBC_SCCS and not lint */ #include #include #if __STDC__ #include #else #include #endif +#include "local.h" + #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; char *fmt; va_dcl #endif { size_t on; int ret; va_list ap; FILE f; on = n; if (n != 0) n--; if (n > INT_MAX) n = INT_MAX; #if __STDC__ va_start(ap, fmt); #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; - ret = vfprintf(&f, fmt, ap); + ret = __vfprintf(&f, fmt, ap); if (on > 0) *f._p = '\0'; va_end(ap); return (ret); } Index: head/lib/libc/stdio/sprintf.c =================================================================== --- head/lib/libc/stdio/sprintf.c (revision 72372) +++ head/lib/libc/stdio/sprintf.c (revision 72373) @@ -1,81 +1,81 @@ /*- * Copyright (c) 1990, 1993 * The Regents of the University of California. All rights reserved. * * This code is derived from software contributed to Berkeley by * Chris Torek. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * 3. All advertising materials mentioning features or use of this software * must display the following acknowledgement: * This product includes software developed by the University of * California, Berkeley and its contributors. * 4. Neither the name of the University nor the names of its contributors * may be used to endorse or promote products derived from this software * without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. */ #if defined(LIBC_SCCS) && !defined(lint) #if 0 static char sccsid[] = "@(#)sprintf.c 8.1 (Berkeley) 6/4/93"; #endif static const char rcsid[] = "$FreeBSD$"; #endif /* LIBC_SCCS and not lint */ #include #if __STDC__ #include #else #include #endif #include #include "local.h" int #if __STDC__ sprintf(char *str, char const *fmt, ...) #else sprintf(str, fmt, va_alist) char *str; char *fmt; va_dcl #endif { int ret; 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; #if __STDC__ va_start(ap, fmt); #else va_start(ap); #endif - ret = vfprintf(&f, fmt, ap); + ret = __vfprintf(&f, fmt, ap); va_end(ap); *f._p = 0; return (ret); }