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];
/* Magic number and bits for the _flags field. The magic number is mostly vestigial, but preserved for compatibility. It occupies the high 16 bits of _flags; the low 16 bits are actual flag bits. */ #define _IO_MAGIC 0xFBAD0000 /* Magic number */ #define _IO_MAGIC_MASK 0xFFFF0000 #define _IO_USER_BUF 0x0001 /* Don't deallocate buffer on close. */ #define _IO_UNBUFFERED 0x0002 #define _IO_NO_READS 0x0004 /* Reading not allowed. */ #define _IO_NO_WRITES 0x0008 /* Writing not allowed. */ #define _IO_EOF_SEEN 0x0010 #define _IO_ERR_SEEN 0x0020 #define _IO_DELETE_DONT_CLOSE 0x0040 /* Don't call close(_fileno) on close. */ #define _IO_LINKED 0x0080 /* In the list of all open files. */ #define _IO_IN_BACKUP 0x0100 #define _IO_LINE_BUF 0x0200 #define _IO_TIED_PUT_GET 0x0400 /* Put and get pointer move in unison. */ #define _IO_CURRENTLY_PUTTING 0x0800 #define _IO_IS_APPENDING 0x1000 #define _IO_IS_FILEBUF 0x2000 /* 0x4000 No longer used, reserved for compat. */ #define _IO_USER_LOCK 0x8000
#define _IOFBF 0 /* Fully buffered. */ #define _IOLBF 1 /* Line buffered. */ #define _IONBF 2 /* No buffering. */ int _IO_setvbuf (_IO_FILE *fp, char *buf, int mode, _IO_size_t size) { int result; CHECK_FILE (fp, EOF); _IO_acquire_lock (fp); switch (mode) { case _IOFBF: fp->_IO_file_flags &= ~(_IO_LINE_BUF|_IO_UNBUFFERED); if (buf == NULL) { if (fp->_IO_buf_base == NULL) { /* There is no flag to distinguish between "fully buffered mode has been explicitly set" as opposed to "line buffering has not been explicitly set". In both cases, _IO_LINE_BUF is off. If this is a tty, and _IO_filedoalloc later gets called, it cannot know if it should set the _IO_LINE_BUF flag (because that is the default), or not (because we have explicitly asked for fully buffered mode). So we make sure a buffer gets allocated now, and explicitly turn off line buffering. A possibly cleaner alternative would be to add an extra flag, but then flags are a finite resource. */ if (_IO_DOALLOCATE (fp) < 0) { result = EOF; goto unlock_return; } fp->_IO_file_flags &= ~_IO_LINE_BUF; } result = 0; goto unlock_return; } break; case _IOLBF: fp->_IO_file_flags &= ~_IO_UNBUFFERED; fp->_IO_file_flags |= _IO_LINE_BUF; if (buf == NULL) { result = 0; goto unlock_return; } break; case _IONBF: fp->_IO_file_flags &= ~_IO_LINE_BUF; fp->_IO_file_flags |= _IO_UNBUFFERED; buf = NULL; size = 0; break; default: result = EOF; goto unlock_return; } result = _IO_SETBUF (fp, buf, size) == NULL ? EOF : 0;