aboutsummaryrefslogtreecommitdiffstats
path: root/libc/stdio/refill.c
diff options
context:
space:
mode:
Diffstat (limited to 'libc/stdio/refill.c')
-rw-r--r--libc/stdio/refill.c13
1 files changed, 10 insertions, 3 deletions
diff --git a/libc/stdio/refill.c b/libc/stdio/refill.c
index 74b378e14..7cb6b7892 100644
--- a/libc/stdio/refill.c
+++ b/libc/stdio/refill.c
@@ -39,9 +39,8 @@
static int
lflush(FILE *fp)
{
-
if ((fp->_flags & (__SLBF|__SWR)) == (__SLBF|__SWR))
- return (__sflush(fp));
+ return (__sflush_locked(fp)); /* ignored... */
return (0);
}
@@ -103,8 +102,16 @@ __srefill(FILE *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 */