struct _IO_FILE { int _flags; /* High-order word is _IO_MAGIC; rest is flags. */ #define _IO_file_flags _flags
/* The following pointers correspond to the C++ streambuf protocol. */ /* Note: Tk uses the _IO_read_ptr and _IO_read_end fields directly. */ char* _IO_read_ptr; /* Current read pointer */ char* _IO_read_end; /* End of get area. */ char* _IO_read_base; /* Start of putback+get area. */ char* _IO_write_base; /* Start of put area. */ char* _IO_write_ptr; /* Current put pointer. */ char* _IO_write_end; /* End of put area. */ char* _IO_buf_base; /* Start of reserve area. */ char* _IO_buf_end; /* End of reserve area. */ /* The following fields are used to support backing up and undo. */ char *_IO_save_base; /* Pointer to start of non-current get area. */ char *_IO_backup_base; /* Pointer to first valid character of backup area */ char *_IO_save_end; /* Pointer to end of non-current get area. */
struct _IO_marker *_markers;
struct _IO_FILE *_chain;
int _fileno; #if 0 int _blksize; #else int _flags2; #endif _IO_off_t _old_offset; /* This used to be _offset but it's too small. */
#define __HAVE_COLUMN /* temporary */ /* 1+column number of pbase(); 0 is unknown. */ unsignedshort _cur_column; signedchar _vtable_offset; char _shortbuf[1];
if (n <= 0) return0; /* This is an optimized implementation. If the amount to be written straddles a block boundary (or the filebuf is unbuffered), use sys_write directly. */
/* First figure out how much space is available in the buffer. */ if ((f->_flags & _IO_LINE_BUF) && (f->_flags & _IO_CURRENTLY_PUTTING)) { count = f->_IO_buf_end - f->_IO_write_ptr; if (count >= n) 4{ 4 constchar *p; 4 for (p = s + n; p > s; ) 4 { 4 if (*--p == '\n') 44{ 44 count = p - s + 1; 44 must_flush = 1; 44 break; 44} 4 } 4} } elseif (f->_IO_write_end > f->_IO_write_ptr) count = f->_IO_write_end - f->_IO_write_ptr; /* Space available. */
/* Then fill the buffer. */ if (count > 0) { if (count > to_do) 4count = to_do; f->_IO_write_ptr = __mempcpy (f->_IO_write_ptr, s, count); s += count; to_do -= count; } if (to_do + must_flush > 0) { size_t block_size, do_write; /* Next flush the (full) buffer. */ if (_IO_OVERFLOW (f, EOF) == EOF) 4/* If nothing else has to be written we must not signal the 4 caller that everything has been written. */ 4return to_do == 0 ? EOF : n - to_do;
/* Try to maintain alignment: write a whole number of blocks. */ block_size = f->_IO_buf_end - f->_IO_buf_base; do_write = to_do - (block_size >= 128 ? to_do % block_size : 0);
if (do_write) 4{ 4 count = new_do_write (f, s, do_write); 4 to_do -= count; 4 if (count < do_write) 4 return n - to_do; 4}
/* Now write out the remainder. Normally, this will fit in the 4 buffer, but it's somewhat messier for line-buffered files, 4 so we let _IO_default_xsputn handle the general case. */ if (to_do) 4to_do -= _IO_default_xsputn (f, s+do_write, to_do); } return n - to_do; }
1335if (__IO_OVERFLOW (f, EOF) == EOF) 1336/* If nothing else has to be written we must not signal the 1337 caller that everything has been written. */ 1338return to_do == 0 ? EOF : n - to_do;
int _IO_new_file_overflow (FILE *f, int ch) { if (f->_flags & _IO_NO_WRITES) /* SET ERROR */ { f->_flags |= _IO_ERR_SEEN; __set_errno (EBADF); return EOF; } /* If currently reading or no buffer allocated. */ if ((f->_flags & _IO_CURRENTLY_PUTTING) == 0 || f->_IO_write_base == NULL) { /* Allocate a buffer if needed. */ if (f->_IO_write_base == NULL) 4{ 4 _IO_doallocbuf (f); 4 _IO_setg (f, f->_IO_buf_base, f->_IO_buf_base, f->_IO_buf_base); 4} /* Otherwise must be currently reading. 4 If _IO_read_ptr (and hence also _IO_read_end) is at the buffer end, 4 logically slide the buffer forwards one block (by setting the 4 read pointers to all point at the beginning of the block). This 4 makes room for subsequent output. 4 Otherwise, set the read pointers to _IO_read_end (leaving that 4 alone, so it can continue to correspond to the external position). */ if (__glibc_unlikely (_IO_in_backup (f))) 4{ 4 size_t nbackup = f->_IO_read_end - f->_IO_read_ptr; 4 _IO_free_backup_area (f); 4 f->_IO_read_base -= MIN (nbackup, 4444 f->_IO_read_base - f->_IO_buf_base); 4 f->_IO_read_ptr = f->_IO_read_base; 4}