/* * 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); }
/* * * 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); }
/* * * Description: * writes nbytes bytes, with *ubc unused bits, from bufptr to * the next lower layer. * Parameters: * fio - Pointer to fdinfo block * bufptr - bit pointer to user's data * nbytes - Number of bytes to be written * stat - pointer to status return word * fulp - full or partial write mode flag * ubc - pointer to unused bit count * Returns: * number of bytes written * -1 if error */ ssize_t _sqb_write( struct fdinfo *fio, bitptr bufptr, size_t nbytes, struct ffsw *stat, int fulp, int *ubc) { int ret; int bs, btomove; uint64 nbits; ssize_t moved; struct sqb_f *sqb_info; struct fdinfo *llfio; struct ffsw locstat; struct sqbio *sqbptr; int zero = 0; nbits = ((uint64)nbytes << 3) - *ubc; sqb_info = (struct sqb_f *)fio->lyr_info; llfio = fio->fioptr; moved = 0; if (fio->rwflag == READIN || fio->rwflag == POSITIN) { /* synchronize physical position with logical position */ if (_sqb_sync(fio, &locstat, 1) < 0) { goto erret; } } fio->rwflag = WRITIN; bs = sqb_info->bufsiz>>3; sqbptr = sqb_info->sqbio_cur; while (nbits != 0) { if (sqbptr->status == IOACTIVE) { /* wait for the outstanding asynch i/o to complete */ while (sqbptr->iostat.sw_flag == 0 || sqbptr->iostat.sw_stat == 0) { ret = XRCALL(llfio,fcntlrtn) llfio, FC_RECALL, &(sqbptr->iostat), &locstat); if (ret < 0) { goto erret; } } if (sqbptr->iostat.sw_error != 0) { ERETURN(stat, sqbptr->iostat.sw_error, 0); } if (sqbptr->iostat.sw_count != sqbptr->_iowritten) { ERETURN(stat, FDC_ERR_WRTERR, 0); } sqbptr->status = EMPTY; sqbptr->_cnt = sqb_info->bufsiz; CLRFFSTAT(sqbptr->iostat); } if (sqbptr->status == EMPTY) { sqbptr->_cnt = sqb_info->bufsiz; } /* * Move data from user to buffer */ btomove = MIN(nbits, sqbptr->_cnt); MOV_BITS(sqb_info->_ptr, bufptr, btomove); SET_BPTR(bufptr, INC_BPTR(bufptr, btomove)); nbits -= btomove; sqbptr->_cnt -= btomove; sqbptr->status = IODATA; if (sqbptr->_cnt == 0) { /* no room left in this buffer; start I/O on it */ CLRFFSTAT(sqbptr->iostat); sqbptr->_iowritten = bs; if( XRCALL(llfio, writeartn) llfio, sqbptr->_base,(size_t) bs, &(sqbptr->iostat), FULL, &zero) < 0) { ERETURN(stat, sqbptr->iostat.sw_error, (moved +7) >> 3); } sqbptr->status = IOACTIVE; sqb_info->sqbio_cur = sqb_info->sqbio_cur->nxt; sqbptr = sqb_info->sqbio_cur; sqb_info->_ptr = sqb_info->sqbio_cur->_base; } else {