aboutsummaryrefslogtreecommitdiff
path: root/libio/wfileops.c
diff options
context:
space:
mode:
Diffstat (limited to 'libio/wfileops.c')
-rw-r--r--libio/wfileops.c92
1 files changed, 90 insertions, 2 deletions
diff --git a/libio/wfileops.c b/libio/wfileops.c
index 92d1a08..35d201b 100644
--- a/libio/wfileops.c
+++ b/libio/wfileops.c
@@ -143,7 +143,7 @@ _IO_wfile_underflow (fp)
int tries;
const char *read_ptr_copy;
- if (fp->_flags & _IO_NO_READS)
+ if (__builtin_expect (fp->_flags & _IO_NO_READS, 0))
{
fp->_flags |= _IO_ERR_SEEN;
__set_errno (EBADF);
@@ -161,10 +161,12 @@ _IO_wfile_underflow (fp)
const char *read_stop = (const char *) fp->_IO_read_ptr;
fp->_wide_data->_IO_last_state = fp->_wide_data->_IO_state;
+ fp->_wide_data->_IO_read_base = fp->_wide_data->_IO_read_ptr =
+ fp->_wide_data->_IO_buf_base;
status = (*cd->__codecvt_do_in) (cd, &fp->_wide_data->_IO_state,
fp->_IO_read_ptr, fp->_IO_read_end,
&read_stop,
- fp->_wide_data->_IO_read_end,
+ fp->_wide_data->_IO_read_ptr,
fp->_wide_data->_IO_buf_end,
&fp->_wide_data->_IO_read_end);
@@ -306,6 +308,67 @@ _IO_wfile_underflow (fp)
}
+static wint_t
+_IO_wfile_underflow_mmap (_IO_FILE *fp)
+{
+ struct _IO_codecvt *cd;
+ enum __codecvt_result status;
+
+ if (__builtin_expect (fp->_flags & _IO_NO_READS, 0))
+ {
+ fp->_flags |= _IO_ERR_SEEN;
+ __set_errno (EBADF);
+ return WEOF;
+ }
+ if (fp->_wide_data->_IO_read_ptr < fp->_wide_data->_IO_read_end)
+ return *fp->_wide_data->_IO_read_ptr;
+
+ cd = fp->_codecvt;
+
+ /* Maybe there is something left in the external buffer. */
+ if (fp->_IO_read_ptr < fp->_IO_read_end)
+ {
+ /* There is more in the external. Convert it. */
+ const char *read_stop = (const char *) fp->_IO_read_ptr;
+
+ if (fp->_wide_data->_IO_buf_base == NULL)
+ {
+ /* Maybe we already have a push back pointer. */
+ if (fp->_wide_data->_IO_save_base != NULL)
+ {
+ free (fp->_wide_data->_IO_save_base);
+ fp->_flags &= ~_IO_IN_BACKUP;
+ }
+ _IO_wdoallocbuf (fp);
+ }
+
+ fp->_wide_data->_IO_last_state = fp->_wide_data->_IO_state;
+ fp->_wide_data->_IO_read_base = fp->_wide_data->_IO_read_ptr =
+ fp->_wide_data->_IO_buf_base;
+ status = (*cd->__codecvt_do_in) (cd, &fp->_wide_data->_IO_state,
+ fp->_IO_read_ptr, fp->_IO_read_end,
+ &read_stop,
+ fp->_wide_data->_IO_read_ptr,
+ fp->_wide_data->_IO_buf_end,
+ &fp->_wide_data->_IO_read_end);
+
+ fp->_IO_read_ptr = (char *) read_stop;
+
+ /* If we managed to generate some text return the next character. */
+ if (fp->_wide_data->_IO_read_ptr < fp->_wide_data->_IO_read_end)
+ return *fp->_wide_data->_IO_read_ptr;
+
+ /* There is some garbage at the end of the file. */
+ __set_errno (EILSEQ);
+ fp->_flags |= _IO_ERR_SEEN;
+ return WEOF;
+ }
+
+ fp->_flags |= _IO_EOF_SEEN;
+ return WEOF;
+}
+
+
wint_t
_IO_wfile_overflow (f, wch)
_IO_FILE *f;
@@ -789,3 +852,28 @@ struct _IO_jump_t _IO_wfile_jumps =
JUMP_INIT(showmanyc, _IO_default_showmanyc),
JUMP_INIT(imbue, _IO_default_imbue)
};
+
+
+struct _IO_jump_t _IO_wfile_jumps_mmap =
+{
+ JUMP_INIT_DUMMY,
+ JUMP_INIT(finish, _IO_new_file_finish),
+ JUMP_INIT(overflow, (_IO_overflow_t) _IO_wfile_overflow),
+ JUMP_INIT(underflow, (_IO_underflow_t) _IO_wfile_underflow_mmap),
+ JUMP_INIT(uflow, (_IO_underflow_t) _IO_wdefault_uflow),
+ JUMP_INIT(pbackfail, (_IO_pbackfail_t) _IO_wdefault_pbackfail),
+ JUMP_INIT(xsputn, _IO_wfile_xsputn),
+ JUMP_INIT(xsgetn, _IO_file_xsgetn),
+ JUMP_INIT(seekoff, _IO_wfile_seekoff),
+ JUMP_INIT(seekpos, _IO_default_seekpos),
+ JUMP_INIT(setbuf, _IO_new_file_setbuf),
+ JUMP_INIT(sync, (_IO_sync_t) _IO_wfile_sync),
+ JUMP_INIT(doallocate, _IO_wfile_doallocate),
+ JUMP_INIT(read, _IO_file_read),
+ JUMP_INIT(write, _IO_new_file_write),
+ JUMP_INIT(seek, _IO_file_seek),
+ JUMP_INIT(close, _IO_file_close_mmap),
+ JUMP_INIT(stat, _IO_file_stat),
+ JUMP_INIT(showmanyc, _IO_default_showmanyc),
+ JUMP_INIT(imbue, _IO_default_imbue)
+};