diff options
author | Mike Frysinger <vapier@gentoo.org> | 2007-02-08 18:05:44 +0000 |
---|---|---|
committer | Mike Frysinger <vapier@gentoo.org> | 2007-02-08 18:05:44 +0000 |
commit | 3dcb135f7b6add6b8237b45dd8da6a04eec9942e (patch) | |
tree | 85c34716c5e39e875efd64f53adec125b3ab4900 /libc/stdio | |
parent | 3a57ff2c1f6b7bb8fc6d7bcf8165b542f86b3c5c (diff) |
Paul Brook writes:
I'm seeing a hang in applications that open and close files with a
non-threaded uClibc. There is code in fclose() to remove a file handle from
_stdio_openlist however it's commented out, allegedly because it is dead.
_stdio_openlist is used in several places, including _stdio_term when a
program exits. fclose() frees the struct, so I don't see how the code can
possibly be redundant.
In the __UCLIBC_HAS_THREADS__ && __STDIO_BUFFERS case the file is removed from
_stdio_openlist by __STDIO_OPENLIST_DEC_USE.
The attached patch fixes this bug be re-enabling the code.
Diffstat (limited to 'libc/stdio')
-rw-r--r-- | libc/stdio/fclose.c | 53 |
1 files changed, 24 insertions, 29 deletions
diff --git a/libc/stdio/fclose.c b/libc/stdio/fclose.c index f3e181c8a..27d3c7e96 100644 --- a/libc/stdio/fclose.c +++ b/libc/stdio/fclose.c @@ -16,36 +16,31 @@ int fclose(register FILE *stream) int rv = 0; __STDIO_AUTO_THREADLOCK_VAR; -#ifdef __UCLIBC_MJN3_ONLY__ -#warning REMINDER: dead code... but may want to simply check and not remove +#ifdef __STDIO_HAS_OPENLIST +#if !defined(__UCLIBC_HAS_THREADS__) || !defined(__STDIO_BUFFERS) + /* First, remove the file from the open file list. */ + { + FILE *ptr; + + __STDIO_THREADLOCK_OPENLIST_DEL; + __STDIO_THREADLOCK_OPENLIST_ADD; + ptr = _stdio_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_ADD; + __STDIO_THREADUNLOCK_OPENLIST_DEL; + } +#endif #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); |