summaryrefslogtreecommitdiffstats
path: root/libc/stdio
diff options
context:
space:
mode:
Diffstat (limited to 'libc/stdio')
-rw-r--r--libc/stdio/printf.c4
-rw-r--r--libc/stdio/scanf.c2
-rw-r--r--libc/stdio/stdio.c29
3 files changed, 26 insertions, 9 deletions
diff --git a/libc/stdio/printf.c b/libc/stdio/printf.c
index 47c11c6bf..365cd41a2 100644
--- a/libc/stdio/printf.c
+++ b/libc/stdio/printf.c
@@ -61,6 +61,7 @@
#include <printf.h>
#ifdef __STDIO_THREADSAFE
+#include <stdio_ext.h>
#include <pthread.h>
#endif /* __STDIO_THREADSAFE */
@@ -1313,6 +1314,7 @@ int vsnprintf(char *__restrict buf, size_t size,
#endif /* __STDIO_MBSTATE */
#ifdef __STDIO_THREADSAFE
+ f.user_locking = 0;
__stdio_init_mutex(&f.lock);
#endif
@@ -1392,6 +1394,7 @@ int vsnprintf(char *__restrict buf, size_t size,
#endif /* __STDIO_MBSTATE */
#ifdef __STDIO_THREADSAFE
+ f.user_locking = 0;
__stdio_init_mutex(&f.lock);
#endif
@@ -1439,6 +1442,7 @@ int vdprintf(int filedes, const char * __restrict format, va_list arg)
#endif /* __STDIO_MBSTATE */
#ifdef __STDIO_THREADSAFE
+ f.user_locking = 0;
__stdio_init_mutex(&f.lock);
#endif
diff --git a/libc/stdio/scanf.c b/libc/stdio/scanf.c
index 6d7a84e57..f392fe790 100644
--- a/libc/stdio/scanf.c
+++ b/libc/stdio/scanf.c
@@ -42,6 +42,7 @@
#include <stdarg.h>
#ifdef __STDIO_THREADSAFE
+#include <stdio_ext.h>
#include <pthread.h>
#endif /* __STDIO_THREADSAFE */
@@ -128,6 +129,7 @@ int vsscanf(__const char *sp, __const char *fmt, va_list ap)
#endif /* __STDIO_MBSTATE */
#ifdef __STDIO_THREADSAFE
+ string->user_locking = 0;
__stdio_init_mutex(&string->lock);
#endif
diff --git a/libc/stdio/stdio.c b/libc/stdio/stdio.c
index 2c5f3bbed..bd6a7263c 100644
--- a/libc/stdio/stdio.c
+++ b/libc/stdio/stdio.c
@@ -1023,31 +1023,41 @@ void _flushlbf(void)
/**********************************************************************/
#ifdef L___fsetlocking
-/* No (serious) reentrancy issues -- return value could be incorrect. */
-/* TODO -- fix race */
+/* NOT threadsafe!!! (I don't think glibc's is either)
+ *
+ * This interacts badly with internal locking/unlocking. If you use this routine,
+ * make sure the file isn't being accessed by any other threads. Typical use would
+ * be to change to user locking immediately after opening the stream.
+ */
+
+link_warning(__fsetlocking, "Oddly enough, __fsetlocking() is NOT threadsafe.")
int __fsetlocking(FILE *stream, int locking_mode)
{
+#ifdef __STDIO_THREADSAFE
int old_mode;
+#endif
assert((FSETLOCKING_QUERY == 0) && (FSETLOCKING_INTERNAL == 1)
&& (FSETLOCKING_BYCALLER == 2));
assert(((unsigned int) locking_mode) <= 2);
- /* Note: don't even bother locking here... */
+#ifdef __STDIO_THREADSAFE
+ old_mode = stream->user_locking;
- old_mode = stream->user_locking;
+ assert(((unsigned int) old_mode) <= 1); /* Must be 0 (internal) or 1 (user). */
if (locking_mode != FSETLOCKING_QUERY) {
/* In case we're not debugging, treat any unknown as a request to
* set internal locking, in order to match glibc behavior. */
- stream->user_locking = ((locking_mode == FSETLOCKING_BYCALLER)
- ? FSETLOCKING_BYCALLER
- : FSETLOCKING_INTERNAL);
+ stream->user_locking = (locking_mode == FSETLOCKING_BYCALLER);
}
- return old_mode;
+ return 2 - old_mode;
+#else
+ return FSETLOCKING_BYCALLER; /* Well, without thread support... */
+#endif
}
#endif
@@ -1851,7 +1861,7 @@ void _stdio_term(void)
* Note: Set locking mode to "by caller" to save some overhead later. */
__stdio_init_mutex(&_stdio_openlist_lock);
for (ptr = _stdio_openlist ; ptr ; ptr = ptr->nextopen ) {
- ptr->user_locking = FSETLOCKING_BYCALLER;
+ ptr->user_locking = 1;
__stdio_init_mutex(&ptr->lock);
}
#endif /* __STDIO_THREADSAFE */
@@ -2358,6 +2368,7 @@ FILE *_stdio_fopen(const char * __restrict filename,
#endif /* __STDIO_MBSTATE */
#ifdef __STDIO_THREADSAFE
+ stream->user_locking = 0;
__stdio_init_mutex(&stream->lock);
#endif /* __STDIO_THREADSAFE */