Force the file mark to EOF whenever writing to a stream in append mode.

This is what the standards require. Note that the mark is only set to EOF when actually writing to the underlying file, not merely buffering data to write later. This is consistent with the usual POSIX implementation using O_APPEND.
This commit is contained in:
Stephen Heumann 2022-06-26 18:59:57 -05:00
parent 0047b755c9
commit 8cfb73a474
2 changed files with 68 additions and 31 deletions

View File

@ -63,6 +63,7 @@ _IOEOF gequ $0080 has an EOF been found?
_IOERR gequ $0100 has an error occurred? _IOERR gequ $0100 has an error occurred?
_IOTEXT gequ $0200 is this file a text file? _IOTEXT gequ $0200 is this file a text file?
_IOTEMPFILE gequ $0400 was this file created by tmpfile()? _IOTEMPFILE gequ $0400 was this file created by tmpfile()?
_IOAPPEND gequ $0800 is this file open in append mode?
! record structure ! record structure
! ---------------- ! ----------------

View File

@ -336,8 +336,9 @@ fa3 lda #EOF assume there is an error
jcs rts jcs rts
ldy #FILE_flag if the mode is not writing, quit ldy #FILE_flag if the mode is not writing, quit
lda [stream],Y lda [stream],Y
and #_IOWRT bit #_IOWRT
beq fl1 beq fl1a
tax
ldy #FILE_file set the reference number ldy #FILE_file set the reference number
lda [stream],Y lda [stream],Y
sta wrRefNum sta wrRefNum
@ -360,7 +361,12 @@ fa3 lda #EOF assume there is an error
sta wrRequestCount+2 sta wrRequestCount+2
ora wrRequestCount skip the write if there are no ora wrRequestCount skip the write if there are no
beq fl1 characters beq fl1 characters
OSwrite wr write the info txa
bit #_IOAPPEND if append mode, force to EOF
beq fa4
lda wrRefNum
jsr ~ForceToEOF
fa4 OSwrite wr write the info
bcc fl1 bcc fl1
ph4 stream ph4 stream
jsr ~ioerror jsr ~ioerror
@ -368,7 +374,7 @@ fa3 lda #EOF assume there is an error
fl1 ldy #FILE_flag if the file is open for read/write then fl1 ldy #FILE_flag if the file is open for read/write then
lda [stream],Y lda [stream],Y
bit #_IORW fl1a bit #_IORW
beq fl3 beq fl3
bit #_IOREAD if the file is being read then bit #_IOREAD if the file is being read then
beq fl2 beq fl2
@ -837,20 +843,14 @@ of2 lda fileType if the file type is 'w' then
lda opRefNum reset it lda opRefNum reset it
sta efRefNum sta efRefNum
OSSet_EOF ef OSSet_EOF ef
bcc ar1 allow "not a block device error" bra of4
cmp #$0058
beq ar1
bra errEIO flag the error
of3 cmp #'a' else if the file type is 'a' then of3 cmp #'a' else if the file type is 'a' then
bne ar1 bne ar1
lda opRefNum lda opRefNum
sta gfRefNum jsr ~ForceToEOF append to it
sta smRefNum of4 bcc ar1 allow "not a block device error"
OSGet_EOF gf append to it cmp #$0058
bcs errEIO bne errEIO flag any other error
move4 gfEOF,smDisplacement
OSSet_Mark sm
bcs errEIO
; ;
; allocate and fill in the file record ; allocate and fill in the file record
; ;
@ -926,7 +926,11 @@ ar6 ldy #FILE_flag
cpx #BIN cpx #BIN
beq ar6a beq ar6a
ora #_IOTEXT ora #_IOTEXT
ar6a sta [fileBuff],Y ar6a ldx fileType
cpx #'a'
bne ar6b
ora #_IOAPPEND
ar6b sta [fileBuff],Y
ldy #FILE_cnt no chars in buffer ldy #FILE_cnt no chars in buffer
lda #0 lda #0
sta [fileBuff],Y sta [fileBuff],Y
@ -978,15 +982,6 @@ opRefNum ds 2
opName ds 4 opName ds 4
opAccess ds 2 opAccess ds 2
gf dc i'2' GetEOF record
gfRefNum ds 2
gfEOF ds 4
sm dc i'3' SetMark record
smRefNum ds 2
smBase dc i'0'
smDisplacement ds 4
ef dc i'3' parameter block for OSSet_EOF ef dc i'3' parameter block for OSSet_EOF
efRefNum ds 2 efRefNum ds 2
dc i'0' dc i'0'
@ -1150,11 +1145,18 @@ of1a OSopen op open the file
of2 lda fileType if the file type is 'w', reset it of2 lda fileType if the file type is 'w', reset it
cmp #'w' cmp #'w'
bne ar1 bne of3
lda opRefNum lda opRefNum
sta efRefNum sta efRefNum
OSSet_EOF ef OSSet_EOF ef
bcs errEIO bra of4
of3 cmp #'a' else if the file type is 'a' then
bne ar1
lda opRefNum
jsr ~ForceToEOF append to it
of4 bcc ar1 allow "not a block device error"
cmp #$0058
bne errEIO flag any other error
; ;
; fill in the file record ; fill in the file record
; ;
@ -1209,7 +1211,11 @@ ar6 ldy #FILE_flag
cpx #BIN cpx #BIN
beq ar6a beq ar6a
ora #_IOTEXT ora #_IOTEXT
ar6a sta [fileBuff],Y ar6a ldx fileType
cpx #'a'
bne ar6b
ora #_IOAPPEND
ar6b sta [fileBuff],Y
ldy #FILE_cnt no chars in buffer ldy #FILE_cnt no chars in buffer
lda #0 lda #0
sta [fileBuff],Y sta [fileBuff],Y
@ -2029,10 +2035,10 @@ lb1 lda [ptr] write the bytes
ora wrRequestCount+2 ora wrRequestCount+2
bne lb1 bne lb1
move4 count,wrTransferCount set the # of elements written move4 count,wrTransferCount set the # of elements written
bra lb6 brl lb6
lb2 cmp #stderrID if the file is stderr then lb2 cmp #stderrID if the file is stderr then
bne lb6 jne lb6
lb3 lda [ptr] write the bytes lb3 lda [ptr] write the bytes
pha pha
jsl SYSCHARERROUT jsl SYSCHARERROUT
@ -2048,7 +2054,13 @@ lb4 sta wrRefNum set the reference number
ph4 stream purge the file ph4 stream purge the file
jsl fflush jsl fflush
move4 ptr,wrDataBuffer set the start address move4 ptr,wrDataBuffer set the start address
OSWrite wr write the bytes ldy #FILE_flag if append mode, force to EOF
lda [stream],Y
bit #_IOAPPEND
beq lb4a
lda wrRefNum
jsr ~ForceToEOF
lb4a OSWrite wr write the bytes
bcc lb5 bcc lb5
ph4 stream I/O error ph4 stream I/O error
jsr ~ioerror jsr ~ioerror
@ -6152,6 +6164,30 @@ ch ds 2 temp storage
~isVarArgs ds 2 is this a varargs call (vscanf etc.)? ~isVarArgs ds 2 is this a varargs call (vscanf etc.)?
end end
****************************************************************
*
* ~ForceToEOF - force file mark to EOF
*
* Inputs:
* A - GS/OS refNum for file
*
* Outputs:
* Carry set on GS/OS error, error code in A
*
****************************************************************
*
~ForceToEOF private
sta smRefNum
OSSet_Mark sm
rts
sm dc i'3' SetMark record
smRefNum ds 2
smBase dc i'1' EOF-displacement mode
smDisplacement dc i4'0' displacement = 0
end
**************************************************************** ****************************************************************
* *
* ~SetFilePointer - makes sure nothing is in the input buffer * ~SetFilePointer - makes sure nothing is in the input buffer