static wint_t _IO_wstrn_overflow (_IO_FILE *fp, wint_t c) { /* When we come to here this means the user supplied buffer is filled. But since we must return the number of characters which would have been written in total we must provide a buffer for further use. We can do this by writing on and on in the overflow buffer in the _IO_wstrnfile structure. */ _IO_wstrnfile *snf = (_IO_wstrnfile *) fp; if (fp->_wide_data->_IO_buf_base != snf->overflow_buf) { _IO_wsetb (fp, snf->overflow_buf, snf->overflow_buf + (sizeof (snf->overflow_buf) / sizeof (wchar_t)), 0); fp->_wide_data->_IO_write_base = snf->overflow_buf; fp->_wide_data->_IO_read_base = snf->overflow_buf; fp->_wide_data->_IO_read_ptr = snf->overflow_buf; fp->_wide_data->_IO_read_end = (snf->overflow_buf + (sizeof (snf->overflow_buf) / sizeof (wchar_t))); } fp->_wide_data->_IO_write_ptr = snf->overflow_buf; fp->_wide_data->_IO_write_end = snf->overflow_buf; /* Since we are not really interested in storing the characters which do not fit in the buffer we simply ignore it. */ return c; }
void _IO_wstr_init_static (_IO_FILE *fp, wchar_t *ptr, _IO_size_t size, wchar_t *pstart) { wchar_t *end; if (size == 0) end = ptr + __wcslen (ptr); else if ((_IO_size_t) ptr + size * sizeof (wchar_t) > (_IO_size_t) ptr) end = ptr + size; else /* Even for misaligned ptr make sure there is integral number of wide characters. */ end = ptr + (-1 - (_IO_size_t) ptr) / sizeof (wchar_t); _IO_wsetb (fp, ptr, end, 0); fp->_wide_data->_IO_write_base = ptr; fp->_wide_data->_IO_read_base = ptr; fp->_wide_data->_IO_read_ptr = ptr; if (pstart) { fp->_wide_data->_IO_write_ptr = pstart; fp->_wide_data->_IO_write_end = end; fp->_wide_data->_IO_read_end = pstart; } else { fp->_wide_data->_IO_write_ptr = ptr; fp->_wide_data->_IO_write_end = ptr; fp->_wide_data->_IO_read_end = end; } /* A null _allocate_buffer function flags the strfile as being static. */ (((_IO_strfile *) fp)->_s._allocate_buffer) = (_IO_alloc_type)0; }
int _IO_wdefault_doallocate (FILE *fp) { wchar_t *buf; buf = malloc (BUFSIZ); if (__glibc_unlikely (buf == NULL)) return EOF; _IO_wsetb (fp, buf, buf + BUFSIZ, 1); return 1; }
void _IO_wdoallocbuf (FILE *fp) { if (fp->_wide_data->_IO_buf_base) return; if (!(fp->_flags & _IO_UNBUFFERED)) if ((wint_t)_IO_WDOALLOCATE (fp) != WEOF) return; _IO_wsetb (fp, fp->_wide_data->_shortbuf, fp->_wide_data->_shortbuf + 1, 0); }
static void _IO_unbuffer_all (void) { struct _IO_FILE *fp; for (fp = (_IO_FILE *) _IO_list_all; fp; fp = fp->_chain) { if (! (fp->_flags & _IO_UNBUFFERED) /* Iff stream is un-orientated, it wasn't used. */ && fp->_mode != 0) { #ifdef _IO_MTSAFE_IO int cnt; #define MAXTRIES 2 for (cnt = 0; cnt < MAXTRIES; ++cnt) if (fp->_lock == NULL || _IO_lock_trylock (*fp->_lock) == 0) break; else /* Give the other thread time to finish up its use of the stream. */ __sched_yield (); #endif if (! dealloc_buffers && !(fp->_flags & _IO_USER_BUF)) { fp->_flags |= _IO_USER_BUF; fp->_freeres_list = freeres_list; freeres_list = fp; fp->_freeres_buf = fp->_IO_buf_base; } _IO_SETBUF (fp, NULL, 0); if (fp->_mode > 0) _IO_wsetb (fp, NULL, NULL, 0); #ifdef _IO_MTSAFE_IO if (cnt < MAXTRIES && fp->_lock != NULL) _IO_lock_unlock (*fp->_lock); #endif } /* Make sure that never again the wide char functions can be used. */ fp->_mode = -1; } }
int _IO_new_file_close_it (_IO_FILE *fp) { int write_status; if (!_IO_file_is_open (fp)) return EOF; if ((fp->_flags & _IO_NO_WRITES) == 0 && (fp->_flags & _IO_CURRENTLY_PUTTING) != 0) write_status = _IO_do_flush (fp); else write_status = 0; _IO_unsave_markers (fp); int close_status = ((fp->_flags2 & _IO_FLAGS2_NOCLOSE) == 0 ? _IO_SYSCLOSE (fp) : 0); /* Free buffer. */ #if defined _LIBC || defined _GLIBCPP_USE_WCHAR_T if (fp->_mode > 0) { if (_IO_have_wbackup (fp)) _IO_free_wbackup_area (fp); _IO_wsetb (fp, NULL, NULL, 0); _IO_wsetg (fp, NULL, NULL, NULL); _IO_wsetp (fp, NULL, NULL); } #endif _IO_setb (fp, NULL, NULL, 0); _IO_setg (fp, NULL, NULL, NULL); _IO_setp (fp, NULL, NULL); _IO_un_link ((struct _IO_FILE_plus *) fp); fp->_flags = _IO_MAGIC|CLOSED_FILEBUF_FLAGS; fp->_fileno = -1; fp->_offset = _IO_pos_BAD; return close_status ? close_status : write_status; }
_IO_wint_t _IO_wstr_overflow (_IO_FILE *fp, _IO_wint_t c) { int flush_only = c == WEOF; _IO_size_t pos; if (fp->_flags & _IO_NO_WRITES) return flush_only ? 0 : WEOF; if ((fp->_flags & _IO_TIED_PUT_GET) && !(fp->_flags & _IO_CURRENTLY_PUTTING)) { fp->_flags |= _IO_CURRENTLY_PUTTING; fp->_wide_data->_IO_write_ptr = fp->_wide_data->_IO_read_ptr; fp->_wide_data->_IO_read_ptr = fp->_wide_data->_IO_read_end; } pos = fp->_wide_data->_IO_write_ptr - fp->_wide_data->_IO_write_base; if (pos >= (_IO_size_t) (_IO_wblen (fp) + flush_only)) { if (fp->_flags2 & _IO_FLAGS2_USER_WBUF) /* not allowed to enlarge */ return WEOF; else { wchar_t *new_buf; wchar_t *old_buf = fp->_wide_data->_IO_buf_base; size_t old_wblen = _IO_wblen (fp); _IO_size_t new_size = 2 * old_wblen + 100; if (__glibc_unlikely (new_size < old_wblen) || __glibc_unlikely (new_size > SIZE_MAX / sizeof (wchar_t))) return EOF; new_buf = (wchar_t *) (*((_IO_strfile *) fp)->_s._allocate_buffer) (new_size * sizeof (wchar_t)); if (new_buf == NULL) { /* __ferror(fp) = 1; */ return WEOF; } if (old_buf) { __wmemcpy (new_buf, old_buf, old_wblen); (*((_IO_strfile *) fp)->_s._free_buffer) (old_buf); /* Make sure _IO_setb won't try to delete _IO_buf_base. */ fp->_wide_data->_IO_buf_base = NULL; } __wmemset (new_buf + old_wblen, L'\0', new_size - old_wblen); _IO_wsetb (fp, new_buf, new_buf + new_size, 1); fp->_wide_data->_IO_read_base = new_buf + (fp->_wide_data->_IO_read_base - old_buf); fp->_wide_data->_IO_read_ptr = new_buf + (fp->_wide_data->_IO_read_ptr - old_buf); fp->_wide_data->_IO_read_end = new_buf + (fp->_wide_data->_IO_read_end - old_buf); fp->_wide_data->_IO_write_ptr = new_buf + (fp->_wide_data->_IO_write_ptr - old_buf); fp->_wide_data->_IO_write_base = new_buf; fp->_wide_data->_IO_write_end = fp->_wide_data->_IO_buf_end; } } if (!flush_only) *fp->_wide_data->_IO_write_ptr++ = c; if (fp->_wide_data->_IO_write_ptr > fp->_wide_data->_IO_read_end) fp->_wide_data->_IO_read_end = fp->_wide_data->_IO_write_ptr; return c; }
static int enlarge_userbuf (_IO_FILE *fp, _IO_off64_t offset, int reading) { if ((_IO_ssize_t) offset <= _IO_wblen (fp)) return 0; struct _IO_wide_data *wd = fp->_wide_data; _IO_ssize_t oldend = wd->_IO_write_end - wd->_IO_write_base; /* Try to enlarge the buffer. */ if (fp->_flags2 & _IO_FLAGS2_USER_WBUF) /* User-provided buffer. */ return 1; _IO_size_t newsize = offset + 100; if (__glibc_unlikely (newsize > SIZE_MAX / sizeof (wchar_t))) return 1; wchar_t *oldbuf = wd->_IO_buf_base; wchar_t *newbuf = (wchar_t *) (*((_IO_strfile *) fp)->_s._allocate_buffer) (newsize * sizeof (wchar_t)); if (newbuf == NULL) return 1; if (oldbuf != NULL) { __wmemcpy (newbuf, oldbuf, _IO_wblen (fp)); (*((_IO_strfile *) fp)->_s._free_buffer) (oldbuf); /* Make sure _IO_setb won't try to delete _IO_buf_base. */ wd->_IO_buf_base = NULL; } _IO_wsetb (fp, newbuf, newbuf + newsize, 1); if (reading) { wd->_IO_write_base = newbuf + (wd->_IO_write_base - oldbuf); wd->_IO_write_ptr = newbuf + (wd->_IO_write_ptr - oldbuf); wd->_IO_write_end = newbuf + (wd->_IO_write_end - oldbuf); wd->_IO_read_ptr = newbuf + (wd->_IO_read_ptr - oldbuf); wd->_IO_read_base = newbuf; wd->_IO_read_end = wd->_IO_buf_end; } else { wd->_IO_read_base = newbuf + (wd->_IO_read_base - oldbuf); wd->_IO_read_ptr = newbuf + (wd->_IO_read_ptr - oldbuf); wd->_IO_read_end = newbuf + (wd->_IO_read_end - oldbuf); wd->_IO_write_ptr = newbuf + (wd->_IO_write_ptr - oldbuf); wd->_IO_write_base = newbuf; wd->_IO_write_end = wd->_IO_buf_end; } /* Clear the area between the last write position and th new position. */ assert (offset >= oldend); if (reading) __wmemset (wd->_IO_read_base + oldend, L'\0', offset - oldend); else __wmemset (wd->_IO_write_base + oldend, L'\0', offset - oldend); return 0; }