summaryrefslogtreecommitdiff
path: root/libc/stdio/fclose.c
diff options
context:
space:
mode:
Diffstat (limited to 'libc/stdio/fclose.c')
-rw-r--r--libc/stdio/fclose.c66
1 files changed, 43 insertions, 23 deletions
diff --git a/libc/stdio/fclose.c b/libc/stdio/fclose.c
index 843599c0f..f3e181c8a 100644
--- a/libc/stdio/fclose.c
+++ b/libc/stdio/fclose.c
@@ -16,30 +16,36 @@ int fclose(register FILE *stream)
int rv = 0;
__STDIO_AUTO_THREADLOCK_VAR;
- /* First, remove the file from the open file list. */
-#ifdef __STDIO_HAS_OPENLIST
- {
- register FILE *ptr;
-
- __STDIO_THREADLOCK_OPENLIST;
- if ((ptr = _stdio_openlist) == stream) {
- _stdio_openlist = stream->__nextopen;
- } else {
- while (ptr) {
- if (ptr->__nextopen == stream) {
- ptr->__nextopen = stream->__nextopen;
- break;
- }
- ptr = ptr->__nextopen;
- }
- }
- __STDIO_THREADUNLOCK_OPENLIST;
-
- if (!ptr) { /* Did not find stream in the open file list! */
- return EOF;
- }
- }
+#ifdef __UCLIBC_MJN3_ONLY__
+#warning REMINDER: dead code... but may want to simply check and not remove
#endif
+/* #ifdef __STDIO_HAS_OPENLIST */
+/* #if !defined(__UCLIBC_HAS_THREADS__) || !defined(__STDIO_BUFFERS) */
+/* /\* First, remove the file from the open file list. *\/ */
+/* { */
+/* register FILE *ptr; */
+
+/* __STDIO_THREADLOCK_OPENLIST; */
+/* if ((ptr = _stdio_openlist) == stream) { */
+/* #warning does a mod!!! */
+/* _stdio_openlist = stream->__nextopen; */
+/* } else { */
+/* while (ptr) { */
+/* if (ptr->__nextopen == stream) { */
+/* ptr->__nextopen = stream->__nextopen; */
+/* break; */
+/* } */
+/* ptr = ptr->__nextopen; */
+/* } */
+/* } */
+/* __STDIO_THREADUNLOCK_OPENLIST; */
+
+/* if (!ptr) { /\* Did not find stream in the open file list! *\/ */
+/* return EOF; */
+/* } */
+/* } */
+/* #endif */
+/* #endif */
__STDIO_AUTO_THREADLOCK(stream);
@@ -62,6 +68,11 @@ int fclose(register FILE *stream)
* Since a file can't be both readonly and writeonly, that makes
* an effective signal. It also has the benefit of disabling
* transitions to either reading or writing. */
+#if defined(__UCLIBC_HAS_THREADS__) && defined(__STDIO_BUFFERS)
+ /* Before we mark the file as closed, make sure we increment the openlist use count
+ * so it isn't freed under us while still cleaning up. */
+ __STDIO_OPENLIST_INC_USE;
+#endif
stream->__modeflags &= (__FLAG_FREEBUF|__FLAG_FREEFILE);
stream->__modeflags |= (__FLAG_READONLY|__FLAG_WRITEONLY);
@@ -84,7 +95,16 @@ int fclose(register FILE *stream)
__STDIO_AUTO_THREADUNLOCK(stream);
__STDIO_STREAM_FREE_BUFFER(stream);
+#ifdef __UCLIBC_MJN3_ONLY__
+#warning REMINDER: inefficient - locks and unlocks twice and walks whole list
+#endif
+#if defined(__UCLIBC_HAS_THREADS__) && defined(__STDIO_BUFFERS)
+ /* inefficient - locks/unlocks twice and walks whole list */
+ __STDIO_OPENLIST_INC_DEL_CNT;
+ __STDIO_OPENLIST_DEC_USE; /* This with free the file if necessary. */
+#else
__STDIO_STREAM_FREE_FILE(stream);
+#endif
return rv;
}