int __uflow (_IO_FILE *fp) { #if defined _LIBC || defined _GLIBCPP_USE_WCHAR_T if (_IO_vtable_offset (fp) == 0 && _IO_fwide (fp, -1) != -1) return EOF; #endif if (fp->_mode == 0) _IO_fwide (fp, -1); if (_IO_in_put_mode (fp)) if (_IO_switch_to_get_mode (fp) == EOF) return EOF; if (fp->_IO_read_ptr < fp->_IO_read_end) return *(unsigned char *) fp->_IO_read_ptr++; if (_IO_in_backup (fp)) { _IO_switch_to_main_get_area (fp); if (fp->_IO_read_ptr < fp->_IO_read_end) return *(unsigned char *) fp->_IO_read_ptr++; } if (_IO_have_markers (fp)) { if (save_for_backup (fp, fp->_IO_read_end)) return EOF; } else if (_IO_have_backup (fp)) _IO_free_backup_area (fp); return _IO_UFLOW (fp); }
void _IO_unsave_markers (_IO_FILE *fp) { struct _IO_marker *mark = fp->_markers; if (mark) { #ifdef TODO streampos offset = seekoff (0, ios::cur, ios::in); if (offset != EOF) { offset += eGptr () - Gbase (); for ( ; mark != NULL; mark = mark->_next) mark->set_streampos (mark->_pos + offset); } else { for ( ; mark != NULL; mark = mark->_next) mark->set_streampos (EOF); } #endif fp->_markers = 0; } if (_IO_have_backup (fp)) _IO_free_backup_area (fp); }
int attribute_compat_text_section _IO_old_fclose (_IO_FILE *fp) { int status; CHECK_FILE(fp, EOF); /* We desperately try to help programs which are using streams in a strange way and mix old and new functions. Detect new streams here. */ if (fp->_vtable_offset == 0) return _IO_new_fclose (fp); /* First unlink the stream. */ if (fp->_IO_file_flags & _IO_IS_FILEBUF) _IO_un_link ((struct _IO_FILE_plus *) fp); _IO_acquire_lock (fp); if (fp->_IO_file_flags & _IO_IS_FILEBUF) status = _IO_old_file_close_it (fp); else status = fp->_flags & _IO_ERR_SEEN ? -1 : 0; _IO_release_lock (fp); _IO_FINISH (fp); if (_IO_have_backup (fp)) _IO_free_backup_area (fp); if (fp != _IO_stdin && fp != _IO_stdout && fp != _IO_stderr) { fp->_IO_file_flags = 0; free(fp); } return status; }
int _IO_new_file_overflow (_IO_FILE *f, int ch) { if (f->_flags & _IO_NO_WRITES) /* SET ERROR */ { f->_flags |= _IO_ERR_SEEN; __set_errno (EBADF); return EOF; } /* If currently reading or no buffer allocated. */ if ((f->_flags & _IO_CURRENTLY_PUTTING) == 0 || f->_IO_write_base == NULL) { /* Allocate a buffer if needed. */ if (f->_IO_write_base == NULL) { _IO_doallocbuf (f); _IO_setg (f, f->_IO_buf_base, f->_IO_buf_base, f->_IO_buf_base); } /* Otherwise must be currently reading. If _IO_read_ptr (and hence also _IO_read_end) is at the buffer end, logically slide the buffer forwards one block (by setting the read pointers to all point at the beginning of the block). This makes room for subsequent output. Otherwise, set the read pointers to _IO_read_end (leaving that alone, so it can continue to correspond to the external position). */ if (__glibc_unlikely (_IO_in_backup (f))) { size_t nbackup = f->_IO_read_end - f->_IO_read_ptr; _IO_free_backup_area (f); f->_IO_read_base -= MIN (nbackup, f->_IO_read_base - f->_IO_buf_base); f->_IO_read_ptr = f->_IO_read_base; } if (f->_IO_read_ptr == f->_IO_buf_end) f->_IO_read_end = f->_IO_read_ptr = f->_IO_buf_base; f->_IO_write_ptr = f->_IO_read_ptr; f->_IO_write_base = f->_IO_write_ptr; f->_IO_write_end = f->_IO_buf_end; f->_IO_read_base = f->_IO_read_ptr = f->_IO_read_end; f->_flags |= _IO_CURRENTLY_PUTTING; if (f->_mode <= 0 && f->_flags & (_IO_LINE_BUF | _IO_UNBUFFERED)) f->_IO_write_end = f->_IO_write_ptr; } if (ch == EOF) return _IO_do_write (f, f->_IO_write_base, f->_IO_write_ptr - f->_IO_write_base); if (f->_IO_write_ptr == f->_IO_buf_end ) /* Buffer is really full */ if (_IO_do_flush (f) == EOF) return EOF; *f->_IO_write_ptr++ = ch; if ((f->_flags & _IO_UNBUFFERED) || ((f->_flags & _IO_LINE_BUF) && ch == '\n')) if (_IO_do_write (f, f->_IO_write_base, f->_IO_write_ptr - f->_IO_write_base) == EOF) return EOF; return (unsigned char) ch; }
int _IO_new_fclose (_IO_FILE *fp) { int status; CHECK_FILE(fp, EOF); #if SHLIB_COMPAT (libc, GLIBC_2_0, GLIBC_2_1) /* We desperately try to help programs which are using streams in a strange way and mix old and new functions. Detect old streams here. */ if (_IO_vtable_offset (fp) != 0) return _IO_old_fclose (fp); #endif /* First unlink the stream. */ if (fp->_IO_file_flags & _IO_IS_FILEBUF) _IO_un_link ((struct _IO_FILE_plus *) fp); _IO_acquire_lock (fp); if (fp->_IO_file_flags & _IO_IS_FILEBUF) status = _IO_file_close_it (fp); else status = fp->_flags & _IO_ERR_SEEN ? -1 : 0; _IO_release_lock (fp); _IO_FINISH (fp); if (fp->_mode > 0) { #if _LIBC /* This stream has a wide orientation. This means we have to free the conversion functions. */ struct _IO_codecvt *cc = fp->_codecvt; __libc_lock_lock (__gconv_lock); __gconv_release_step (cc->__cd_in.__cd.__steps); __gconv_release_step (cc->__cd_out.__cd.__steps); __libc_lock_unlock (__gconv_lock); #endif } else { if (_IO_have_backup (fp)) _IO_free_backup_area (fp); } if (fp != _IO_stdin && fp != _IO_stdout && fp != _IO_stderr) { fp->_IO_file_flags = 0; free(fp); } return status; }
_IO_off64_t _IO_seekpos_unlocked (_IO_FILE *fp, _IO_off64_t pos, int mode) { /* If we have a backup buffer, get rid of it, since the __seekoff callback may not know to do the right thing about it. This may be over-kill, but it'll do for now. TODO */ if (_IO_fwide (fp, 0) <= 0) { if (_IO_have_backup (fp)) _IO_free_backup_area (fp); } else { if (_IO_have_wbackup (fp)) _IO_free_wbackup_area (fp); } return _IO_SEEKOFF (fp, pos, 0, mode); }
void __fpurge (FILE *fp) { if (fp->_mode > 0) { /* Wide-char stream. */ if (_IO_in_backup (fp)) _IO_free_wbackup_area (fp); fp->_wide_data->_IO_read_end = fp->_wide_data->_IO_read_ptr; fp->_wide_data->_IO_write_ptr = fp->_wide_data->_IO_write_base; } else { /* Byte stream. */ if (_IO_in_backup (fp)) _IO_free_backup_area (fp); fp->_IO_read_end = fp->_IO_read_ptr; fp->_IO_write_ptr = fp->_IO_write_base; } }