.Title Shared File Record Locking ; This set of routines provides shared file record ; locking extensions to the standard DECUS C file ; i/o library. The functions are: ; ; VOID frcdlock(blknum,fp) lock a record ; VOID frcdunlock(blknum,fp) unlock a record ; VOID frcdread(bufr,blknum,fp) read a record ; VOID frcdwrite(bufr,blknum,fp) write a record ; ; A record is 1 block (512 bytes) of data. ; ; No normal fread() or fwrite() operations ; should be performed, only the fopen() for ; read and fclose() should be performed. ; ; ; The normal sequence to perform an update on a ; shared record is: ; ; (1) open file for read fp = fopen(filespec,"r"); ; ; (2) lock a block frcdlock(blknum,fp); ; (3) read the block frcdread(bufr,blknum,fp); ; (4) do updates on data block ; (5) write the block frcdwrite(bufr,blknum,fp); ; (6) unlock the block frcdunlock(blknum,fp); ; ; (7) repeat steps (2)-(6) as needed ; ; (8) close file fclose(fp); ; ; ; These routines make the assumption that the ; shared-file support has been sysgened into TSX+. ; If this is not the case, then these calls ; are noops and record locking does not occur. ; ; DECUS C Calling Format ; ; jsr r5,csv$ ;save r2,r3, and r4 ; ;r5 is parameter base ; ;c$pmtr(r5) is first argument ; ;c$pmtr+2(r5) is second argument ; ;... ; ;return args in r0 ; ... ; user code ; ... ; ; jmp cret$ ;restore r2-r5 and return ; rts pc ;does the same (cret$ follows csv$) ; ; csv$ and cret$ need be used only if arguments are used ; .include "os.mac" .mcall .readw .writw .page .sbttl DECUS C File I/O block structure ; typedef struct IOV { /* From DECUS C STDIO.H */ ; int _cnt; /* Bytes left in buffer */ ; char *_ptr; /* Free spot in buffer */ ; char *_base; /* Base of buffer */ ; int _flag; /* Flag word */ ; int io_wflag; /* Wild card flags */ ; char *io_wild; /* Wild card buffer */ ; int io_rbsz; /* Record buffer size */ ; /* ; * RT11 specific ; */ ; int io_lun; /* RT11 unit number */ ; int io_bnbr; /* Disk block number */ ; int io_size; /* File size in blocks */ ; char *io_name; /* File name pointer */ ; char io_dbuf[2]; /* Dummy record buffer */ ; } FILE; ; /* ; * Bits in ((FILE *)fd)->_flag: ; * _NAME Compatible with Unix usage ; * IO_NAME Decus C specific. ; */ ; #define _IOREAD 0000001 /* Open for reading */ ; #define _IOWRT 0000002 /* Open for writing */ ; #define _IONBF 0000004 /* Unbuffered "u" mode */ ; #define _IOMYBUF 0000010 /* io stuff got buffer */ ; #define _IOEOF 0000020 /* Eof seen if set */ ; #define _IOERR 0000040 /* Error seen if set */ ; #define _IOSTRG 0000100 /* for sprintf, sscanf */ ; #define _IORW 0000200 /* Open for read/write */ ; /* ; * Bits in fd->_flag (all in high byte of that word) ; * These are needed for Dec-style i/o. ; */ ; #define IO_BZY 0000400 /* Buffer busy (RT11) */ ; #define IO_APN 0001000 /* Append mode open */ ; #define IO_NOS 0002000 /* No newlines needed */ ; #define IO_NEWL 0004000 /* RSX TTY newline hack */ ; #define IO_FIL 0010000 /* Disk file */ ; #define IO_TTY 0020000 /* Console terminal */ ; #define IO_REC 0040000 /* Record device */ ; #define IO_OPN 0100000 /* Open file */ ; /* ; * The following bits are set in fd->io_wflag for wild-card ; * processing. Note: IO_WLD must be in the low byte. ; */ ; #define IO_WLD 0000001 /* fwild: wildcard file */ ; #define IO_VM1 0000002 /* fwild: version ;-1 */ ; #define IO_VER 0000004 /* fwild: ;0 or ;-1 */ ; #define IO_WF1 0000010 /* fwild first flag */ ; #define IO_NLH 0000020 /* fopen 'n' hack bit */ .page .sbttl IOV Structure Offsets $cnt = 0 $ptr = 2 $base = 4 $flag = 6 io$wflag= 10 io$wild = 12 io$rbsz = 14 io$lun = 16 io$bnbr = 20 io$size = 22 io$name = 24 io$dbuf = 26 .sbttl frcdlock(blknum,fp) .psect c$code frcdlock:: .if ne ts$sys ; tsx-plus specific jsr r5,csv$ mov c$pmtr+2(r5),r1 ; IOV pointer movb io$lun(r1),lock1$ ; channel number mov #lock1$,r0 ; set file for shared (updating) emt 375 movb io$lun(r1),lock2$ ; channel number mov c$pmtr(r5),lock3$ ; block number mov #lock2$,r0 ; wait and lock record emt 375 .endc rts pc ; exit when locked .psect c$data .if ne ts$sys ; tsx-plus specific lock1$: .byte 0,125 ; shared update .word 5 lock2$: .byte 0,102 ; lock a record lock3$: .word 0 .endc .sbttl frcdunlock(blknum,fp) .psect c$code frcdunlock:: .if ne ts$sys ; tsx-plus specific jsr r5,csv$ mov c$pmtr+2(r5),r1 ; IOV pointer movb io$lun(r1),unlo1$ ; channel number mov c$pmtr(r5),unlo2$ ; block number mov #unlo1$,r0 ; unlock record emt 375 .endc rts pc .psect c$data .if ne ts$sys ; tsx-plus specific unlo1$: .byte 0,113 ; unlock a record unlo2$: .word 0 .endc .page .sbttl frcdread(blknum,fp) .psect c$code frcdread:: jsr r5,csv$ mov c$pmtr+4(r5),r1 ; IOV pointer .readw #argblk,io$lun(r1),c$pmtr(r5),#256.,c$pmtr+2(r5) rts pc .sbttl frcdwrite(blknum,fp) .psect c$code frcdwrite:: jsr r5,csv$ mov c$pmtr+4(r5),r1 ; IOV pointer .writw #argblk,io$lun(r1),c$pmtr(r5),#256.,c$pmtr+2(r5) rts pc .psect c$data argblk: .blkw 5 ; argument area .end