.title fseek Reposition file pointer (seek) .ident /000009/ ; ;+ ; ; Index Reposition file pointer (seek) ; ; Usage ; ; fseek(iop, offset, param); ; FILE *iop; /* What device to seek */ ; long offset; /* New read position */ ; int param; /* Zero for abs. seek */ ; ; Description ; ; fseek() moves the file pointer to the indicated position. ; The position must have been returned by ftell() or equal ; zero for rewind. Param must be zero. The file/device must ; be seekable. ; ; fseek() returns zero if correct, EOF if an error occurs. ; If no error occurred, error and eof flags are reset. ; ; flseek() is an alternate entry with identical parameters ; and actions. ; ; Note that on RSX, fseek() can be used to open a file for ; update by a sequence such as: ; ; fd = fopen("file.nam", "a"); ; fseek(fd, 0L, 0); /* Rewind file */ ; ; If the file was opened on RSX using the 'n' mode switch, it will ; be opened using file attributes "fixed 512-byte records with ; no carriage control". The offset pointer is thus ; a virtual byte number and fseek may be used to freely reposition ; the file pointer. ; ; Bugs ; ;- ; ; Edit history ; 000001 13-Mar-80 MM Initial edit ; 000002 27-Jun-80 MM $$get returns -1 on error ; 000003 01-Aug-80 MM Track IOV change ; 000004 05-Mar-81 RBD Clear V$BCNT to force a new read ; 000005 17-Jun-81 RBD ... but only on RSX ; 000006 25-Aug-81 RBD Allow seek on writeable rsx files ; 000007 29-Jun-82 MM New library, use virtual byte pointer for rt11 ; 000008 03-Aug-82 MM Painfully dumb typo ; 000009 29-Sep-82 MM Changed buffer busy test ; .iif ndf rsx rsx = 1 ;Assume rsx11m .psect c$code flseek:: fseek:: jsr r5,csv$ mov C$PMTR+0(r5),r4 ;r4 -> iop mov #-1,r0 ;expect the worst tst C$PMTR+6(r5) ;parameter = 0? bne 40$ ;nope, die. ;07 .if ne rsx bit #VF$REC,V$FLAG(r4) ;will it seek? ;03/06/07 bne 40$ ;nope, can't seek. ;07 bit #VF$WRT,V$FLAG(r4) ;is it open for write/append ;06+/07 beq 5$ ;no, continue bisb #FD.INS,F.RACC+V$FDB(r4) ;yes, set "don't truncate" 5$: ;main sequence ;06- mov C$PMTR+2(r5),r1 ;r1 := high-order vbn mov C$PMTR+4(r5),r2 ;r2 := low-order vbn mov r2,r3 ;r3 := byte offset in block bic #^C777,r3 ;now it does mov #9.,r0 ;do a long shift 10$: asr r1 ;of the ror r2 ;long block dec r0 ;number bgt 10$ ; bit #VF$FIL,V$FLAG(r4) ;File or device ;07 beq 20$ ;Br if device add #1,r2 ;File, make origin adc r1 ;1 20$: mov r4,r0 ;r0 -> fdb add #V$FDB,r0 ;now it does call .point ;seek away clr V$BCNT(r4) ;force $$get to read the record ;04/05 clr r0 ;Normal return ;07 .iff ; ; RT11 ; bit #VF$REC+VF$TTY+VF$WRT,V$FLAG(r4) ;will it seek? ;03/07 bne 40$ ;not a chance ;07 ; ; Make sure there's a buffer to read into. ; tst V$BASE(r4) ;Already set a buffer? ;07+ bne 3$ ;yup. ;08 call $$abuf ;allocate a default buffer bcc 3$ ;continue if ok com r0 ;return -1 br 40$ ;and exit 3$: ;07- ; ; Since this is a stream i/o package, we don't bother to ; check the busy bit and flush the current buffer. ; mov C$PMTR+2(r5),r1 ;High order byte offset ;07+ mov C$PMTR+4(r5),r0 ;Low order byte offset mov r0,r3 ;Grab a copy bic #^C777,r3 ;r3 has buffer offset mov #9.,r2 ;Shift counter 5$: asr r1 ;Long shift ror r0 ; to locate the dec r2 ; block bgt 5$ ; number tst V$BCNT(r4) ; Is the buffer empty? ;09/07- beq 10$ ;Yes, always read inc r0 ;Check against current (i.e. next) block cmp r0,V$BNBR(r4) ;Trying to get the block that's in? beq 20$ ;Yes, skip the read dec r0 ;No, reget the correct number ; 10$: call $$get ;Go for it tst r0 ;ok return? bmi 40$ ;no, die. ;02 ; 20$: mov V$RBSZ(r4),V$BCNT(r4) ;Setup free count sub r3,V$BCNT(r4) ;Load free count ;07+ add V$BASE(r4),r3 ;Load free pointer mov r3,V$BPTR(r4) ;and put it away. ;07- ; .endc ; ; Normal return ; bic #VF$EOR,V$FLAG(r4) ;Clear error and eof flags ;07 ; 40$: jmp cret$ ;back we go. .end