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 /* Both ftell() and fseek() (for SEEK_CUR) need to correct the stream's 11 * position to take into account buffered data and ungotten chars. 12 * 13 * If successful, store corrected position in *pos and return >= 0. 14 * Otherwise return < 0. 15 * 16 * If position is unrepresentable, set errno to EOVERFLOW. 17 */ 18 __stdio_adjust_position(register FILE * __restrict stream,register __offmax_t * pos)19int attribute_hidden __stdio_adjust_position(register FILE * __restrict stream, 20 register __offmax_t *pos) 21 { 22 __offmax_t oldpos; 23 int corr; 24 25 if ((corr = stream->__modeflags & __MASK_READING) != 0) { 26 --corr; /* Correct for ungots. Assume narrow, and fix below. */ 27 } 28 29 #ifdef __UCLIBC_HAS_WCHAR__ 30 if (corr && __STDIO_STREAM_IS_WIDE(stream)) { 31 /* A wide stream and we have at least one ungotten wchar. 32 * If it is a user ungot, we need to fail since position 33 * is unspecified as per C99. */ 34 if ((corr > 1) || stream->__ungot[1]) { /* User ungetwc, */ 35 return -1; /* so position is undefined. */ 36 } 37 corr -= (1 + stream->__ungot_width[1]); 38 if (stream->__state.__mask > 0) { /* Incomplete (bad?) mb char. */ 39 corr -= stream->__ungot_width[0]; 40 } 41 } 42 #endif 43 44 #ifdef __STDIO_BUFFERS 45 corr += (((__STDIO_STREAM_IS_WRITING(stream)) 46 ? stream->__bufstart : stream->__bufread) 47 - stream->__bufpos); 48 #endif 49 50 oldpos = *pos; 51 52 /* Range checking cases: 53 * (pos - corr > pos) && (corr > 0) : underflow? return -corr < 0 54 * (pos - corr > pos) && (corr < 0) : ok .. return -corr > 0 55 * (pos - corr <= pos) && (corr >= 0) : ok .. return corr > 0 56 * (pos - corr <= pos) && (corr < 0) : overflow .. return corr < 0 57 */ 58 59 if ((*pos -= corr) > oldpos) { 60 corr = -corr; 61 } 62 63 if (corr < 0) { 64 __set_errno(EOVERFLOW); 65 } 66 67 return corr; 68 } 69