.title ftell Get file position for subsequent seek .ident /000004/ ; ;+ ; ; Index Get file position for subsequent seek ; ; Usage ; ; long ; ftell(iop); ; FILE *iop; /* What device to seek */ ; ; Description ; ; ftell() returns the position of the read/write pointer of ; the indicated file. This value may be fed back to the ; file system by calling fseek(). Note that the value is ; a pointer to the record, not a block or byte pointer. On RSX, ; the program should flush the current record before calling ftell(). ; (Flush() is a noop on RT11.) ; ; If reading lines of text, the correct sequence is: ; ; position = ftell(fd); ; if (fgets(buffer, sizeof buffer, fd) != EOF) { ; /* ; * 'position' locates the record ; * read by the call to fgets() ; */ ; } ; ; Make sure you declare ftell() ; ; extern long ftell(); ; ; If you do not, it will return garbage. ; ; Bugs ; ; On both systems, the value returned is the position of the file ; pointer (RFA), as a byte offset from the start of the file. ; Note, however, that on RSX systems the pointer is to the start ; of the current record. It is not necessarily the case that ; the start of a text line equates to the start of a record. ; RSX supports many file record formats, including Fortran, ; print_file and "unformatted" (with embedded control ; information). The latter files may have multiple text lines ; embedded in each record. This is handled internally by ; the formatted read routines (i.e., fgets() and getc()). ; On RSX, the only way to be certain of the exact record/line ; correspondance is to use the fget() and fput() functions. ; The T utility program (in the tools library) shows another ; method of handling this problem. ; ; On RSTS/E RT11 mode, ftell will not process "large" files ; (with more than 65535 blocks) correctly. ; ;- ; ; Edit history ; 000001 13-Mar-80 MM Initial edit ; 000002 29-Jul-80 MM Nothing like debugging ; 000003 01-Aug-80 MM Track IOV change ; 000004 29-Jun-82 MM Newer library, new rt11 ftell ; .iif ndf rsx rsx = 1 ;Assume rsx11m .psect c$code ftell:: jsr r5,csv$ mov c$pmtr+0(r5),r4 ;r4 -> iop .if ne rsx ;01 mov r4,r0 ;r0 -> fdb add #v$fdb,r0 ;now it does call .mark ;Get fcs position: ;r1 high-order bits of vbn ;r2 low-order bits of vbn ;r3 next byte in this block bit #vf$fil,v$flag(r4) ;A file device? ;04 beq 10$ ;no, a true disk sub #1,r2 ;fix block number sbc r1 ;both halves. 10$: .iff ;04+ clr r1 ;(No high-order block number) tst v$bptr(r4) ;Live buffer? bne 5$ ;Br if so. clr r0 ;Nope, empty file is at [0,0] br 30$ ;take common exit 5$: mov v$bptr(r4),r3 ;Get offset to sub v$base(r4),r3 ;current free byte. mov v$bnbr(r4),r2 ;Here's the low-order block number bit #VF$WRT,v$flag(r4) ;Writing? bne 10$ ;yes, got the right block dec r2 ;reading -- block is off by 1 10$: .endc ;04- mov #9.,r0 ;shift 20$: asl r2 ;vbn rol r1 ;left dec r0 ;nine bgt 20$ ;bits add r3,r2 ;Then add in byte pointer adc r1 ;Both halves. mov r1,r0 ;return a long mov r2,r1 ;in the right place. 30$: ;Jump here for RT11 rewind ;04 jmp cret$ ;and back we go. .end