× The internal search function is temporarily non-functional. The current search engine is no longer viable and we are researching alternatives.
As a stop gap measure, we are using Google's custom search engine service.
If you know of an easy to use, open source, search engine ... please contact support@midrange.com.



Not sure what is responsible for the change in effect, the RPG or the API, but the idea of using storage for an input parameter that is the same memory location as the output parameter is something I would want to avoid generally. Plus normally I would perform validation that the size requirement does not exceed the available storage in the receiver. While the output in the given scenario is to a User Space (*USRSPC) object, a value that is too large means the effects are merely that an ugly error will be logged by the API, e.g. MCH2804, before giving feedback that the API can not complete the request. And although it was noted that "for V7R1 the second call to the API stopped actually retrieving the data into the userspace", what the values of DSPF0100.BytesAvail and DSPF0100.BytesRetn were after the invocation was unstated; presumably the former matches what was returned on the first invocation.? If so, then unless the latter shows eight or fewer bytes, then the results are inconsistent [between what is claimed to have been returned and what was actually returned]. After the second invocation, there typically would be another test to ensure the amount of data returned is expected, before trying to address that data.

Of course if the RPG implements the effect of CONST by copying the parameter data before the call, then that would make the invocation work; the compiler, under no obligation either way, may or may not do so. Perhaps in the past the RPG was making that copy, but perhaps having gotten smarter, the RPG realized that the temporary copy of the value was unnecessary; i.e. according to the rules, not according to the effect seen. Thus, another /resolution/ would have been as simple as making the second parameter an expression, thus requiring the RPG make the temporary copy; e.g. DSPF0100.BytesAvail*1 for which the RPG is obliged to make the temporary copy to store the result of the expression.

If the API had copied the parameter to local storage before writing anything to the receiver variable, then the invocation also should have worked. Interesting that the API apparently does not, especially if it had previously; noting: different security levels potentially could impact that, due to parameter integrity validation. I tested that the API apparently does overwrite the storage in the receiver variable in v5r3 before making a copy of the second argument in its local storage; tested by removing the CONST specification for the parameter. That test result also suggests that on v5r3 the CONST specification alone was sufficient to prevent the issue.... so it seems maybe the RPG changed?

Even if the API does not make a local copy of the parameter value before writing to the receiver variable, I would not consider that API to be operating /incorrectly/, but I would consider the API to be working less than ideally. But based upon my observations on v5r3, what seems *is a defect* is that the API will return no data, even while telling the caller that *all data* was returned; i.e. after the second invocation, retrieving information from a DSPF for which there is sufficient storage supplied for the receiver, the test "DSPF0100.BytesAvail=DSPF0100.BytesRetn" evaluates to True. While arguably it was daft to have addressed output storage as input to the API, the API still should never claim to have provided all output while having provided none. It seems then, that the simple fix to the API is to copy the value from the second argument into local storage, and then reference that local storage throughout the API. Currently the API must [at least once, somewhere,] refer to some storage at the address of second argument that was since-corrupted by its having written data starting at the address of the first argument.

Regards, Chuck

On 16-Dec-2013 14:07 -0800, Hiebert, Chris wrote:
I have resolved an issue that I wanted to share with everyone.

The issue: on V7R1 QDFRTVFD doesn't appear to process correctly when
the second input parameter (Length of receiver variable ) is inside
the memory of the first parameter (Receiver variable).

http://pic.dhe.ibm.com/infocenter/iseries/v7r1m0/topic/apis/qdfrtvfd.htm

Background:

We went to V7R1 last year and all of our programs went through the
conversion process, most without recompiling.

I had need to update a RPGLE program that was using the QDFRTVFD
API.

The original program was compiled on our test system when our test
system was at v7r1 and our production system was at v5r4.

The program was compiled on v7r1, created for release V5R4, and then
eventually converted to V7R1.

The V5R1 version functioned like this:

Data structure DSPF0100 is based into a Userspace that was created in
QTEMP as auto-extendable.

The program was coded to call the API twice. First to retrieve the
needed size, and second to retrieve the data using that size.

D QDFRTVFD PR EXTPGM('QDFRTVFD')
D Receiver 1A CONST OPTIONS(*VARSIZE)
D Receiverlen 10I 0 CONST
D Dataformat 8A CONST
D Qualfile 20A CONST
D Apierror LIKEDS(Apierrords)

D ptrDSPF0100 S *
D DSPF0100 DS BASED(ptrDSPF0100) QUALIFIED
D BytesRetn 10I 0
D Bytesavail 10I 0
D Offset_QDFFINFO...
D 5U 0
D RcdFmtCount 5U 0
D DspAtrBits 1A
D ScnSizeCount 5U 0
D Offset_SortSeqTable...
D 5U 0
D Source_ccsid 2A

// Retrieve display file description
QDFRTVFD(DSPF0100 :8 :'DSPF0100' :FILE :APIERRORDS);

IF APIERRORDS.BYTESAVAIL = 0;
QDFRTVFD(DSPF0100 :DSPF0100.BytesAvail
:'DSPF0100' :FILE :APIERRORDS);
ENDIF;

On V5R4 and the converted V7R1 the second call correctly retrieves the
data into the userspace.

Once the program was compiled on V7R1 for V7R1 the second call to the
API stopped actually retrieving the data into the userspace.

During debugging I ended up recompiling the program on V7R1 without any
changes, and still the second call does not populate the userspace with
the requested data.

I made a small modification.

Added a work field:

D wkBytes S 10I 0

Modified the second call to use the work field:

// Retrieve display file description

QDFRTVFD(DSPF0100 :8 :'DSPF0100' :FILE :APIERRORDS);
IF APIERRORDS.BYTESAVAIL = 0;
wkBytes = DSPF0100.BytesAvail;
QDFRTVFD(DSPF0100 :wkBytes
:'DSPF0100' :FILE :APIERRORDS);
ENDIF;

Now the data is being returned to the user space just like the prior
(V5R4) version of the program.


As an Amazon Associate we earn from qualifying purchases.

This thread ...

Follow-Ups:

Follow On AppleNews
Return to Archive home page | Return to MIDRANGE.COM home page

This mailing list archive is Copyright 1997-2024 by midrange.com and David Gibbs as a compilation work. Use of the archive is restricted to research of a business or technical nature. Any other uses are prohibited. Full details are available on our policy page. If you have questions about this, please contact [javascript protected email address].

Operating expenses for this site are earned using the Amazon Associate program and Google Adsense.