fclose.c 2.0 KB

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