Beispiel #1
0
int
attribute_compat_text_section
_IO_old_file_sync (_IO_FILE *fp)
{
  _IO_ssize_t delta;
  int retval = 0;

  /*    char* ptr = cur_ptr(); */
  if (fp->_IO_write_ptr > fp->_IO_write_base)
    if (_IO_old_do_flush(fp)) return EOF;
  delta = fp->_IO_read_ptr - fp->_IO_read_end;
  if (delta != 0)
    {
#ifdef TODO
      if (_IO_in_backup (fp))
	delta -= eGptr () - Gbase ();
#endif
      _IO_off_t new_pos = _IO_SYSSEEK (fp, delta, 1);
      if (new_pos != (_IO_off_t) EOF)
	fp->_IO_read_end = fp->_IO_read_ptr;
#ifdef ESPIPE
      else if (errno == ESPIPE)
	; /* Ignore error from unseekable devices. */
#endif
      else
	retval = EOF;
    }
  if (retval != EOF)
    fp->_old_offset = _IO_pos_BAD;
  /* FIXME: Cleanup - can this be shared? */
  /*    setg(base(), ptr, ptr); */
  return retval;
}
Beispiel #2
0
void
_IO_unsave_markers (_IO_FILE *fp)
{
  struct _IO_marker *mark = fp->_markers;
  if (mark)
    {
#ifdef TODO
      streampos offset = seekoff (0, ios::cur, ios::in);
      if (offset != EOF)
	{
	  offset += eGptr () - Gbase ();
	  for ( ; mark != NULL; mark = mark->_next)
	    mark->set_streampos (mark->_pos + offset);
	}
    else
      {
	for ( ; mark != NULL; mark = mark->_next)
	  mark->set_streampos (EOF);
      }
#endif
      fp->_markers = 0;
    }

  if (_IO_have_backup (fp))
    _IO_free_backup_area (fp);
}
Beispiel #3
0
int filebuf::sync()
{
//    char* ptr = cur_ptr();
    if (pptr() > pbase())
	if (do_flush()) return EOF;
    if (gptr() != egptr()) {
	streampos delta = gptr() - egptr();
	if (in_backup())
	    delta -= eGptr() - Gbase();
	if (sys_seek(delta, ios::cur) == EOF)
	    return EOF;
    }
    // FIXME: Cleanup - can this be shared?
//    setg(base(), ptr, ptr);
    return 0;
}
Beispiel #4
0
static int
_IO_file_sync_mmap (_IO_FILE *fp)
{
  if (fp->_IO_read_ptr != fp->_IO_read_end)
    {
#ifdef TODO
      if (_IO_in_backup (fp))
	delta -= eGptr () - Gbase ();
#endif
      if (__lseek64 (fp->_fileno, fp->_IO_read_ptr - fp->_IO_buf_base,
		     SEEK_SET)
	  != fp->_IO_read_ptr - fp->_IO_buf_base)
	{
	  fp->_flags |= _IO_ERR_SEEN;
	  return EOF;
	}
    }
  fp->_offset = fp->_IO_read_ptr - fp->_IO_buf_base;
  fp->_IO_read_end = fp->_IO_read_ptr = fp->_IO_read_base;
  return 0;
}
Beispiel #5
0
streampos filebuf::seekoff(streamoff offset, _seek_dir dir, int mode)
{
    streampos result, new_offset, delta;
    _G_ssize_t count;

    if (mode == 0) // Don't move any pointers.
	dir = ios::cur, offset = 0;

    // Flush unwritten characters.
    // (This may do an unneeded write if we seek within the buffer.
    // But to be able to switch to reading, we would need to set
    // egptr to ptr.  That can't be done in the current design,
    // which assumes file_ptr() is eGptr.  Anyway, since we probably
    // end up flushing when we close(), it doesn't make much difference.)
    if (pptr() > pbase() || put_mode())
	if (switch_to_get_mode()) return EOF;

    if (base() == NULL) {
	doallocbuf();
	setp(base(), base());
	setg(base(), base(), base());
    }
    switch (dir) {
      case ios::cur:
	if (_fb._offset < 0) {
	    _fb._offset = sys_seek(0, ios::cur);
	    if (_fb._offset < 0)
		return EOF;
	}
	// Make offset absolute, assuming current pointer is file_ptr().
	offset += _fb._offset;

	offset -= _egptr - _gptr;
	if (in_backup())
	    offset -= _other_egptr - _other_gbase;
	dir = ios::beg;
	break;
      case ios::beg:
	break;
      case ios::end:
	struct stat st;
	if (sys_stat(&st) == 0 && S_ISREG(st.st_mode)) {
	    offset += st.st_size;
	    dir = ios::beg;
	}
	else
	    goto dumb;
    }
    // At this point, dir==ios::beg.

    // If destination is within current buffer, optimize:
    if (_fb._offset >= 0 && _eback != NULL) {
	// Offset relative to start of main get area.
	fpos_t rel_offset = offset - _fb._offset
	    + (eGptr()-Gbase());
	if (rel_offset >= 0) {
	    if (in_backup())
		switch_to_main_get_area();
	    if (rel_offset <= _egptr - _eback) {
		setg(base(), base() + rel_offset, egptr());
		setp(base(), base());
		return offset;
	    }
	    // If we have streammarkers, seek forward by reading ahead.
	    if (have_markers()) {
		int to_skip = rel_offset - (_gptr - _eback);
		if (ignore(to_skip) != to_skip)
		    goto dumb;
		return offset;
	    }
	}
	if (rel_offset < 0 && rel_offset >= Bbase() - Bptr()) {
	    if (!in_backup())
		switch_to_backup_area();
	    gbump(_egptr + rel_offset - gptr());
	    return offset;
	}
    }

    unsave_markers();

    // Try to seek to a block boundary, to improve kernel page management.
    new_offset = offset & ~(ebuf() - base() - 1);
    delta = offset - new_offset;
    if (delta > ebuf() - base()) {
	new_offset = offset;
	delta = 0;
    }
    result = sys_seek(new_offset, ios::beg);
    if (result < 0)
	return EOF;
    if (delta == 0)
	count = 0;
    else {
	count = sys_read(base(), ebuf()-base());
	if (count < delta) {
	    // We weren't allowed to read, but try to seek the remainder.
	    offset = count == EOF ? delta : delta-count;
	    dir = ios::cur;
	    goto dumb;
	}
    }
    setg(base(), base()+delta, base()+count);
    setp(base(), base());
    _fb._offset = result + count;
    xflags(xflags() & ~ _S_EOF_SEEN);
    return offset;
  dumb:
    unsave_markers();
    result = sys_seek(offset, dir);
    if (result != EOF) {
	xflags(xflags() & ~_S_EOF_SEEN);
    }
    _fb._offset = result;
    setg(base(), base(), base());
    setp(base(), base());
    return result;
}
Beispiel #6
0
streammarker::~streammarker()
{
    if (saving()) {
	// Unlink from sb's chain.
	register streammarker **ptr = &((backupbuf*)_sbuf)->_markers;
	for (; ; ptr = &(*ptr)->_next)
	    if (*ptr == NULL)
		break;
	    else if (*ptr == this) {
		*ptr = _next;
		return;
	    }
    }
#if 0
    if _sbuf has a backup area that is no longer needed, should we delete
    it now, or wait until underflow()?
#endif
}

