int _IO_default_pbackfail (_IO_FILE *fp, int c) { if (fp->_IO_read_ptr > fp->_IO_read_base && !_IO_in_backup (fp) && (unsigned char) fp->_IO_read_ptr[-1] == c) --fp->_IO_read_ptr; else { /* Need to handle a filebuf in write mode (switch to read mode). FIXME!*/ if (!_IO_in_backup (fp)) { /* We need to keep the invariant that the main get area logically follows the backup area. */ if (fp->_IO_read_ptr > fp->_IO_read_base && _IO_have_backup (fp)) { if (save_for_backup (fp, fp->_IO_read_ptr)) return EOF; } else if (!_IO_have_backup (fp)) { /* No backup buffer: allocate one. */ /* Use nshort buffer, if unused? (probably not) FIXME */ int backup_size = 128; char *bbuf = (char *) malloc (backup_size); if (bbuf == NULL) return EOF; fp->_IO_save_base = bbuf; fp->_IO_save_end = fp->_IO_save_base + backup_size; fp->_IO_backup_base = fp->_IO_save_end; } fp->_IO_read_base = fp->_IO_read_ptr; _IO_switch_to_backup_area (fp); } else if (fp->_IO_read_ptr <= fp->_IO_read_base) { /* Increase size of existing backup buffer. */ _IO_size_t new_size; _IO_size_t old_size = fp->_IO_read_end - fp->_IO_read_base; char *new_buf; new_size = 2 * old_size; new_buf = (char *) malloc (new_size); if (new_buf == NULL) return EOF; memcpy (new_buf + (new_size - old_size), fp->_IO_read_base, old_size); free (fp->_IO_read_base); _IO_setg (fp, new_buf, new_buf + (new_size - old_size), new_buf + new_size); fp->_IO_backup_base = fp->_IO_read_ptr; } *--fp->_IO_read_ptr = c; } return (unsigned char) c; }
wint_t __wunderflow (FILE *fp) { if (fp->_mode < 0 || (fp->_mode == 0 && _IO_fwide (fp, 1) != 1)) return WEOF; if (fp->_mode == 0) _IO_fwide (fp, 1); if (_IO_in_put_mode (fp)) if (_IO_switch_to_wget_mode (fp) == EOF) return WEOF; if (fp->_wide_data->_IO_read_ptr < fp->_wide_data->_IO_read_end) return *fp->_wide_data->_IO_read_ptr; if (_IO_in_backup (fp)) { _IO_switch_to_main_wget_area (fp); if (fp->_wide_data->_IO_read_ptr < fp->_wide_data->_IO_read_end) return *fp->_wide_data->_IO_read_ptr; } if (_IO_have_markers (fp)) { if (save_for_wbackup (fp, fp->_wide_data->_IO_read_end)) return WEOF; } else if (_IO_have_backup (fp)) _IO_free_wbackup_area (fp); return _IO_UNDERFLOW (fp); }
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; }
void _IO_unsave_wmarkers (FILE *fp) { struct _IO_marker *mark = fp->_markers; if (mark) { fp->_markers = 0; } if (_IO_have_backup (fp)) _IO_free_wbackup_area (fp); }
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); }