fclose.c 2.1 KB

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