int _tmf_bksp(struct fdinfo *fio, struct ffsw *stat) { struct tmfio *xf_info; register int ret; int usertm; xf_info = (struct tmfio *)fio->lyr_info; if (xf_info->tmf_tpos) { if (_tmf_tpwait (xf_info) < 0) { ERETURN(stat, errno, 0); } } /* * If the file's been writing, flush out any unwritten data. */ if (xf_info->rwflag == WRITIN) { if (_tmf_flush(fio, stat) < 0) { return(ERR); } } /* * Now backspace. */ ret = _tmf_stpos(fio, FP_TPOS_BACK, 1, 0, 0, 0, &usertm, stat); if (ret < 0 && stat->sw_error != ETBOF) return(ERR); xf_info->rwflag = POSITIN; return(0); }
/* * _tmf_closev - Switches tape volume * * returns: * 0 OK * -1 error (errno is set) */ int _tmf_closev(struct fdinfo *fio, struct ffsw *st) { tmfreqhdr_t ctl; struct tmfio *xfinfo; xfinfo = (struct tmfio *)fio->lyr_info; if (xfinfo->tmf_tpos){ if (_tmf_tpwait(xfinfo) < 0){ return(ERR); } } /* * If the file's been writing, flush out data. * If we've been reading, clear out any unread data. */ if (_tmf_flush(fio, st) < 0){ return(ERR); } bzero(&ctl, sizeof(tmfreqhdr_t)); ctl.request = TR_CLV; if(ioctl(xfinfo->tmf_fd, TMFC_DMNREQ, &ctl) <0) { ERETURN(st, errno, 0); } if (ctl.reply != 0) { ERETURN(st, ctl.reply, 0); } return(0); }
/* * Write an EOF. * If we can write a tape mark, do so. * Otherwise, return an error. */ int _tmf_weof(struct fdinfo *fio, struct ffsw *stat) { register int ret; struct tmfio *xfinfo; tmfwfm_t ctl; xfinfo = (struct tmfio *)fio->lyr_info; if (xfinfo->tmf_rwtpmk == 0) ERETURN(stat, FDC_ERR_NWEOF, 0); if (xfinfo->rwflag == READIN) { /* * Issue an error if we are not positioned at a record * boundary. ffweof would terminate the current record, but * _cos_write overwrites the current record. We need to * decide which is the proper approach before permitting this * here. */ if (xfinfo->tmf_base != xfinfo->tmf_bufptr) { _SETERROR(stat, FDC_ERR_NOTREC, 0); return(ERR); } ret = _tmf_wrard(fio, stat); if (ret < 0) return(ERR); } if(_tmf_flush(fio, stat) == ERR) { return(ERR); } xfinfo->rwflag = WRITIN; (void) memset(&ctl, 0, sizeof(ctl)); ctl.rh.request = TR_WFM; ctl.rh.length = sizeof(tmfwfm_t) - sizeof(tmfreqhdr_t); ctl.count = 1; ret = ioctl(xfinfo->tmf_fd, TMFC_DMNREQ, &ctl); if (ret < 0) { if (xfinfo->tmf_eovon && !xfinfo->tmf_speov) { /* The user has enabled eov processing */ /* Determine whether we hit EOV */ if (errno == ENOSPC) { /* This is eov */ /* We need to save away the */ /* unwritten tapemark */ /* and set a flag so we can */ /* tell the user eov was reached. */ /* This user's write will return a good status */ xfinfo->tmf_eovhit = 1; xfinfo->tmf_tpmk = 1; xfinfo->tmf_bufptr = xfinfo->tmf_base; xfinfo->tmf_cnt = 0; return(0); } } ERETURN(stat, errno, 0); } SETSTAT(stat, FFEOF, 0); return(0); }
/* * Get tape position * Parameters: * fio - fdinfo ptr for this file * pa - an array of 64-bit words. Tape info is * returned here. * palen - number of 64-bit words in pa * synch - unused now. Kept for compatibility? with Unicos * * Returns: 0 if OK * -1 if error (errno is set) */ int _tmf_gtpos(struct fdinfo *fio, long long *pa, int palen, int synch) { register short partial; int lib; struct tsdata tsdata; struct tmfio *xf_info; char vsn[MAXVSN][L_MAXVSN]; xf_info = (struct tmfio *)fio->lyr_info; if ( xf_info->tmf_tpos ) { if ( _tmf_tpwait( xf_info) < 0) return(ERR); } /* * If previous i/o request was a write request make sure the list * is flushed before getting the position. */ partial = 0; if ( xf_info->rwflag == WRITIN ) { if (xf_info->tmf_bufptr != xf_info->tmf_base){ /* If we just wrote part of a record */ /* don't try to flush to tape */ partial = 1; } else { /* This could cause us to hit eov */ if (_tmf_flush(fio, stat) < 0) return(ERR); } } lib = 0; if (xf_info->rwflag == READIN) { /* * If we were reading, count the blocks that are in the * library's buffer. */ /* JAS: Should we count partial blocks?? */ /* Without read-ahead, there will be no blocks in */ /* the library's buffer */ } /* If we've seen eov, but we haven't started eov processing, */ /* then count up how many blocks we have buffered */ if (xf_info->tmf_eovhit && (xf_info->tmf_speov == 0)){ /* Count blocks in the library buffer. */ /* Without write behind, the buffered data is either */ /* a single full block or a single partial block */ partial = xf_info->tmf_partblk; if (partial == 0 && xf_info->eovbytes != 0) lib = 1; } if ( _tmf_tptsi (xf_info, &tsdata, vsn) != 0) return(ERR); __gtpos(&tsdata, vsn, lib, partial, pa, palen); return(0); }