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 8 #include "_stdio.h" 9 10 /* Function to handle transition to reading. 11 * Initialize or verify the stream's orientation (even if writeonly). 12 * Check that the stream is readable. 13 * If currently reading, check that we can transition to writing. 14 * C99 requires that we not be reading, but attempting to 15 * auto-transition by commiting the write buffer is a configurable 16 * option. 17 * Returns 0 on success and EOF otherwise. 18 * 19 * Notes: 20 * There are two function signatures, depending on wchar support, 21 * since with no wchar support the orientation is narrow by default. 22 */ 23 24 #ifdef __UCLIBC_HAS_WCHAR__ __stdio_trans2r_o(FILE * __restrict stream,int oflag)25int attribute_hidden __stdio_trans2r_o(FILE * __restrict stream, int oflag) 26 #else 27 int attribute_hidden __stdio_trans2r(FILE * __restrict stream) 28 #endif 29 { 30 __STDIO_STREAM_VALIDATE(stream); 31 assert(!__STDIO_STREAM_IS_READING(stream)); 32 33 #ifdef __UCLIBC_HAS_WCHAR__ 34 if (!(stream->__modeflags & oflag)) { 35 if (stream->__modeflags & (__FLAG_NARROW|__FLAG_WIDE)) { 36 __UNDEFINED_OR_NONPORTABLE; 37 goto DO_EBADF; 38 } 39 stream->__modeflags |= oflag; 40 } 41 #endif 42 43 if (stream->__modeflags & __FLAG_WRITEONLY) { 44 #if defined(__UCLIBC_HAS_WCHAR__) || !defined(__UCLIBC_HAS_STDIO_AUTO_RW_TRANSITION__) 45 DO_EBADF: 46 #endif 47 __set_errno(EBADF); 48 #ifdef __UCLIBC_HAS_STDIO_AUTO_RW_TRANSITION__ 49 ERROR: 50 #endif 51 __STDIO_STREAM_SET_ERROR(stream); 52 __STDIO_STREAM_VALIDATE(stream); 53 return EOF; 54 } 55 56 if (__STDIO_STREAM_IS_WRITING(stream)) { 57 #ifdef __UCLIBC_HAS_STDIO_AUTO_RW_TRANSITION__ 58 if (__STDIO_COMMIT_WRITE_BUFFER(stream)) { /* commit failed! */ 59 goto ERROR; 60 } 61 assert(!__STDIO_STREAM_BUFFER_WUSED(stream)); 62 63 __STDIO_STREAM_DISABLE_PUTC(stream); 64 __STDIO_STREAM_CLEAR_WRITING(stream); 65 #else 66 /* C99: Output shall not be directly followed by input without an 67 intervening call to the fflush function or to a file positioning 68 function (fseek, fsetpos, or rewind). */ 69 __UNDEFINED_OR_NONPORTABLE; 70 goto DO_EBADF; 71 #endif 72 } 73 74 __STDIO_STREAM_SET_READING(stream); 75 /* getc macro is enabled when data is read into buffer. */ 76 77 __STDIO_STREAM_VALIDATE(stream); 78 return 0; 79 } 80