コード例 #1
0
ファイル: filebuf.C プロジェクト: LambdaCalculus379/SLS-1.02
int filebuf::do_write(const char *data, int to_do)
{
    if (to_do == 0)
	return 0;
    if (xflags() & _S_IS_APPENDING) {
	// On a system without a proper O_APPEND implementation,
	// you would need to sys_seek(0, ios::end) here, but is
	// is not needed nor desirable for Unix- or Posix-like systems.
	// Instead, just indicate that offset (before and after) is
	// unpredictable.
	_fb._offset = -1;
    }
    else if (egptr() != pbase()) {
	long new_pos = sys_seek(pbase()-egptr(), ios::cur);
	if (new_pos == -1)
	    return EOF;
	_fb._offset = new_pos;
    }
    _G_ssize_t count = sys_write(data, to_do);
    if (_cur_column)
	_cur_column = __adjust_column(_cur_column - 1, data, to_do) + 1;
    setg(base(), base(), base());
    if (xflags() & _S_LINE_BUF+_S_UNBUFFERED) setp(base(), base());
    else setp(base(), ebuf());
    return count != to_do ? EOF : 0;
}
コード例 #2
0
ファイル: filebuf.C プロジェクト: Kiddinglife/4.4BSD-Lite
int filebuf::overflow(int c)
{
    if (xflags() & _S_NO_WRITES) // SET ERROR
	return EOF;
    // Allocate a buffer if needed.
    if (base() == NULL) {
	doallocbuf();
	if (xflags() & _S_LINE_BUF+_S_UNBUFFERED) setp(_base, _base);
	else setp(_base, _ebuf);
	setg(_base, _base, _base);
	_flags |= _S_CURRENTLY_PUTTING;
    }
    // If currently reading, switch to writing.
    else if ((_flags & _S_CURRENTLY_PUTTING) == 0) {
	if (xflags() & _S_LINE_BUF+_S_UNBUFFERED) setp(gptr(), gptr());
	else setp(gptr(), ebuf());
	setg(egptr(), egptr(), egptr());
	_flags |= _S_CURRENTLY_PUTTING;
    }
    if (c == EOF)
	return do_flush();
    if (pptr() == ebuf() ) // Buffer is really full
	if (do_flush() == EOF)
	    return EOF;
    xput_char(c);
    if (unbuffered() || (linebuffered() && c == '\n'))
	if (do_flush() == EOF)
	    return EOF;
    return (unsigned char)c;
}
コード例 #3
0
ファイル: filebuf.C プロジェクト: LambdaCalculus379/SLS-1.02
filebuf::~filebuf()
{
    if (!(xflags() & _S_DELETE_DONT_CLOSE))
	close();

    _un_link();
}
コード例 #4
0
ファイル: filebuf.C プロジェクト: LambdaCalculus379/SLS-1.02
int filebuf::underflow()
{
#if 0
    /* SysV does not make this test; take it out for compatibility */
    if (fp->_flags & __SEOF)
	return (EOF);
#endif

    if (xflags() & _S_NO_READS)
	return EOF;
    if (gptr() < egptr())
	return *(unsigned char*)gptr();
    allocbuf();

    // FIXME This can/should be moved to __streambuf ??
    if ((xflags() & _S_LINE_BUF) || unbuffered()) {
	// Flush all line buffered files before reading.
	streambuf::flush_all_linebuffered();
    }
#if 1
    if (pptr() > pbase())
	if (do_flush()) return EOF;
#endif

    _G_ssize_t count = sys_read(base(), ebuf() - base());
    if (count <= 0) {
	if (count == 0)
	    xsetflags(_S_EOF_SEEN);
	else
	    xsetflags(_S_ERR_SEEN), count = 0;
    }
    setg(base(), base(), base() + count);
    setp(base(), base());
    if (count == 0)
	return EOF;
    if (_fb._offset >= 0)
	_fb._offset += count;
    return *(unsigned char*)gptr();
}
コード例 #5
0
ファイル: filebuf.C プロジェクト: LambdaCalculus379/SLS-1.02
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;
}