Exemplo n.º 1
0
/*
 *
 * 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);	
}
Exemplo n.º 2
0
/*
 * 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);
}
Exemplo n.º 3
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);
			   }
			   }