Opened 7 years ago

Closed 5 years ago

#195 closed defect (fixed)

tape_mult_ doesn't set nread to zero when returning error_table_$end_of_info

Reported by: dmw.technical@… Owned by: Gary Dixon
Priority: minor Milestone: MR12.7
Component: Hardcore Version: MR12.6f
Keywords: MST tape_mult_ Cc:

Description

This issue was described on dps8m-users on Dec 6, 2019.

The following program elicits and diagnoses the error. See comments for instructions:
&version 2
&trace &all_types off

&- tryit28.ec -- an exec_com program to demonstrate a
&- problem w/ tape_mult_. The problem is that the get_chars
&- entry does not set the status code to zero once an end of
&- file has been detected (191208)

&- To run this test program:
&- 1) Create an MST tape, however it might be convenient. The
&- tape should be reasonably short, less than 500k bytes.
&- 2) Edit this program so that TAPELABEL is set to the label
&- name of the MST tape.
&- 3) Run this program. If it detects the relevant error, it
&- will signal INVALID_RETURN_VALUE_FROM_IOX_GET_CHARS (or
&- actually, the first 32 chars of that name). Otherwise,
&- is should complete without complaint.

&set TAPELABEL "tmp/CARRY"

&on cleanup
&begin
&- &print In cleanup handler. Doing non-local &&goto.

&if &[io_call attached S]
&then &do

&if &[io_call opened S]
&then io_call close S
io_call detach S

&end
io_call close S
io_call detach S

&end

&- &trace &all
&if &[io_call attached S]
&then &do

&if &[io_call opened S]
&then io_call close S
io_call detach S

io_call attach S tape_mult_ &(TAPELABEL)
io_call open S stream_input
io_call get_chars S 800000 -segment &[pd]>foo 0

&- That should have positioned the tape at EOF (for
&- any tape w/ less than 800 KiB.

&print &[io_call find_iocb S]
&set SIOCBPTR &[io_call find_iocb S]
&- &print &(SIOCBPTR)

&- Verify that we've actually reached EOF.

&set errcode &[call iox_$get_chars -input &(SIOCBPTR) -input "abc" -addr "char(1000)" -input 1000 -input 9999 -output -code -return]
&print errcode = &(errcode)
&if &[not &[equal &(errcode) error_table_$end_of_info]]
&then signal UNEXPECTED_STATUS_CODE_FROM_IOX_GET_CHARS

&set n_read &[call iox_$get_chars -input &(SIOCBPTR) -input "abc" -addr "char(1000)" -input 1000 -inout 9999 -return -input 0]
&print n_read = &(n_read)
&if &[not &[nequal &(n_read) 0]]
&then signal INVALID_RETURN_VALUE_FROM_IOX_GET_CHARS

io_call close S
io_call detach S

&quit

&end

Change History (6)

comment:1 by Gary Dixon, 7 years ago

Owner: changed from Eric Swenson to Gary Dixon
Status: newaccepted

comment:2 by Gary Dixon, 7 years ago

MCR10071 entered to resolve this defect:

This MCR is to fix tape_mult_ get_chars routine to always zero the number of 
characters read by the call before reading starts.  If called when EOT (end-of-tape)
has been reached, the Lcallers_buffer parameter is currently unset, which is
contrary to iox_$get_chars requirements.  See ticket:
   http://multics-trac.swenson.org/ticket/195

comment:3 by Gary Dixon, 7 years ago

The following test exec_com was used to create a test tape, then test for the bug reported in this ticket. It is based on the exec_com included in the initial ticket description, with changes to eliminate used of the io_call command/AF.

                    tape_mult_read_test.ec        01/23/20  1223.0 pdt Thu


&version 2
&trace &all_types off
&-
&- To run this test program:
&- 1) Edit this ec to set TAPELABEL (ec variable below)
&-    to the label name of a new Multics standard tape.
&- 2) Create a Multics standard tape, using the write operation.
&-    of this exec_com.
&-    Tape should be reasonably short.  Test file referenced by
&-    this exec_com is 10000 chars long.  To use your own test
&-    file, set the TESTFILE (ec variable below).
&- 3) After tape is created, run tests using the read operation
&-    of this exec_com.
&-
&- Usage:  ec test write
&-   OR:   ec test read {PARTIAL|FULL}
&-
&-
&goto INITIALIZE_&(1)
&-
&-
&label INITIALIZE_write
&label INITIALIZE_read
&-
&set TAPELABEL "GCD001"
&set TESTFILE &[directory &ec_path]>test_file.txt
&-
&-         Establish cleanup handler to detach tape if condition is signalled.
&on cleanup &begin
    &print &"test.ec cleanup handler: detaching switch S for tape:" &(TAPELABEL)