#define BAD_DELTA EOF

int streammarker::delta(streammarker& other_mark)
{
    if (_sbuf != other_mark._sbuf)
	return BAD_DELTA;
    if (saving() && other_mark.saving())
	return _pos - other_mark._pos;
    else if (!saving() && !other_mark.saving())
	return _spos - other_mark._spos;
    else
	return BAD_DELTA;
}

int streammarker::delta()
{
    if (_sbuf == NULL)
	return BAD_DELTA;
    if (saving()) {
	int cur_pos;
	if (_sbuf->in_backup())
	    cur_pos = _sbuf->_gptr - _sbuf->_egptr;
	else
	    cur_pos = _sbuf->_gptr - _sbuf->_eback;
	return _pos - cur_pos;
    }
    else {
	if (_spos == EOF)
	    return BAD_DELTA;
	int cur_pos = _sbuf->seekoff(0, ios::cur);
	if (cur_pos == EOF)
	    return BAD_DELTA;
	return _pos - cur_pos;
    }
}

int streambuf::seekmark(streammarker& mark, int delta /* = 0 */)
{
    if (mark._sbuf != this)
	return EOF;
    if (!mark.saving()) {
	return seekpos(mark._spos, ios::in);
    }
    else if (mark._pos >= 0) {
	if (in_backup())
	    switch_to_main_get_area();
	_gptr = _eback + mark._pos;
    }
    else {
	if (!in_backup())
	    switch_to_backup_area();
	_gptr = _egptr + mark._pos;
    }
    return 0;
}

void streambuf::unsave_markers()
{
    register streammarker *mark =_markers;
    if (_markers) {
	streampos offset = seekoff(0, ios::cur, ios::in);
	if (offset != EOF) {
	    offset += eGptr() - Gbase();
	    for ( ; mark != NULL; mark = mark->_next)
		mark->set_streampos(mark->_pos + offset);
	}
	else {
	    for ( ; mark != NULL; mark = mark->_next)
		mark->set_streampos(EOF);
	}
	_markers = 0;
    }

    free_backup_area();
}

int backupbuf::pbackfail(int c)
{
    if (_gptr <= _eback) {
	// Need to handle a filebuf in write mode (switch to read mode).  FIXME!
	if (have_backup() && !in_backup()) {
	    switch_to_backup_area();
	}
	if (!have_backup()) {
	    // No backup buffer: allocate one.
	    // Use short buffer, if unused? (probably not)  FIXME 
	    int backup_size = 128;
	    _other_gbase = new char [backup_size];
	    _other_egptr = _other_gbase + backup_size;
	    _aux_limit = _other_egptr;
	    switch_to_backup_area();
	}
	else if (gptr() <= eback()) {
	    // Increase size of existing backup buffer.
	    size_t new_size;
	    size_t old_size = egptr() - eback();
	    new_size = 2 * old_size;
	    char* new_buf = new char [new_size];
	    memcpy(new_buf+(new_size-old_size), eback(), old_size);
	    delete [] eback();
	    setg(new_buf, new_buf+(new_size-old_size), new_buf+new_size);
	    _aux_limit = _gptr;
        }
    }
    _gptr--;
    if (c != EOF && *_gptr != c)
	*_gptr = c;
    return (unsigned char)*_gptr;
}

unsigned __adjust_column(unsigned start, const char *line, int count)
{
    register const char *ptr = line + count;
    while (ptr > line)
	if (*--ptr == '\n')
	    return line + count - ptr - 1;
    return start + count;
}

int ios::readable() { return !(rdbuf()->_flags & _S_NO_READS); }
int ios::writable() { return !(rdbuf()->_flags & _S_NO_WRITES); }
int ios::is_open() { return rdbuf()
			 && (rdbuf()->_flags & _S_NO_READS+_S_NO_WRITES)
			     != _S_NO_READS+_S_NO_WRITES; }

#if defined(linux)
#define IO_CLEANUP ;
#endif

#ifdef IO_CLEANUP
  IO_CLEANUP
#else
struct __io_defs {
    __io_defs() { }
    ~__io_defs() { streambuf::flush_all(); }
};   
__io_defs io_defs__;