/* * * Perform a seek operation on a buffered file. * * Parameters: * fio - fdinfo pointer * pos - requested byte offset * whence - SEEK_SET, SEEK_CUR, or SEEK_END * stat - status return word * * Return value: * * The new byte postion in the file. * If an error occurs, -1 is returned, and the stat->sw_error field is * set. */ _ffseek_t _sqb_seek(struct fdinfo *fio, off_t pos, int whence, struct ffsw *stat) { _ffseek_t ret; struct sqb_f *sqb_info; int sync = 0; struct fdinfo *llfio; sqb_info = (struct sqb_f *)fio->lyr_info; llfio = fio->fioptr; /* We could probably do more record keeping, and */ /* determine whether the desired position was already */ /* in our buffers. */ /* Wait for outstanding I/O */ if (fio->rwflag == READIN || fio->rwflag == POSITIN) { if (whence == SEEK_CUR) sync = 1; /* synchronize physical and logical */ /* positions */ if (_sqb_sync(fio, stat, sync) < 0) { return(ERR); } } else if (fio->rwflag == WRITIN) { if (_sqb_flush(fio, stat) < 0) { return(ERR); } } fio->rwflag = POSITIN; ret = XRCALL(llfio, seekrtn) llfio, pos, whence, stat); return(ret); }
/* * Write an EOF to a buffer-layer file. * */ int _sqb_weof(struct fdinfo *fio, struct ffsw *stat) { struct fdinfo *llfio; if (fio->rwflag == WRITIN) { if (_sqb_flush(fio, stat) < 0) { return(ERR); } } else if (fio->rwflag == READIN || fio->rwflag == POSITIN) { /* synchronize physical position with logical */ if (_sqb_sync(fio, stat, 1) < 0) { return(ERR); } } fio->rwflag = WRITIN; /* * Tell the underlying layer to write an EOF */ llfio = fio->fioptr; if (XRCALL(llfio,weofrtn) llfio, stat) == ERR) return(ERR); SETSTAT(stat, FFEOF, 0); return(0); }
int _sqb_pos(struct fdinfo *fio, int cmd, long *arg, int len, struct ffsw *stat) { int ret = 0; struct sqb_f *sqb_info; struct sqbio *sqbptr; struct sqbio *sqborig; struct sqbio *s; struct fdinfo *llfio; int found = 0; int nbits; int sync = -1; llfio = fio->fioptr; sqb_info = (struct sqb_f *)fio->lyr_info; if (fio->rwflag == WRITIN) { /* flush buffers and wait for outstanding I/O to finish. */ if (_sqb_flush(fio, stat) < 0) { return(ERR); } } switch(cmd) { /* For now, this is not supported on SGI systems. */ /* We need to work out what "arg" should be. */ #if !defined(__mips) && !defined(_LITTLE_ENDIAN) case FP_RSEEK: if ((fio->rwflag == READIN) || (fio->rwflag == POSITIN)) { if (*arg < 0) { /* Seeking backwards */ /* Are we seeking within the current */ /* buffer? */ sqbptr = sqb_info->sqbio_cur; if (sqbptr->status == IOACTIVE) { while (sqbptr->iostat.sw_flag == 0 || sqbptr->iostat.sw_stat == 0) { ret = XRCALL(llfio,fcntlrtn) llfio, FC_RECALL, &(sqbptr->iostat), stat); if (ret < 0) { return(ERR); } } if (FFSTAT(sqbptr->iostat) == FFERR) { ERETURN(stat, sqbptr->iostat.sw_error,0); } sqbptr->_cnt = sqbptr->iostat.sw_count<<3; sqbptr->status = IODATA; } if (sqbptr->status == IODATA) { nbits = -(*arg); /* convert to positive */ nbits = nbits<<3; if (nbits <= SUBT_BPTR(sqb_info->_ptr,sqbptr->_base)){ SET_BPTR(sqb_info->_ptr, INC_BPTR(sqb_info->_ptr,-nbits)); sqbptr->_cnt += nbits; break; } } } else { /* seeking forward */ /* Any chance that the position would be in */ /* our buffers? */ nbits = *arg << 3; if (nbits > sqb_info->nbuf * sqb_info->bufsiz){ /* won't be in any of the buffers */ goto a1; } sqbptr = sqb_info->sqbio_cur; sqborig = sqbptr; do { if (sqbptr->status == IOACTIVE) { while (sqbptr->iostat.sw_flag == 0 || sqbptr->iostat.sw_stat == 0) { ret = XRCALL(llfio,fcntlrtn) llfio, FC_RECALL, &(sqbptr->iostat), stat); if (ret < 0) { return(ERR); } } if (FFSTAT(sqbptr->iostat) == FFERR) { ERETURN(stat, sqbptr->iostat.sw_error,0); } sqbptr->_cnt = sqbptr->iostat.sw_count<<3; sqbptr->status = IODATA; } if (sqbptr->status == IODATA) { if (nbits <= sqbptr->_cnt) { /* Desired position is in this buffer */ sqbptr->_cnt -= nbits; /* Clear out buffers that preceeded this */ s = sqborig; for (; s != sqbptr; s= s->nxt) { s->status = EMPTY; CLRFFSTAT(s->iostat); } sqb_info->sqbio_cur = sqbptr; if (sqbptr != sqborig) sqb_info->_ptr = sqbptr->_base; SET_BPTR(sqb_info->_ptr, INC_BPTR(sqb_info->_ptr,nbits)); found = 1; break; } else { nbits -= sqbptr->_cnt; } } else goto a1; /* all out of data */ sqbptr = sqbptr->nxt; } while (sqbptr != sqborig); } }