&-
    &if &[io_call look_iocb S]
    &then &do
&-
        &if &[io_call attached S]
        &then &do
&-
            &if &[io_call opened S]
            &then io_call close S
&-
            io_call detach S
            &end
        &end
    &end
&-
&trace &command &expanded
&-
&-
&-        Make sure switch S is detached
&if &[io_call look_iocb S]
&then &do
&-
    &if &[io_call attached S]
    &then &do
&-
        &if &[io_call opened S]
        &then io_call close S
&-
        io_call detach S
        &end
    &end
&-
&-
&-        Both write and read operations begin by attaching switch S to TAPELABEL

&-
&-        Split to do different things for read and write operations.
&goto DO_&(1)
&-
&-
&label DO_write
io_call attach S tape_mult_ &(TAPELABEL) -write
&-
io_call open S stream_output
&-
&if &[io_call opened S]
&then &do
    io_call put_chars S -segment &r(TESTFILE)
    io_call close S
    io_call detach S
    &end
&-
&quit

&label DO_read
&-
&set L_TESTFILE &[divide [status -bc &(TESTFILE)] 9]
&set L_BUFFER   2500
&if &[equal -&(2)- -PARTIAL-]
&then &set L_BUFFER 2900
&-
&set S_IOCBPTR &[io_call find_iocb S]
&-
&print L_TESTFILE &(L_TESTFILE)
&print L_BUFFER &(L_BUFFER)
&print S_IOCBPTR &(S_IOCBPTR)
&-
io_call attach S tape_mult_ &(TAPELABEL)
&-
io_call open S stream_input
&-
&if &[io_call opened S]
&then &do
    &set READ 0

&-        This read loop should position the tape at EOF (if FULL was given or defaulted),
&-        or just before last string on the tape (if PARTIAL was given).
&label READ_LOOP
    &print &""
    &print &""
    call iox_$get_chars -in &(S_IOCBPTR)
&+ -inout "" -id buff_ptr -addr "char(n)"
&+ -in &(L_BUFFER) -id n
&+ -inout 9999 -id n_read
&+ -out -id code -code
&-
    &set READ [plus &(READ) &(L_BUFFER)]
    &if &[nless &(READ) &(L_TESTFILE)]
    &then &goto READ_LOOP
&-
&-        Perform one more read operation to see how error_table_$end_of_information is handled.
    &print &""
    &print &""
    call iox_$get_chars -in &(S_IOCBPTR)
&+ -inout "" -id buff_ptr -addr "char(n)"
&+ -in &(L_BUFFER) -id n
&+ -inout 9999 -id n_read
&+ -out -id code -code
&-
    io_call close S
    io_call detach S
    &end

&quit

&label INITIALIZE_&(1)
&if &[equal -&(1)- --]
&then &print &"ERROR: Missing operation"
&else &print &"ERROR: Unsupported operation: " &(1)
&print
&print &"Usage:  ec test write"
&print &"  OR:"
&print &"        ec test read {PARTIAL|FULL}"
&print &"where:  PARTIAL = final read is incomplete buffer load."
&print &"        FULL    = final read results in full buffer. (default)"
&quit
r 12:23 0.804 1

comment:4 by Gary Dixon, 7 years ago

See MCR10071 (https://s3.amazonaws.com/eswenson-multics/public/mcrs/MCR10071.pdf) for a proposed repair of this defect.

comment:5 by Eric Swenson, 7 years ago

Milestone: MR12.7
Version: MR12.6f

comment:6 by Eric Swenson, 5 years ago

Resolution: fixed
Status: acceptedclosed
Note: See TracTickets for help on using tickets.