_trans2w.c 2.6 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889
  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. /* Function to handle transition to writing.
  9. * Initialize or verify the stream's orientation (even if readonly).
  10. * Check that the stream is writable.
  11. * If currently reading, check that we can transition to writing.
  12. * C99 requires that the stream is at EOF, but attempting to
  13. * auto-transition via fseek() is a configurable option.
  14. * Returns 0 on success and EOF otherwise.
  15. *
  16. * Notes:
  17. * There are two function signatures, depending on wchar support,
  18. * since with no wchar support the orientation is narrow by default.
  19. */
  20. #ifdef __UCLIBC_HAS_WCHAR__
  21. int __stdio_trans2w_o(FILE * __restrict stream, int oflag)
  22. #else
  23. int __stdio_trans2w(FILE * __restrict stream)
  24. #endif
  25. {
  26. __STDIO_STREAM_VALIDATE(stream);
  27. assert(!__STDIO_STREAM_IS_WRITING(stream));
  28. #ifdef __UCLIBC_HAS_WCHAR__
  29. if (!(stream->__modeflags & oflag)) {
  30. if (stream->__modeflags & (__FLAG_NARROW|__FLAG_WIDE)) {
  31. __UNDEFINED_OR_NONPORTABLE;
  32. goto DO_EBADF;
  33. }
  34. stream->__modeflags |= oflag;
  35. }
  36. #endif
  37. if (stream->__modeflags & __FLAG_READONLY) {
  38. DO_EBADF:
  39. __set_errno(EBADF);
  40. ERROR:
  41. __STDIO_STREAM_SET_ERROR(stream);
  42. __STDIO_STREAM_VALIDATE(stream);
  43. return EOF;
  44. }
  45. if (__STDIO_STREAM_IS_READING(stream)) {
  46. if (!__FEOF_UNLOCKED(stream)) {
  47. #ifdef __UCLIBC_HAS_STDIO_AUTO_RW_TRANSITION__
  48. /* Need to seek to correct position if we have buffered
  49. * read data or ungots. If appending, we might as well
  50. * seek to the end.
  51. *
  52. * NOTE: If the OS does not handle append files correctly,
  53. * this is insufficient since we would need to seek to
  54. * the end even if not reading.*/
  55. if (((__STDIO_STREAM_BUFFER_RAVAIL(stream))
  56. || (stream->__modeflags & __FLAG_UNGOT))
  57. && fseek(stream, 0L,
  58. ((stream->__modeflags & __FLAG_APPEND)
  59. ? SEEK_END : SEEK_CUR))
  60. ) {
  61. /* fseek() only sets error indicator on read/write error. */
  62. goto ERROR;
  63. }
  64. #else
  65. /* C99 requires either at EOF or currently not reading. */
  66. __UNDEFINED_OR_NONPORTABLE;
  67. goto DO_EBADF;
  68. #endif
  69. }
  70. __STDIO_STREAM_CLEAR_READING_AND_UNGOTS(stream);
  71. __STDIO_STREAM_DISABLE_GETC(stream);
  72. /* Reaching EOF does not reset buffer pointers... */
  73. __STDIO_STREAM_INIT_BUFREAD_BUFPOS(stream);
  74. }
  75. __STDIO_STREAM_SET_WRITING(stream);
  76. if (__STDIO_STREAM_IS_NARROW_FBF(stream)) {
  77. __STDIO_STREAM_ENABLE_PUTC(stream);
  78. }
  79. __STDIO_STREAM_VALIDATE(stream);
  80. return 0;
  81. }