示例#1
0
/*
 * Set up a file stream on an OS file.  The caller has allocated the
 * stream and buffer.
 */
void
file_init_stream(stream *s, FILE *file, const char *fmode, byte *buffer,
		 uint buffer_size)
{
    switch (fmode[0]) {
    case 'a':
	sappend_file(s, file, buffer, buffer_size);
	break;
    case 'r':
	/* Defeat buffering for terminals. */
	{
	    struct stat rstat;

	    fstat(fileno(file), &rstat);
	    sread_file(s, file, buffer,
		       (S_ISCHR(rstat.st_mode) ? 1 : buffer_size));
	}
	break;
    case 'w':
	swrite_file(s, file, buffer, buffer_size);
    }
    if (fmode[1] == '+')
	s->file_modes |= s_mode_read | s_mode_write;
    s->save_close = s->procs.close;
    s->procs.close = file_close_file;
}
示例#2
0
/* Switch a file stream to reading or writing. */
static int
s_fileno_switch(stream * s, bool writing)
{
    uint modes = s->file_modes;
    int fd = sfileno(s);
    long pos;

    if (writing) {
        if (!(s->file_modes & s_mode_write))
            return ERRC;
        pos = stell(s);
        if_debug2('s', "[s]switch 0x%lx to write at %ld\n",
                  (ulong) s, pos);
        lseek(fd, pos, SEEK_SET);	/* pacify OS */
        if (modes & s_mode_append) {
            sappend_file(s, s->file, s->cbuf, s->cbsize);  /* sets position */
        } else {
            swrite_file(s, s->file, s->cbuf, s->cbsize);
            s->position = pos;
        }
        s->modes = modes;
    } else {
        if (!(s->file_modes & s_mode_read))
            return ERRC;
        pos = stell(s);
        if_debug2('s', "[s]switch 0x%lx to read at %ld\n",
                  (ulong) s, pos);
        if (sflush(s) < 0)
            return ERRC;
        lseek(fd, 0L, SEEK_CUR);	/* pacify OS */
        sread_file(s, s->file, s->cbuf, s->cbsize);
        s->modes |= modes & s_mode_append;	/* don't lose append info */
        s->position = pos;
    }
    s->file_modes = modes;
    return 0;
}