int attribute_compat_text_section _IO_old_file_close_it (_IO_FILE *fp) { int write_status, close_status; if (!_IO_file_is_open (fp)) return EOF; write_status = _IO_old_do_flush (fp); _IO_unsave_markers (fp); close_status = ((fp->_flags2 & _IO_FLAGS2_NOCLOSE) == 0 ? _IO_SYSCLOSE (fp) : 0); /* Free buffer. */ _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->_old_offset = _IO_pos_BAD; return close_status ? close_status : write_status; }
/* Allocate a file buffer, or switch to unbuffered I/O. Streams for TTY devices default to line buffered. */ int _IO_file_doallocate (_IO_FILE *fp) { _IO_size_t size; char *p; struct stat64 st; size = _IO_BUFSIZ; if (fp->_fileno >= 0 && __builtin_expect (_IO_SYSSTAT (fp, &st), 0) >= 0) { if (S_ISCHR (st.st_mode)) { /* Possibly a tty. */ if ( #ifdef DEV_TTY_P DEV_TTY_P (&st) || #endif local_isatty (fp->_fileno)) fp->_flags |= _IO_LINE_BUF; } #if _IO_HAVE_ST_BLKSIZE if (st.st_blksize > 0 && st.st_blksize < _IO_BUFSIZ) size = st.st_blksize; #endif } p = malloc (size); if (__glibc_unlikely (p == NULL)) return EOF; _IO_setb (fp, p, p + size, 1); return 1; }
void _IO_str_init_static_internal (_IO_strfile *sf, char *ptr, _IO_size_t size, char *pstart) { _IO_FILE *fp = &sf->_sbf._f; char *end; if (size == 0) end = __rawmemchr (ptr, '\0'); else if ((_IO_size_t) ptr + size > (_IO_size_t) ptr) end = ptr + size; else end = (char *) -1; _IO_setb (fp, ptr, end, 0); fp->_IO_write_base = ptr; fp->_IO_read_base = ptr; fp->_IO_read_ptr = ptr; if (pstart) { fp->_IO_write_ptr = pstart; fp->_IO_write_end = end; fp->_IO_read_end = pstart; } else { fp->_IO_write_ptr = ptr; fp->_IO_write_end = ptr; fp->_IO_read_end = end; } /* A null _allocate_buffer function flags the strfile as being static. */ sf->_s._allocate_buffer = (_IO_alloc_type) 0; }
int _IO_str_overflow (_IO_FILE *fp, int c) { int flush_only = c == EOF; _IO_size_t pos; if (fp->_flags & _IO_NO_WRITES) return flush_only ? 0 : EOF; if ((fp->_flags & _IO_TIED_PUT_GET) && !(fp->_flags & _IO_CURRENTLY_PUTTING)) { fp->_flags |= _IO_CURRENTLY_PUTTING; fp->_IO_write_ptr = fp->_IO_read_ptr; fp->_IO_read_ptr = fp->_IO_read_end; } pos = fp->_IO_write_ptr - fp->_IO_write_base; if (pos >= (_IO_size_t) (_IO_blen (fp) + flush_only)) { if (fp->_flags & _IO_USER_BUF) /* not allowed to enlarge */ return EOF; else { char *new_buf; char *old_buf = fp->_IO_buf_base; size_t old_blen = _IO_blen (fp); _IO_size_t new_size = 2 * old_blen + 100; if (new_size < old_blen) return EOF; new_buf = (char *) (*((_IO_strfile *) fp)->_s._allocate_buffer) (new_size); if (new_buf == NULL) { /* __ferror(fp) = 1; */ return EOF; } if (old_buf) { memcpy (new_buf, old_buf, old_blen); (*((_IO_strfile *) fp)->_s._free_buffer) (old_buf); /* Make sure _IO_setb won't try to delete _IO_buf_base. */ fp->_IO_buf_base = NULL; } memset (new_buf + old_blen, '\0', new_size - old_blen); _IO_setb (fp, new_buf, new_buf + new_size, 1); fp->_IO_read_base = new_buf + (fp->_IO_read_base - old_buf); fp->_IO_read_ptr = new_buf + (fp->_IO_read_ptr - old_buf); fp->_IO_read_end = new_buf + (fp->_IO_read_end - old_buf); fp->_IO_write_ptr = new_buf + (fp->_IO_write_ptr - old_buf); fp->_IO_write_base = new_buf; fp->_IO_write_end = fp->_IO_buf_end; } } if (!flush_only) *fp->_IO_write_ptr++ = (unsigned char) c; if (fp->_IO_write_ptr > fp->_IO_read_end) fp->_IO_read_end = fp->_IO_write_ptr; return c; }
_IO_FILE * _IO_default_setbuf (_IO_FILE *fp, char *p, _IO_ssize_t len) { if (_IO_SYNC (fp) == EOF) return NULL; if (p == NULL || len == 0) { fp->_flags |= _IO_UNBUFFERED; _IO_setb (fp, fp->_shortbuf, fp->_shortbuf+1, 0); } else { fp->_flags &= ~_IO_UNBUFFERED; _IO_setb (fp, p, p+len, 0); } fp->_IO_write_base = fp->_IO_write_ptr = fp->_IO_write_end = 0; fp->_IO_read_base = fp->_IO_read_ptr = fp->_IO_read_end = 0; return fp; }
void _IO_doallocbuf (_IO_FILE *fp) { if (fp->_IO_buf_base) return; if (!(fp->_flags & _IO_UNBUFFERED) || fp->_mode > 0) if (_IO_DOALLOCATE (fp) != EOF) return; _IO_setb (fp, fp->_shortbuf, fp->_shortbuf+1, 0); }
int _IO_default_doallocate (_IO_FILE *fp) { char *buf; buf = malloc(_IO_BUFSIZ); if (__glibc_unlikely (buf == NULL)) return EOF; _IO_setb (fp, buf, buf+_IO_BUFSIZ, 1); return 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; }
static void decide_maybe_mmap (_IO_FILE *fp) { /* We use the file in read-only mode. This could mean we can mmap the file and use it without any copying. But not all file descriptors are for mmap-able objects and on 32-bit machines we don't want to map files which are too large since this would require too much virtual memory. */ struct stat64 st; if (_IO_SYSSTAT (fp, &st) == 0 && S_ISREG (st.st_mode) && st.st_size != 0 /* Limit the file size to 1MB for 32-bit machines. */ && (sizeof (ptrdiff_t) > 4 || st.st_size < 1*1024*1024) /* Sanity check. */ && (fp->_offset == _IO_pos_BAD || fp->_offset <= st.st_size)) { /* Try to map the file. */ void *p; p = __mmap64 (NULL, st.st_size, PROT_READ, MAP_SHARED, fp->_fileno, 0); if (p != MAP_FAILED) { /* OK, we managed to map the file. Set the buffer up and use a special jump table with simplified underflow functions which never tries to read anything from the file. */ if (__lseek64 (fp->_fileno, st.st_size, SEEK_SET) != st.st_size) { (void) __munmap (p, st.st_size); fp->_offset = _IO_pos_BAD; } else { _IO_setb (fp, p, (char *) p + st.st_size, 0); if (fp->_offset == _IO_pos_BAD) fp->_offset = 0; _IO_setg (fp, p, p + fp->_offset, p + st.st_size); fp->_offset = st.st_size; if (fp->_mode <= 0) _IO_JUMPS_FILE_plus (fp) = &_IO_file_jumps_mmap; else _IO_JUMPS_FILE_plus (fp) = &_IO_wfile_jumps_mmap; fp->_wide_data->_wide_vtable = &_IO_wfile_jumps_mmap; return; } } } /* We couldn't use mmap, so revert to the vanilla file operations. */ if (fp->_mode <= 0) _IO_JUMPS_FILE_plus (fp) = &_IO_file_jumps; else _IO_JUMPS_FILE_plus (fp) = &_IO_wfile_jumps; fp->_wide_data->_wide_vtable = &_IO_wfile_jumps; }
static int enlarge_userbuf (_IO_FILE *fp, _IO_off64_t offset, int reading) { if ((_IO_ssize_t) offset <= _IO_blen (fp)) return 0; _IO_ssize_t oldend = fp->_IO_write_end - fp->_IO_write_base; /* Try to enlarge the buffer. */ if (fp->_flags & _IO_USER_BUF) /* User-provided buffer. */ return 1; _IO_size_t newsize = offset + 100; char *oldbuf = fp->_IO_buf_base; char *newbuf = (char *) (*((_IO_strfile *) fp)->_s._allocate_buffer) (newsize); if (newbuf == NULL) return 1; if (oldbuf != NULL) { memcpy (newbuf, oldbuf, _IO_blen (fp)); (*((_IO_strfile *) fp)->_s._free_buffer) (oldbuf); /* Make sure _IO_setb won't try to delete _IO_buf_base. */ fp->_IO_buf_base = NULL; } _IO_setb (fp, newbuf, newbuf + newsize, 1); if (reading) { fp->_IO_write_base = newbuf + (fp->_IO_write_base - oldbuf); fp->_IO_write_ptr = newbuf + (fp->_IO_write_ptr - oldbuf); fp->_IO_write_end = newbuf + (fp->_IO_write_end - oldbuf); fp->_IO_read_ptr = newbuf + (fp->_IO_read_ptr - oldbuf); fp->_IO_read_base = newbuf; fp->_IO_read_end = fp->_IO_buf_end; } else { fp->_IO_read_base = newbuf + (fp->_IO_read_base - oldbuf); fp->_IO_read_ptr = newbuf + (fp->_IO_read_ptr - oldbuf); fp->_IO_read_end = newbuf + (fp->_IO_read_end - oldbuf); fp->_IO_write_ptr = newbuf + (fp->_IO_write_ptr - oldbuf); fp->_IO_write_base = newbuf; fp->_IO_write_end = fp->_IO_buf_end; } /* Clear the area between the last write position and th new position. */ assert (offset >= oldend); if (reading) memset (fp->_IO_read_base + oldend, '\0', offset - oldend); else memset (fp->_IO_write_base + oldend, '\0', offset - oldend); return 0; }