_IO_off64_t _IO_wstr_seekoff (_IO_FILE *fp, _IO_off64_t offset, int dir, int mode) { _IO_off64_t new_pos; if (mode == 0 && (fp->_flags & _IO_TIED_PUT_GET)) mode = (fp->_flags & _IO_CURRENTLY_PUTTING ? _IOS_OUTPUT : _IOS_INPUT); bool was_writing = (fp->_wide_data->_IO_write_ptr > fp->_wide_data->_IO_write_base || _IO_in_put_mode (fp)); if (was_writing) _IO_wstr_switch_to_get_mode (fp); if (mode == 0) { new_pos = (fp->_wide_data->_IO_write_ptr - fp->_wide_data->_IO_write_base); } else { _IO_ssize_t cur_size = _IO_wstr_count (fp); new_pos = EOF; /* Move the get pointer, if requested. */ if (mode & _IOS_INPUT) { _IO_ssize_t base; switch (dir) { case _IO_seek_set: base = 0; break; case _IO_seek_cur: base = (fp->_wide_data->_IO_read_ptr - fp->_wide_data->_IO_read_base); break; default: /* case _IO_seek_end: */ base = cur_size; break; } _IO_ssize_t maxval = SSIZE_MAX/sizeof (wchar_t) - base; if (offset < -base || offset > maxval) { __set_errno (EINVAL); return EOF; } base += offset; if (base > cur_size && enlarge_userbuf (fp, base, 1) != 0) return EOF; fp->_wide_data->_IO_read_ptr = (fp->_wide_data->_IO_read_base + base); fp->_wide_data->_IO_read_end = (fp->_wide_data->_IO_read_base + cur_size); new_pos = offset; } /* Move the put pointer, if requested. */ if (mode & _IOS_OUTPUT) { _IO_ssize_t base; switch (dir) { case _IO_seek_set: base = 0; break; case _IO_seek_cur: base = (fp->_wide_data->_IO_write_ptr - fp->_wide_data->_IO_write_base); break; default: /* case _IO_seek_end: */ base = cur_size; break; } _IO_ssize_t maxval = SSIZE_MAX/sizeof (wchar_t) - base; if (offset < -base || offset > maxval) { __set_errno (EINVAL); return EOF; } base += offset; if (base > cur_size && enlarge_userbuf (fp, base, 0) != 0) return EOF; fp->_wide_data->_IO_write_ptr = (fp->_wide_data->_IO_write_base + base); new_pos = base; } } return new_pos; }
_IO_off64_t _IO_str_seekoff (_IO_FILE *fp, _IO_off64_t offset, int dir, int mode) { _IO_off64_t new_pos; if (mode == 0 && (fp->_flags & _IO_TIED_PUT_GET)) mode = (fp->_flags & _IO_CURRENTLY_PUTTING ? _IOS_OUTPUT : _IOS_INPUT); if (mode == 0) { /* Don't move any pointers. But there is no clear indication what mode FP is in. Let's guess. */ if (fp->_IO_file_flags & _IO_NO_WRITES) new_pos = fp->_IO_read_ptr - fp->_IO_read_base; else new_pos = fp->_IO_write_ptr - fp->_IO_write_base; } else { _IO_ssize_t cur_size = _IO_str_count(fp); new_pos = EOF; /* Move the get pointer, if requested. */ if (mode & _IOS_INPUT) { switch (dir) { case _IO_seek_end: offset += cur_size; break; case _IO_seek_cur: offset += fp->_IO_read_ptr - fp->_IO_read_base; break; default: /* case _IO_seek_set: */ break; } if (offset < 0) return EOF; if ((_IO_ssize_t) offset > cur_size && enlarge_userbuf (fp, offset, 1) != 0) return EOF; fp->_IO_read_ptr = fp->_IO_read_base + offset; fp->_IO_read_end = fp->_IO_read_base + cur_size; new_pos = offset; } /* Move the put pointer, if requested. */ if (mode & _IOS_OUTPUT) { switch (dir) { case _IO_seek_end: offset += cur_size; break; case _IO_seek_cur: offset += fp->_IO_write_ptr - fp->_IO_write_base; break; default: /* case _IO_seek_set: */ break; } if (offset < 0) return EOF; if ((_IO_ssize_t) offset > cur_size && enlarge_userbuf (fp, offset, 0) != 0) return EOF; fp->_IO_write_ptr = fp->_IO_write_base + offset; new_pos = offset; } } return new_pos; }