freopen.c 1.8 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061
  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. libc_hidden_proto(fclose)
  9. #ifndef __DO_LARGEFILE
  10. # define FILEDES_ARG (-1)
  11. #endif
  12. FILE *freopen(const char * __restrict filename, const char * __restrict mode,
  13. register FILE * __restrict stream)
  14. {
  15. /*
  16. * ANSI/ISO allow (implementation-defined) change of mode for an
  17. * existing file if filename is NULL. It doesn't look like Linux
  18. * supports this, so we don't here.
  19. *
  20. * NOTE: Whether or not the stream is free'd on failure is unclear
  21. * w.r.t. ANSI/ISO. This implementation chooses to NOT free
  22. * the stream and associated buffer if they were dynamically
  23. * allocated.
  24. * NOTE: Previous versions of uClibc did free dynamic storage.
  25. *
  26. * TODO: Apparently linux allows setting append mode. Implement?
  27. */
  28. unsigned short dynmode;
  29. register FILE *fp;
  30. __STDIO_AUTO_THREADLOCK_VAR;
  31. __STDIO_AUTO_THREADLOCK(stream);
  32. __STDIO_STREAM_VALIDATE(stream);
  33. /* First, flush and close, but don't deallocate, the stream. */
  34. /* This also removes the stream for the open file list. */
  35. dynmode = (stream->__modeflags & (__FLAG_FREEBUF|__FLAG_FREEFILE));
  36. stream->__modeflags &= ~(__FLAG_FREEBUF|__FLAG_FREEFILE);
  37. /* Only call fclose on the stream if it is not already closed. */
  38. if ((stream->__modeflags & (__FLAG_READONLY|__FLAG_WRITEONLY))
  39. != (__FLAG_READONLY|__FLAG_WRITEONLY)
  40. ) {
  41. fclose(stream); /* Failures are ignored. */
  42. }
  43. fp = _stdio_fopen(((intptr_t) filename), mode, stream, FILEDES_ARG);
  44. /* Reset the allocation flags. */
  45. stream->__modeflags |= dynmode;
  46. __STDIO_AUTO_THREADUNLOCK(stream);
  47. return fp;
  48. }