summaryrefslogtreecommitdiffstats
path: root/libc/stdio/_fopen.c
diff options
context:
space:
mode:
Diffstat (limited to 'libc/stdio/_fopen.c')
-rw-r--r--libc/stdio/_fopen.c37
1 files changed, 21 insertions, 16 deletions
diff --git a/libc/stdio/_fopen.c b/libc/stdio/_fopen.c
index 58066ea3f..d68f2ead1 100644
--- a/libc/stdio/_fopen.c
+++ b/libc/stdio/_fopen.c
@@ -76,13 +76,13 @@ FILE attribute_hidden *_stdio_fopen(intptr_t fname_or_mode,
while (*++mode) {
# ifdef __UCLIBC_HAS_FOPEN_EXCLUSIVE_MODE__
- if (*mode == 'x') { /* Open exclusive (a glibc extension). */
+ if (*mode == 'x') { /* Open exclusive (a glibc extension). */
open_mode |= O_EXCL;
continue;
}
# endif
# ifdef __UCLIBC_HAS_FOPEN_LARGEFILE_MODE__
- if (*mode == 'F') { /* Open as large file (uClibc extension). */
+ if (*mode == 'F') { /* Open as large file (uClibc extension). */
open_mode |= O_LARGEFILE;
continue;
}
@@ -102,11 +102,7 @@ FILE attribute_hidden *_stdio_fopen(intptr_t fname_or_mode,
#ifdef __UCLIBC_HAS_THREADS__
/* We only initialize the mutex in the non-freopen case. */
/* stream->__user_locking = _stdio_user_locking; */
-#ifdef __USE_STDIO_FUTEXES__
- _IO_lock_init (stream->_lock);
-#else
- __stdio_init_mutex(&stream->__lock);
-#endif
+ STDIO_INIT_MUTEX(stream->__lock);
#endif
}
@@ -198,18 +194,27 @@ FILE attribute_hidden *_stdio_fopen(intptr_t fname_or_mode,
#ifdef __UCLIBC_HAS_THREADS__
/* Even in the freopen case, we reset the user locking flag. */
stream->__user_locking = _stdio_user_locking;
-#ifdef __USE_STDIO_FUTEXES__
- /* _IO_lock_init (stream->_lock); */
-#else
- /* __stdio_init_mutex(&stream->__lock); */
-#endif
+ /* STDIO_INIT_MUTEX(stream->__lock); */
#endif
#ifdef __STDIO_HAS_OPENLIST
- __STDIO_THREADLOCK_OPENLIST;
- stream->__nextopen = _stdio_openlist; /* New files are inserted at */
- _stdio_openlist = stream; /* the head of the list. */
- __STDIO_THREADUNLOCK_OPENLIST;
+#if defined(__UCLIBC_HAS_THREADS__) && defined(__STDIO_BUFFERS)
+ if (!(stream->__modeflags & __FLAG_FREEFILE))
+ {
+ /* An freopen call so the file was never removed from the list. */
+ }
+ else
+#endif
+ {
+ /* We have to lock the del mutex in case another thread wants to fclose()
+ * the last file. */
+ __STDIO_THREADLOCK_OPENLIST_DEL;
+ __STDIO_THREADLOCK_OPENLIST_ADD;
+ stream->__nextopen = _stdio_openlist; /* New files are inserted at */
+ _stdio_openlist = stream; /* the head of the list. */
+ __STDIO_THREADUNLOCK_OPENLIST_ADD;
+ __STDIO_THREADUNLOCK_OPENLIST_DEL;
+ }
#endif
__STDIO_STREAM_VALIDATE(stream);