wint_t ungetwc(wint_t c, register FILE *stream) { __STDIO_AUTO_THREADLOCK_VAR; __STDIO_AUTO_THREADLOCK(stream); __STDIO_STREAM_VALIDATE(stream); /* debugging only */ /* Note: Even if c == WEOF, we need to initialize/verify the * stream's orientation and ensure the stream is in reading * mode (if readable and properly oriented). */ if ((!__STDIO_STREAM_IS_WIDE_READING(stream) && __STDIO_STREAM_TRANS_TO_READ(stream, __FLAG_WIDE)) || ((stream->__modeflags & __FLAG_UNGOT) && ((stream->__modeflags & 1) || stream->__ungot[1])) || (c == WEOF) ) { c = WEOF; } else { /* In the wide case, getc macros should already be disabled. */ /* __STDIO_STREAM_DISABLE_GETC(stream); */ /* Flag this as a user ungot, as scanf does the necessary fixup. */ stream->__ungot[1] = 1; stream->__ungot[(++stream->__modeflags) & 1] = c; /* Note: ungot_width is handled by fgetwc. */ __STDIO_STREAM_CLEAR_EOF(stream); /* Must clear end-of-file flag. */ } __STDIO_STREAM_VALIDATE(stream); __STDIO_AUTO_THREADUNLOCK(stream); return c; }
OFFSET_TYPE_T FTELL(register FILE *stream) { #if defined(__UCLIBC_HAS_LFS__) && !defined(__DO_LARGEFILE) __offmax_t pos = __ftello64(stream); if ((sizeof(long) >= sizeof(__offmax_t)) || (((long) pos) == pos)) { return ((long) pos); } else { __set_errno(EOVERFLOW); return -1; } #else __offmax_t pos = 0; __STDIO_AUTO_THREADLOCK_VAR; __STDIO_AUTO_THREADLOCK(stream); __STDIO_STREAM_VALIDATE(stream); if ((__SEEK(stream, &pos, SEEK_CUR) < 0) || (__stdio_adjust_position(stream, &pos) < 0)) { pos = -1; } __STDIO_AUTO_THREADUNLOCK(stream); return pos; #endif }
int FSEEK(register FILE *stream, OFFSET_TYPE offset, int whence) { #if defined(__UCLIBC_HAS_LFS__) && !defined(__DO_LARGEFILE) return fseeko64(stream, offset, whence); #else __offmax_t pos = offset; int retval = -1; __STDIO_AUTO_THREADLOCK_VAR; if (((unsigned int) whence) > 2) { __set_errno(EINVAL); } else { __STDIO_AUTO_THREADLOCK(stream); __STDIO_STREAM_VALIDATE(stream); if ((!__STDIO_STREAM_IS_WRITING(stream) || !__STDIO_COMMIT_WRITE_BUFFER(stream)) && ((whence != SEEK_CUR) || (__stdio_adjust_position(stream, &pos) >= 0)) && (__SEEK(stream, &pos, whence) >= 0) ) { /* Clear reading/writing modes, EOF, and ungots. */ stream->__modeflags &= ~(__MASK_READING|__FLAG_WRITING|__FLAG_EOF); /* Make sure all pointers are reset. */ __STDIO_STREAM_INIT_BUFREAD_BUFPOS(stream); __STDIO_STREAM_DISABLE_GETC(stream); __STDIO_STREAM_DISABLE_PUTC(stream); /* We reinitialize the mbstate object. Doing so is * implementation defined behavior. */ #ifdef __STDIO_MBSTATE __INIT_MBSTATE(&(stream->__state)); #endif #ifdef __UCLIBC_HAS_WCHAR__ stream->__ungot_width[0] = 0; #endif retval = 0; } __STDIO_STREAM_VALIDATE(stream); __STDIO_AUTO_THREADUNLOCK(stream); } return retval; #endif }
/* libc_hidden_proto(rewind) */ void rewind(register FILE *stream) { __STDIO_AUTO_THREADLOCK_VAR; __STDIO_AUTO_THREADLOCK(stream); __STDIO_STREAM_CLEAR_ERROR(stream); /* Clear the error indicator */ fseek(stream, 0L, SEEK_SET); /* first since fseek could set it. */ __STDIO_AUTO_THREADUNLOCK(stream); }
void clearerr(register FILE *stream) { __STDIO_AUTO_THREADLOCK_VAR; __STDIO_AUTO_THREADLOCK(stream); __STDIO_STREAM_VALIDATE(stream); __CLEARERR_UNLOCKED(stream); __STDIO_AUTO_THREADUNLOCK(stream); }
wint_t fgetwc(register FILE *stream) { wint_t retval; __STDIO_AUTO_THREADLOCK_VAR; __STDIO_AUTO_THREADLOCK(stream); retval = fgetwc_unlocked(stream); __STDIO_AUTO_THREADUNLOCK(stream); return retval; }
int ungetc(int c, register FILE *stream) { __STDIO_AUTO_THREADLOCK_VAR; __STDIO_AUTO_THREADLOCK(stream); __STDIO_STREAM_VALIDATE(stream); #ifdef __UCLIBC_MJN3_ONLY__ #warning CONSIDER: Make fast ungetc an option? #endif #ifdef __UCLIBC_HAS_STDIO_GETC_MACRO__ /* If buffered narrow reading with no ungot slots filled, and if not * ungetting a different char than the one last read from the buffer, * we can simply decrement the position and not worry about disabling * the getc macros. This will cut down on overhead in applications * that use getc/ungetc extensively (like gcc). */ /* NOTE: If we can use getc, then we are buffered narrow reading with * no ungot slots filled. */ if (__STDIO_STREAM_CAN_USE_BUFFER_GET(stream) && (c != EOF) && (stream->__bufpos > stream->__bufstart) && (stream->__bufpos[-1] == ((unsigned char)c)) ) { --stream->__bufpos; __STDIO_STREAM_CLEAR_EOF(stream); /* Must clear end-of-file flag. */ } else #endif /* Note: Even if c == EOF, we need to initialize/verify the * stream's orientation and ensure the stream is in reading * mode (if readable and properly oriented). */ if ((!__STDIO_STREAM_IS_NARROW_READING(stream) && __STDIO_STREAM_TRANS_TO_READ(stream, __FLAG_NARROW)) || ((stream->__modeflags & __FLAG_UNGOT) && ((stream->__modeflags & 1) || stream->__ungot[1])) ) { c = EOF; } else if (c != EOF) { __STDIO_STREAM_DISABLE_GETC(stream); /* Flag this as a user ungot, as scanf does the necessary fixup. */ stream->__ungot[1] = 1; stream->__ungot[(++stream->__modeflags) & 1] = c; __STDIO_STREAM_CLEAR_EOF(stream); /* Must clear end-of-file flag. */ } __STDIO_STREAM_VALIDATE(stream); __STDIO_AUTO_THREADUNLOCK(stream); return c; }
int fcloseall (void) { #ifdef __STDIO_HAS_OPENLIST int retval = 0; FILE *f; __STDIO_OPENLIST_INC_USE; #ifdef __UCLIBC_MJN3_ONLY__ #warning REMINDER: should probably have a get_head() operation #endif __STDIO_THREADLOCK_OPENLIST_ADD; f = _stdio_openlist; __STDIO_THREADUNLOCK_OPENLIST_ADD; while (f) { #ifdef __UCLIBC_MJN3_ONLY__ #warning REMINDER: should probably have a get_next() operation #endif FILE *n = f->__nextopen; __STDIO_AUTO_THREADLOCK_VAR; __STDIO_AUTO_THREADLOCK(f); /* Only call fclose on the stream if it is not already closed. */ if ((f->__modeflags & (__FLAG_READONLY|__FLAG_WRITEONLY)) != (__FLAG_READONLY|__FLAG_WRITEONLY) ) { if (fclose(f)) { retval = EOF; } } __STDIO_AUTO_THREADUNLOCK(f); f = n; } __STDIO_OPENLIST_DEC_USE; return retval; #else #warning Always fails in this configuration because no open file list. return EOF; #endif }
int fwide(register FILE *stream, int mode) { __STDIO_AUTO_THREADLOCK_VAR; __STDIO_AUTO_THREADLOCK(stream); __STDIO_STREAM_VALIDATE(stream); if (mode && !(stream->__modeflags & (__FLAG_WIDE|__FLAG_NARROW))) { stream->__modeflags |= ((mode > 0) ? __FLAG_WIDE : __FLAG_NARROW); } mode = (stream->__modeflags & __FLAG_WIDE) - (stream->__modeflags & __FLAG_NARROW); assert((stream->__modeflags & (__FLAG_WIDE|__FLAG_NARROW)) != (__FLAG_WIDE|__FLAG_NARROW)); __STDIO_AUTO_THREADUNLOCK(stream); return mode; }
int fflush(register FILE *stream) { int retval; __STDIO_AUTO_THREADLOCK_VAR; if (stream #ifdef __STDIO_HAS_OPENLIST && (stream != (FILE *) &_stdio_openlist) #endif ) { __STDIO_AUTO_THREADLOCK(stream); retval = fflush_unlocked(stream); __STDIO_AUTO_THREADUNLOCK(stream); } else { retval = fflush_unlocked(stream); } return retval; }
char *gets(char *s) { register char *p = s; int c; __STDIO_AUTO_THREADLOCK_VAR; __STDIO_AUTO_THREADLOCK(stdin); /* Note: don't worry about performance here... this shouldn't be used! * Therefore, force actual function call. */ while (((c = getchar_unlocked()) != EOF) && ((*p = c) != '\n')) { ++p; } if ((c == EOF) || (s == p)) { s = NULL; } else { *p = 0; } __STDIO_AUTO_THREADUNLOCK(stdin); return s; }
int fclose(register FILE *stream) { int rv = 0; __STDIO_AUTO_THREADLOCK_VAR; #ifdef __STDIO_HAS_OPENLIST #if !defined(__UCLIBC_HAS_THREADS__) || !defined(__STDIO_BUFFERS) /* First, remove the file from the open file list. */ { FILE *ptr; __STDIO_THREADLOCK_OPENLIST_DEL; __STDIO_THREADLOCK_OPENLIST_ADD; ptr = _stdio_openlist; if ((ptr = _stdio_openlist) == stream) { _stdio_openlist = stream->__nextopen; } else { while (ptr) { if (ptr->__nextopen == stream) { ptr->__nextopen = stream->__nextopen; break; } ptr = ptr->__nextopen; } } __STDIO_THREADUNLOCK_OPENLIST_ADD; __STDIO_THREADUNLOCK_OPENLIST_DEL; } #endif #endif __STDIO_AUTO_THREADLOCK(stream); __STDIO_STREAM_VALIDATE(stream); #ifdef __STDIO_BUFFERS /* Write any pending buffered chars. */ if (__STDIO_STREAM_IS_WRITING(stream)) { rv = fflush_unlocked(stream); } #endif if (__CLOSE(stream) < 0) { /* Must close even if fflush failed. */ rv = EOF; } stream->__filedes = -1; /* We need a way for freopen to know that a file has been closed. * Since a file can't be both readonly and writeonly, that makes * an effective signal. It also has the benefit of disabling * transitions to either reading or writing. */ #if defined(__UCLIBC_HAS_THREADS__) && defined(__STDIO_BUFFERS) /* Before we mark the file as closed, make sure we increment the openlist use count * so it isn't freed under us while still cleaning up. */ __STDIO_OPENLIST_INC_USE; #endif stream->__modeflags &= (__FLAG_FREEBUF|__FLAG_FREEFILE); stream->__modeflags |= (__FLAG_READONLY|__FLAG_WRITEONLY); #ifndef NDEBUG __STDIO_STREAM_RESET_GCS(stream); /* Reinitialize everything (including putc since fflush could fail). */ __STDIO_STREAM_DISABLE_GETC(stream); __STDIO_STREAM_DISABLE_PUTC(stream); __STDIO_STREAM_INIT_BUFREAD_BUFPOS(stream); # ifdef __UCLIBC_HAS_WCHAR__ stream->__ungot_width[0] = 0; # endif # ifdef __STDIO_MBSTATE __INIT_MBSTATE(&(stream->__state)); # endif #endif __STDIO_AUTO_THREADUNLOCK(stream); __STDIO_STREAM_FREE_BUFFER(stream); #ifdef __UCLIBC_MJN3_ONLY__ #warning REMINDER: inefficient - locks and unlocks twice and walks whole list #endif #if defined(__UCLIBC_HAS_THREADS__) && defined(__STDIO_BUFFERS) /* inefficient - locks/unlocks twice and walks whole list */ __STDIO_OPENLIST_INC_DEL_CNT; __STDIO_OPENLIST_DEC_USE; /* This with free the file if necessary. */ #else __STDIO_STREAM_FREE_FILE(stream); #endif return rv; }