libc MT-safety, part 2.
Add a lock to FILE. flockfile and friends are now implemented (for the most part) in libc. flockfile_debug is implemented in libc_r; I suppose it's about time to kill it but will do it in a future commit. Fix a potential deadlock in _fwalk in a threaded environment. A file flag (__SIGN) was added to stdio.h that, when set, tells _fwalk to ignore it in its walk. This seemed to be needed in refill.c because each file needs to be locked when flushing. Add a stub for pthread_self in libc. This is needed by flockfile which is allowed by POSIX to be recursive. Make fgetpos() error return value (-1) match man page. Remove recursive calls to locked functions (stdio); I think I've got them all, but I may have missed a couple. A few K&R -> ANSI conversions along with removal of a few instances of "register". $Id$ -> $FreeBSD$ in libc/stdio/rget.c Not objected to: -arch, a few months ago
This commit is contained in:
parent
5b62961a49
commit
29ac6bd228
@ -49,8 +49,14 @@
|
||||
#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)
|
||||
@ -124,6 +130,12 @@ _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)
|
||||
{
|
||||
|
@ -70,6 +70,7 @@
|
||||
#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
|
||||
@ -115,7 +116,6 @@
|
||||
#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
|
||||
|
@ -65,6 +65,7 @@
|
||||
#undef pthread_mutexattr_destroy
|
||||
#undef pthread_mutexattr_settype
|
||||
#undef pthread_once
|
||||
#undef pthread_self
|
||||
#undef pthread_setspecific
|
||||
#undef read
|
||||
#undef readv
|
||||
@ -102,7 +103,6 @@
|
||||
#undef pthread_rwlock_wrlock
|
||||
#undef pthread_rwlockattr_init
|
||||
#undef pthread_rwlockattr_destroy
|
||||
#undef pthread_self
|
||||
#undef sched_yield
|
||||
#undef sendfile
|
||||
#undef shutdown
|
||||
|
@ -33,49 +33,155 @@
|
||||
*
|
||||
*/
|
||||
|
||||
/*
|
||||
* 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 <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <pthread.h>
|
||||
#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.
|
||||
*/
|
||||
void
|
||||
_flockfile_stub(FILE *fp)
|
||||
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(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);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -40,6 +40,8 @@ static char rcsid[] = "$FreeBSD$";
|
||||
#include <varargs.h>
|
||||
#endif
|
||||
|
||||
#include "local.h"
|
||||
|
||||
int
|
||||
#if __STDC__
|
||||
asprintf(char **str, char const *fmt, ...)
|
||||
@ -68,7 +70,7 @@ asprintf(str, fmt, va_alist)
|
||||
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);
|
||||
|
@ -51,8 +51,7 @@ static const char rcsid[] =
|
||||
#include "local.h"
|
||||
|
||||
int
|
||||
fclose(fp)
|
||||
FILE *fp;
|
||||
fclose(FILE *fp)
|
||||
{
|
||||
int r;
|
||||
|
||||
@ -70,15 +69,9 @@ fclose(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);
|
||||
}
|
||||
|
@ -42,16 +42,24 @@ static const char rcsid[] =
|
||||
"$FreeBSD$";
|
||||
#endif /* LIBC_SCCS and not lint */
|
||||
|
||||
#include "namespace.h"
|
||||
#include <stdio.h>
|
||||
#include "un-namespace.h"
|
||||
#include "libc_private.h"
|
||||
|
||||
/*
|
||||
* A subroutine version of the macro feof.
|
||||
* feof has traditionally been a macro in <stdio.h>. 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);
|
||||
}
|
||||
|
@ -42,16 +42,24 @@ static const char rcsid[] =
|
||||
"$FreeBSD$";
|
||||
#endif /* LIBC_SCCS and not lint */
|
||||
|
||||
#include "namespace.h"
|
||||
#include <stdio.h>
|
||||
#include "un-namespace.h"
|
||||
#include "libc_private.h"
|
||||
|
||||
/*
|
||||
* A subroutine version of the macro ferror.
|
||||
* ferror has traditionally been a macro in <stdio.h>. 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);
|
||||
}
|
||||
|
@ -49,6 +49,8 @@ static const char rcsid[] =
|
||||
#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
|
||||
@ -59,7 +61,7 @@ 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;
|
||||
@ -80,7 +82,7 @@ __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;
|
||||
@ -120,3 +122,14 @@ __sflush(FILE *fp)
|
||||
}
|
||||
return (0);
|
||||
}
|
||||
|
||||
static int
|
||||
sflush_locked(FILE *fp)
|
||||
{
|
||||
int ret;
|
||||
|
||||
FLOCKFILE(fp);
|
||||
ret = __sflush(fp);
|
||||
FUNLOCKFILE(fp);
|
||||
return (ret);
|
||||
}
|
||||
|
@ -46,6 +46,7 @@ static const char rcsid[] =
|
||||
#include <stdio.h>
|
||||
#include "un-namespace.h"
|
||||
#include "libc_private.h"
|
||||
#include "local.h"
|
||||
|
||||
int
|
||||
fgetc(fp)
|
||||
|
@ -42,9 +42,12 @@ static const char rcsid[] =
|
||||
"$FreeBSD$";
|
||||
#endif /* LIBC_SCCS and not lint */
|
||||
|
||||
#include "namespace.h"
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include "un-namespace.h"
|
||||
#include "libc_private.h"
|
||||
#include "local.h"
|
||||
|
||||
/*
|
||||
@ -54,10 +57,8 @@ static const char rcsid[] =
|
||||
* 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;
|
||||
|
||||
@ -81,23 +82,23 @@ __slbexpand(fp, newsize)
|
||||
* 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
|
||||
@ -110,6 +111,7 @@ fgetln(fp, lenp)
|
||||
fp->_flags |= __SMOD;
|
||||
fp->_r -= len;
|
||||
fp->_p = p;
|
||||
FUNLOCKFILE(fp);
|
||||
return (ret);
|
||||
}
|
||||
|
||||
@ -124,14 +126,14 @@ fgetln(fp, lenp)
|
||||
#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);
|
||||
@ -145,7 +147,7 @@ fgetln(fp, lenp)
|
||||
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);
|
||||
@ -157,9 +159,11 @@ fgetln(fp, lenp)
|
||||
#ifdef notdef
|
||||
fp->_lb._base[len] = 0;
|
||||
#endif
|
||||
FUNLOCKFILE(fp);
|
||||
return ((char *)fp->_lb._base);
|
||||
|
||||
error:
|
||||
*lenp = 0; /* ??? */
|
||||
FUNLOCKFILE(fp);
|
||||
return (NULL); /* ??? */
|
||||
}
|
||||
|
@ -42,19 +42,16 @@ static const char rcsid[] =
|
||||
"$FreeBSD$";
|
||||
#endif /* LIBC_SCCS and not lint */
|
||||
|
||||
#include "namespace.h"
|
||||
#include <stdio.h>
|
||||
#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);
|
||||
}
|
||||
|
@ -45,13 +45,14 @@ static const char rcsid[] =
|
||||
#include <stdio.h>
|
||||
|
||||
/*
|
||||
* A subroutine version of the macro fileno.
|
||||
* fileno has traditionally been a macro in <stdio.h>. 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));
|
||||
}
|
||||
|
@ -82,7 +82,7 @@ static spinlock_t thread_lock = _SPINLOCK_INITIALIZER;
|
||||
#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
|
||||
@ -150,7 +150,7 @@ found:
|
||||
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);
|
||||
}
|
||||
|
||||
@ -203,7 +203,7 @@ _cleanup()
|
||||
void
|
||||
__sinit()
|
||||
{
|
||||
/* make sure we clean up on exit */
|
||||
/* Make sure we clean up on exit. */
|
||||
__cleanup = _cleanup; /* conservative */
|
||||
__sdidinit = 1;
|
||||
}
|
||||
|
@ -74,7 +74,6 @@ fopen(file, mode)
|
||||
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
|
||||
|
@ -62,9 +62,9 @@ static const char rcsid[] =
|
||||
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) {
|
||||
|
@ -61,10 +61,13 @@ _fwalk(function)
|
||||
* 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);
|
||||
}
|
||||
|
@ -46,11 +46,10 @@ static const char rcsid[] =
|
||||
#include <stdio.h>
|
||||
#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);
|
||||
|
@ -42,22 +42,28 @@ static const char rcsid[] =
|
||||
"$FreeBSD$";
|
||||
#endif /* LIBC_SCCS and not lint */
|
||||
|
||||
#include "namespace.h"
|
||||
#include <errno.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#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);
|
||||
}
|
||||
|
||||
/*
|
||||
@ -65,10 +71,8 @@ lflush(fp)
|
||||
* 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();
|
||||
@ -119,8 +123,16 @@ __srefill(fp)
|
||||
* 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 */
|
||||
|
@ -39,22 +39,19 @@
|
||||
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 <stdio.h>
|
||||
#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--;
|
||||
|
@ -50,6 +50,8 @@ static const char rcsid[] =
|
||||
#include <varargs.h>
|
||||
#endif
|
||||
|
||||
#include "local.h"
|
||||
|
||||
#if __STDC__
|
||||
int
|
||||
snprintf(char *str, size_t n, char const *fmt, ...)
|
||||
@ -81,7 +83,7 @@ snprintf(str, n, fmt, va_alist)
|
||||
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);
|
||||
|
@ -74,7 +74,7 @@ sprintf(str, fmt, va_alist)
|
||||
#else
|
||||
va_start(ap);
|
||||
#endif
|
||||
ret = vfprintf(&f, fmt, ap);
|
||||
ret = __vfprintf(&f, fmt, ap);
|
||||
va_end(ap);
|
||||
*f._p = 0;
|
||||
return (ret);
|
||||
|
Loading…
x
Reference in New Issue
Block a user