summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--lib/libc/gen/_pthread_stubs.c12
-rw-r--r--lib/libc/include/namespace.h2
-rw-r--r--lib/libc/include/un-namespace.h2
-rw-r--r--lib/libc/stdio/_flock_stub.c150
-rw-r--r--lib/libc/stdio/asprintf.c4
-rw-r--r--lib/libc/stdio/fclose.c11
-rw-r--r--lib/libc/stdio/feof.c20
-rw-r--r--lib/libc/stdio/ferror.c20
-rw-r--r--lib/libc/stdio/fflush.c17
-rw-r--r--lib/libc/stdio/fgetc.c1
-rw-r--r--lib/libc/stdio/fgetln.c30
-rw-r--r--lib/libc/stdio/fgetpos.c19
-rw-r--r--lib/libc/stdio/fileno.c11
-rw-r--r--lib/libc/stdio/findfp.c6
-rw-r--r--lib/libc/stdio/fopen.c1
-rw-r--r--lib/libc/stdio/freopen.c4
-rw-r--r--lib/libc/stdio/fwalk.c5
-rw-r--r--lib/libc/stdio/getc.c5
-rw-r--r--lib/libc/stdio/refill.c30
-rw-r--r--lib/libc/stdio/rget.c9
-rw-r--r--lib/libc/stdio/snprintf.c4
-rw-r--r--lib/libc/stdio/sprintf.c2
22 files changed, 261 insertions, 104 deletions
diff --git a/lib/libc/gen/_pthread_stubs.c b/lib/libc/gen/_pthread_stubs.c
index 87b0ad2..be6dab7 100644
--- a/lib/libc/gen/_pthread_stubs.c
+++ b/lib/libc/gen/_pthread_stubs.c
@@ -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)
{
diff --git a/lib/libc/include/namespace.h b/lib/libc/include/namespace.h
index 95acce4..ddffa82 100644
--- a/lib/libc/include/namespace.h
+++ b/lib/libc/include/namespace.h
@@ -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
diff --git a/lib/libc/include/un-namespace.h b/lib/libc/include/un-namespace.h
index 4d2e8bd..76ba625 100644
--- a/lib/libc/include/un-namespace.h
+++ b/lib/libc/include/un-namespace.h
@@ -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
diff --git a/lib/libc/stdio/_flock_stub.c b/lib/libc/stdio/_flock_stub.c
index 83a3e86..8bea66d 100644
--- a/lib/libc/stdio/_flock_stub.c
+++ b/lib/libc/stdio/_flock_stub.c
@@ -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"
+
+/*
+ * Weak symbols for externally visible functions in this file:
+ */
+#pragma weak flockfile=_flockfile
+#pragma weak _flockfile_debug=_flockfile_debug_stub
+#pragma weak ftrylockfile=_ftrylockfile
+#pragma weak funlockfile=_funlockfile
+
+static int init_lock(FILE *);
/*
- * Declare weak references in case the application is not linked
- * with libpthread.
+ * The FILE lock structure. The FILE *fp is locked when the mutex
+ * is locked.
*/
-#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
+struct __file_lock {
+ pthread_mutex_t fl_mutex;
+ pthread_t fl_owner; /* current owner */
+ int fl_count; /* recursive lock count */
+};
/*
- * This function is a stub for the _flockfile function in libpthread.
+ * 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);
+ }
+ }
}
diff --git a/lib/libc/stdio/asprintf.c b/lib/libc/stdio/asprintf.c
index e125bfc..cf4fb3c 100644
--- a/lib/libc/stdio/asprintf.c
+++ b/lib/libc/stdio/asprintf.c
@@ -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);
diff --git a/lib/libc/stdio/fclose.c b/lib/libc/stdio/fclose.c
index 0d6fd80..e70a2da 100644
--- a/lib/libc/stdio/fclose.c
+++ b/lib/libc/stdio/fclose.c
@@ -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);
}
diff --git a/lib/libc/stdio/feof.c b/lib/libc/stdio/feof.c
index 3581100..60cad53 100644
--- a/lib/libc/stdio/feof.c
+++ b/lib/libc/stdio/feof.c
@@ -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);
}
diff --git a/lib/libc/stdio/ferror.c b/lib/libc/stdio/ferror.c
index 2311926..c4424c6 100644
--- a/lib/libc/stdio/ferror.c
+++ b/lib/libc/stdio/ferror.c
@@ -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);
}
diff --git a/lib/libc/stdio/fflush.c b/lib/libc/stdio/fflush.c
index 09d346b..5c1eaa1 100644
--- a/lib/libc/stdio/fflush.c
+++ b/lib/libc/stdio/fflush.c
@@ -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);
+}
diff --git a/lib/libc/stdio/fgetc.c b/lib/libc/stdio/fgetc.c
index a367af3..684da00 100644
--- a/lib/libc/stdio/fgetc.c
+++ b/lib/libc/stdio/fgetc.c
@@ -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)
diff --git a/lib/libc/stdio/fgetln.c b/lib/libc/stdio/fgetln.c
index 3987b0d..c607a9c 100644
--- a/lib/libc/stdio/fgetln.c
+++ b/lib/libc/stdio/fgetln.c
@@ -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); /* ??? */
}
diff --git a/lib/libc/stdio/fgetpos.c b/lib/libc/stdio/fgetpos.c
index 239f6d1..51f14ef 100644
--- a/lib/libc/stdio/fgetpos.c
+++ b/lib/libc/stdio/fgetpos.c
@@ -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);
}
diff --git a/lib/libc/stdio/fileno.c b/lib/libc/stdio/fileno.c
index 0c3a8dc..b8f500e 100644
--- a/lib/libc/stdio/fileno.c
+++ b/lib/libc/stdio/fileno.c
@@ -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));
}
diff --git a/lib/libc/stdio/findfp.c b/lib/libc/stdio/findfp.c
index 30e8f90..f307e3e 100644
--- a/lib/libc/stdio/findfp.c
+++ b/lib/libc/stdio/findfp.c
@@ -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;
}
diff --git a/lib/libc/stdio/fopen.c b/lib/libc/stdio/fopen.c
index 4ea2eb9..aca314c 100644
--- a/lib/libc/stdio/fopen.c
+++ b/lib/libc/stdio/fopen.c
@@ -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
diff --git a/lib/libc/stdio/freopen.c b/lib/libc/stdio/freopen.c
index fd8612c..a434d5a 100644
--- a/lib/libc/stdio/freopen.c
+++ b/lib/libc/stdio/freopen.c
@@ -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) {
diff --git a/lib/libc/stdio/fwalk.c b/lib/libc/stdio/fwalk.c
index 17cb5ce..b943be4 100644
--- a/lib/libc/stdio/fwalk.c
+++ b/lib/libc/stdio/fwalk.c
@@ -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);
}
diff --git a/lib/libc/stdio/getc.c b/lib/libc/stdio/getc.c
index 1668407..cabc40c 100644
--- a/lib/libc/stdio/getc.c
+++ b/lib/libc/stdio/getc.c
@@ -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);
diff --git a/lib/libc/stdio/refill.c b/lib/libc/stdio/refill.c
index 2db485bba..b597f97 100644
--- a/lib/libc/stdio/refill.c
+++ b/lib/libc/stdio/refill.c
@@ -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 */
diff --git a/lib/libc/stdio/rget.c b/lib/libc/stdio/rget.c
index 45d817d..4ec796f 100644
--- a/lib/libc/stdio/rget.c
+++ b/lib/libc/stdio/rget.c
@@ -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--;
diff --git a/lib/libc/stdio/snprintf.c b/lib/libc/stdio/snprintf.c
index bedf98d..fe21129 100644
--- a/lib/libc/stdio/snprintf.c
+++ b/lib/libc/stdio/snprintf.c
@@ -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);
diff --git a/lib/libc/stdio/sprintf.c b/lib/libc/stdio/sprintf.c
index 10e73f0..a810096 100644
--- a/lib/libc/stdio/sprintf.c
+++ b/lib/libc/stdio/sprintf.c
@@ -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);
OpenPOWER on IntegriCloud