fclose.c 2.0 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788
  1. /* Copyright (C) 2004 Manuel Novoa III <mjn3@codepoet.org>
  2. *
  3. * GNU Library General Public License (LGPL) version 2 or later.
  4. *
  5. * Dedicated to Toni. See uClibc/DEDICATION.mjn3 for details.
  6. */
  7. #include "_stdio.h"
  8. #undef fclose
  9. int attribute_hidden __fclose(register FILE *stream)
  10. {
  11. int rv = 0;
  12. __STDIO_AUTO_THREADLOCK_VAR;
  13. /* First, remove the file from the open file list. */
  14. #ifdef __STDIO_HAS_OPENLIST
  15. {
  16. register FILE *ptr;
  17. __STDIO_THREADLOCK_OPENLIST;
  18. if ((ptr = _stdio_openlist) == stream) {
  19. _stdio_openlist = stream->__nextopen;
  20. } else {
  21. while (ptr) {
  22. if (ptr->__nextopen == stream) {
  23. ptr->__nextopen = stream->__nextopen;
  24. break;
  25. }
  26. ptr = ptr->__nextopen;
  27. }
  28. }
  29. __STDIO_THREADUNLOCK_OPENLIST;
  30. if (!ptr) { /* Did not find stream in the open file list! */
  31. return EOF;
  32. }
  33. }
  34. #endif
  35. __STDIO_AUTO_THREADLOCK(stream);
  36. __STDIO_STREAM_VALIDATE(stream);
  37. #ifdef __STDIO_BUFFERS
  38. /* Write any pending buffered chars. */
  39. if (__STDIO_STREAM_IS_WRITING(stream)) {
  40. rv = __fflush_unlocked(stream);
  41. }
  42. #endif
  43. if (__CLOSE(stream) < 0) { /* Must close even if fflush failed. */
  44. rv = EOF;
  45. }
  46. stream->__filedes = -1;
  47. /* We need a way for freopen to know that a file has been closed.
  48. * Since a file can't be both readonly and writeonly, that makes
  49. * an effective signal. It also has the benefit of disabling
  50. * transitions to either reading or writing. */
  51. stream->__modeflags &= (__FLAG_FREEBUF|__FLAG_FREEFILE);
  52. stream->__modeflags |= (__FLAG_READONLY|__FLAG_WRITEONLY);
  53. #ifndef NDEBUG
  54. __STDIO_STREAM_RESET_GCS(stream);
  55. /* Reinitialize everything (including putc since fflush could fail). */
  56. __STDIO_STREAM_DISABLE_GETC(stream);
  57. __STDIO_STREAM_DISABLE_PUTC(stream);
  58. __STDIO_STREAM_INIT_BUFREAD_BUFPOS(stream);
  59. # ifdef __UCLIBC_HAS_WCHAR__
  60. stream->__ungot_width[0] = 0;
  61. # endif
  62. # ifdef __STDIO_MBSTATE
  63. __INIT_MBSTATE(&(stream->__state));
  64. # endif
  65. #endif
  66. __STDIO_AUTO_THREADUNLOCK(stream);
  67. __STDIO_STREAM_FREE_BUFFER(stream);
  68. __STDIO_STREAM_FREE_FILE(stream);
  69. return rv;
  70. }
  71. strong_alias(__fclose,fclose)