Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

REXX and EXECIO

272 views
Skip to first unread message

Miroslav Vaic

unread,
Mar 14, 1999, 3:00:00 AM3/14/99
to
I am developing REXX scripts for MVS and I do prototype the scripts with
Regina Rexx on Win NT. But there are some inconsistencies, biggest of which
is the difference in IO operations. MVS REXX uses EXECIO instruction,
although almost all other REXX implementations use LINES, LINEIN and
LINEOUT.

I have tried to think about a simple solution, how to make the scripts
easily portable between Win NT and MVS. The best thing I have up to now is
to use something like in the next script:

/* EXECIO="Call WinEXECIO" */ /* uncomment on Win NT */

Interpret EXECIO "* DISKR DATADD (FINIS STEM Data.)"
...
EXIT

WinEXECIO:
Data.0 = Lines(...)
...

but this means extra overhead in every script to implement the WinEXECIO
procedure. Also the necessity of adding and removing comments is unpleasant
etc.

Does anybody know a better way how to easily port between Win NT and MVS ?
Thank for any idea.


Michel Castelein

unread,
Mar 14, 1999, 3:00:00 AM3/14/99
to
On Sun, 14 Mar 1999 01:47:54 +0100, "Miroslav Vaic" <mv...@trask.cz>
wrote:

You could insert some code in your program to check the platform at
execution time.

PARSE SOURCE var .
select; when var = 'TSO' then ...
when var = ...
end

Regards,

Michel Castelein
(Author of a REXX Programming course (OS/390 and VM)
---------------------------------------------------------
Michel Castelein
OS/390 System Engineer & Education Consultant
E-mail Mic...@jeeves.be
Home page http://homepages.infoseek.com/~michelcastelein/
Company: JEEVES Consulting N.V., phone +32-2-251.66.50

David Alcock

unread,
Mar 15, 1999, 3:00:00 AM3/15/99
to Miroslav Vaic
You'll want to check out my Rexx Portability page:

http://www.ticnet.com/davea/rexxany

It has tips on detecting which platform you're on and some sample code
which does I/O using different techniques based on the Rexx
implementation.

HtH...Dave

Miroslav Vaic wrote:
> I am developing REXX scripts for MVS and I do prototype the scripts with
> Regina Rexx on Win NT. But there are some inconsistencies, biggest of which
> is the difference in IO operations. MVS REXX uses EXECIO instruction,
> although almost all other REXX implementations use LINES, LINEIN and
> LINEOUT.

<snip>

Nolly Unvala

unread,
Mar 15, 1999, 3:00:00 AM3/15/99
to
Just a word of caution when using the chars() or lines() function,
especially when
accessing files over a network - it's EXTREMELY slow (at least with the
OREXX
implementation in Win/NT). The implementation seems to read the entire file
for each execution of the chars() or lines() function and is deadly when
processing
large files over a network.

I prefer to execute the function just once, save the value, and manually
code for
the bytes/lines left to read (example below uses chars() and a 4K buffer for
efficiency).

ifile_len = chars(ifile)
if ifile_len = 0 then
do
say '**ERR**' ifile 'is empty.'
return
end

read_buf = 4096
chars_left = ifile_len

if chars_left > read_buf then
chars_to_read = read_buf
else
chars_to_read = chars_left

do until chars_to_read = 0
ifile_buf = charin(ifile,,chars_to_read)
...
... <your code to process the buffer>
...
chars_left = chars_left - chars_to_read
if chars_left > read_buf then
chars_to_read = read_buf
else
chars_to_read = chars_left
end

--
Nolly Unvala
<remove "_xspam" from address to reply>
David Alcock wrote in message
<46839E98D053AD9B.A45B1533...@library-proxy.airnews.ne
t>...

Jerry Prather

unread,
Mar 15, 1999, 3:00:00 AM3/15/99
to
OK, here's another point of uncertainty...

In an application I have many occasions to check for the existance files. I
know that if I want to use the file, I'd have to request a semaphore to see if
the file is in use.

But what if I just want to check for its presence, busy or not, with
RxFileExists(filename)? If the file is in use when RxFileExists runs, will
there be a collision? I haven't seen one yet and would like to avoid writing
all the extra code if it isn't really necessary. (So I'm lazy...but I like
shorter programs.)

TIA,

Jerry Prather pra...@infi.net

"Many religions are worth dying for; no religion is worth killing for."
- Me (circa 1998)


Jeff

unread,
Mar 15, 1999, 3:00:00 AM3/15/99
to
I was forced to do the exact thing you are talking about.

What I did was instead of using specific commands EXECIO/LINEIN I put each
IO command in a subroutine, ex:

READ_LINE: /* WHEN RUN ON MVS */
ARG DDNAME
"EXECIO 1 DISKR "DDNAME" (STEM "DDNAME".L."
READ_RC=RC
RETURN RC

READ_LINE: /* WHEN RUN THROUGH REGINA ON PC */
ARG DDNAME
DDNAME.L.0=DDNAME.L.0+1
REC_COUNT=DDNAME.L.0
DDNAME.L.REC_COUNT=LINEIN(DDNAME,1)
READ_RC=RC
RETURN RC

In this case I misnamed stream id purposely to ddname to simplify changes.

OPEN_FILE_INPUT: /*MVS*/
ARG DDNAME DSN
"ALLOC FI("DDNAME") DA('"DSN"') SHR REUSE"
ALLOC_RC=RC
RETURN RC

OPEN_FILE_INPUT: /*PC*/
ARG DDNAME DSN /* ON PC NO DIFFERENCE BETWEEN DSN AND DDNAME */
DUMMY_REC=LINEIN(DDNAME,0)
ALLOC_RC=RC
RETURN RC

This way when you switch platforms you only have to change a few procedures.
Since I learned REXX on the mainframe first I made REGINA REXX read
everything into STEMS, just because thats the way I am used to working.

It is a little ugly on the PC side, but the loss of CPU is less noticeable
on the PC. At least for what I did.

Hope this helps.

Jeff

unread,
Mar 15, 1999, 3:00:00 AM3/15/99
to
>But what if I just want to check for its presence, busy or not, with


I know this may be a little clunky, but on the PC I usually use the DIR
command from within REXX and route the output to a file and read that back
in to determine results:

FILE_EXISTS: PROCEDURE
ARG FILENAME
"DEL DIR.LIS"
"DIR "FILENAME" /B >> DIR.LIS"
IF LINES('DIR.LIS')>0 THEN DO
RETURN (1=1)
END;ELSE DO
RETURN (1=0)
END
RETURN /* NOT NECESSARY, BUT IT DELIMITS PROCEDURE */

Bob Eberle

unread,
Mar 15, 1999, 3:00:00 AM3/15/99
to
In message <7cjd2e$5aq$1...@nw003t.infi.net> - pra...@infi.net (Jerry
Prather)15 Mar 1999 16:38:38 GMT writes:
:>
:>OK, here's another point of uncertainty...

:>
:>In an application I have many occasions to check for the existance files. I
:>know that if I want to use the file, I'd have to request a semaphore to see if
:>the file is in use.
:>
:>But what if I just want to check for its presence, busy or not, with
:>RxFileExists(filename)? If the file is in use when RxFileExists runs, will

:>there be a collision? I haven't seen one yet and would like to avoid writing
:>all the extra code if it isn't really necessary. (So I'm lazy...but I like
:>shorter programs.)
:>
:>TIA,
:>
:>Jerry Prather pra...@infi.net
:>
:>"Many religions are worth dying for; no religion is worth killing for."
:> - Me (circa 1998)
:>
Jerry,

Try something like this:

filename = 'C:\MYFILE' /* As an example */
name = stream(filename,'c','query exists) /* Get name if it
exists */
if name = '' then say 'File does not exist'
else say 'The file exists'

The stream will return the fully qualified name of the file if it does
in deed exist.

Bob Eberle
rke_so...@ibm.net


Jerry Prather

unread,
Mar 16, 1999, 3:00:00 AM3/16/99
to
In message <36ed...@news3.us.ibm.net> - rke_so...@ibm.net (Bob Eberle)
writes:
:>

:>Jerry,
:>
:>Try something like this:
:>
:> filename = 'C:\MYFILE' /* As an example */
:> name = stream(filename,'c','query exists) /* Get name if it
:>exists */
:> if name = '' then say 'File does not exist'
:> else say 'The file exists'
:>
:>The stream will return the fully qualified name of the file if it does
:>in deed exist.
:>
:>Bob Eberle
:>rke_so...@ibm.net
:>

That's what I was using before trying to use the RxExtra call. Through
experience, I know (I think) that there can be collisions with this and was
using a semaphore on all OS calls to prevent it. Another precaution involved
is that you also need to close the file after querying it with the STREAM
function. I was hoping to save all that code by using RxExtra.

Thanks for the reply,

Miroslav Vaic

unread,
Mar 17, 1999, 3:00:00 AM3/17/99
to
Jeff,
thank you for the response. This seems to me as the best solution I have
seen up to now. But a question - is not the reading row by row quite
unefficient on MVS ?
And still - is it not possible to find a solution for Regina among the
function packages for it ?
Maybe somebody has already done it ...

Thank for all the responces concerning this issue, I am quite surprised with
so many people interested in it ...

Miroslav Vaic


Jerry Prather

unread,
Mar 17, 1999, 3:00:00 AM3/17/99
to
In message <YfCq2RCS57RN-p...@prime028222.lvcablemodem.com> -
dgo...@cfsrexx.com (Dick Goran) writes:
:>

:>On Mon, 15 Mar 1999 16:38:38, pra...@infi.net (Jerry Prather) wrote:
:>
:>> In an application I have many occasions to check for the existance files. I
:>> know that if I want to use the file, I'd have to request a semaphore to see if
:>> the file is in use.
:>
:>STREAM( ..., 'C', QUERY EXISTS' ), recommended in other replies, will
:>not report the presence of files with RHS attributes set. SysFileTree()

First let me thank Dick and the other respondants for their attempts to answer
my question, but I'm beginning to realize that either my question wasn't clear
enough or there is some basic knowledge that I'm missing.

What I need to know is:

(1) If the file is currently being used by another process, what will these
various methods report? Will there be a collision that will require the file
to be protected by a semaphore in order to check for its existence?

(2) If I use any of these methods (especially the STREAM function), do I have
to explicitly CLOSE the STREAM function after the check?

Sorry if I'm being dense, but... :-( ...OK, just tell me I'm dense.

do...@hotrocks.msfc.nasa.gov

unread,
Mar 17, 1999, 3:00:00 AM3/17/99
to
Jerry,

I have a set of code that you probably could simply take and use almost
verbatim, assuming you seriously need to FORCE serial access to a file.

I did this by creating a "databaseserver" program that on starting
accesses a database. Programs that need to talk to the database
actually talk to the server. This is isolated into a suite of
subroutines (DatabaseSetup, _Talker, _Read, and _Write) which I simply
drop into programs as needed.

The server has a timer thread that kills the server if the program that
started the server dies without killing the server. Communication from
program to server is via a named pipe.

If Wayne wants this for his site I'll send it to him also. I had
thought this might be a bit to hairy for a collection of short code
fragments, but what the heck.

Doug

Jerry Prather

unread,
Mar 17, 1999, 3:00:00 AM3/17/99
to
In message <36F01E...@hotrocks.msfc.nasa.gov> -
do...@hotrocks.msfc.nasa.gov writes:
:>
:>Jerry,

:>
:>I have a set of code that you probably could simply take and use almost
:>verbatim, assuming you seriously need to FORCE serial access to a file.
:>
:>I did this by creating a "databaseserver" program that on starting
:>accesses a database. Programs that need to talk to the database
:>actually talk to the server. This is isolated into a suite of
:>subroutines (DatabaseSetup, _Talker, _Read, and _Write) which I simply
:>drop into programs as needed.
:>
:>The server has a timer thread that kills the server if the program that
:>started the server dies without killing the server. Communication from
:>program to server is via a named pipe.
:>
:>If Wayne wants this for his site I'll send it to him also. I had
:>thought this might be a bit to hairy for a collection of short code
:>fragments, but what the heck.
:>
:>Doug

Doug, thanks for the offer and I'll gratefully accept. What you are
suggesting is very close to the application I'm working on (although I'm not
dealing with a server). I have Rexxbase database files which need to be
reindexed and/or rebuild a stemmed variable for access by the next option
selected by the user. The stemmed variable is built from a text file built by
the database on demand (my "update" thread). This thread takes a good bit of
time - about three minutes for a ~20K record table. If there has been a
"significant" change to the database records, the text file is deleted. Many
parts of the program need to know if the text file is present so it can be
rebuilt at a high priority if necessary. This sequence of requirements is
what is generating all my fussy questions.

Wayne Swanson

unread,
Mar 17, 1999, 3:00:00 AM3/17/99
to
do...@hotrocks.msfc.nasa.gov wrote:
>
> Jerry,
>
> I have a set of code that you probably could simply take and use almost
> verbatim, assuming you seriously need to FORCE serial access to a file.
>
> I did this by creating a "databaseserver" program that on starting
> accesses a database. Programs that need to talk to the database
> actually talk to the server. This is isolated into a suite of
> subroutines (DatabaseSetup, _Talker, _Read, and _Write) which I simply
> drop into programs as needed.
>
> The server has a timer thread that kills the server if the program that
> started the server dies without killing the server. Communication from
> program to server is via a named pipe.
>
> If Wayne wants this for his site I'll send it to him also. I had
> thought this might be a bit to hairy for a collection of short code
> fragments, but what the heck.

Isn't that like asking an alcoholic if he wants a drink? I can't say
no! :-)

I think the question we need to ask ourselves is, "Is this something I
can share that someone else will find a use for?" I am happy to add
anything you think is worth adding.

As for the size question, I did have Joachim Scholtysik send a zip of
the VisPro forms and code for his submission but deferred using it in
addition to the html of info he sent. (for space reasons) We discussed
it a bit and I think he has convinced me to try to set something up to
archive this type of information also.

I will be checking into this and will let you know if there are any new
developments.

Wayne Swanson
------------------------------------------------------------
email: Ps...@Tech-Center.com
PillarSoft: http://fm-net.com/pillarsoft
Developers of WarpZip, ShowTime/2 and the Enhanced E Editors
Vice President, V.O.I.C.E. (Virtual OS/2 International Consumer
Education)
VOICE: http://www.os2voice.org
------------------------------------------------------------

Wayne Swanson

unread,
Mar 17, 1999, 3:00:00 AM3/17/99
to
Jerry Prather wrote:
>
> What I need to know is:
>
> (1) If the file is currently being used by another process, what will these
> various methods report? Will there be a collision that will require the file
> to be protected by a semaphore in order to check for its existence?
>
> (2) If I use any of these methods (especially the STREAM function), do I have
> to explicitly CLOSE the STREAM function after the check?

This may or may not be what you're looking for Jerry but...

Can you write an ea to the file you want to access for each access of
it? Make the ".User" ea anything to let your other processes know that
it is busy and a maybe keyword like "None" to let it know it is
available.

rc=SysGetEA(filename, '.User', 'FileUserName')
If FileUserName='None' Then do
rc=SysPutEA(filename, '.User', 'TheUser')
Do='Your work goes here'
rc=SysPutEA(filename, '.User', 'None')
end
else do
/* Depending on what you are writing this in you can wait for a
"When expired" specified time or SysSleep and check again until
the ea says that the file is available. */
end

I did an editor for someone that wanted to keep files locked so other
people on the network could not change them while someone else was
editing them and used a method quite a bit like this. It got a bit more
complex but this was the general idea.

You'll also need an error handler to guard against an interrupted
shutdown and change the ea's to "None" or you will be locked out when
you restart. :-)

Dick Goran

unread,
Mar 18, 1999, 3:00:00 AM3/18/99
to
On Wed, 17 Mar 1999 21:01:50, pra...@infi.net (Jerry Prather) wrote:

> What I need to know is:
>
> (1) If the file is currently being used by another process, what will these
> various methods report? Will there be a collision that will require the file
> to be protected by a semaphore in order to check for its existence?
>
> (2) If I use any of these methods (especially the STREAM function), do I have
> to explicitly CLOSE the STREAM function after the check?

One of the many advantages of REXX is that you can build yourself little
test cases (I have hundreds of them) to answer your own questions. I
have posted a test case below. STREAM, unless it is used to open a file,
does not create a file handle that you are responsible for closing and
there are no collisions.

/*--------------------------------*\
| Test reporting of an open file |
\*--------------------------------*/
call RxFuncAdd 'SysLoadFuncs', 'REXXUTIL', 'SysLoadFuncs'
call SysLoadFuncs

/*------------------------------------*\
| Create a file name and write to it |
\*------------------------------------*/
test_file = SysTempFileName( 'test???' )
call LINEOUT test_file, ' '

reply = STREAM( test_file, 'C', 'QUERY EXISTS' )
say 'QUERY EXISTS' reply

reply = STREAM( test_file, 'D' )
say 'Description' reply

call SysFileTree test_file, 'stem.', 'T'
say stem.1

/*--------------------------*\
| Close file and delete it |
\*--------------------------*/
call STREAM test_file, 'C', 'CLOSE'
call SysFileDelete test_file

--------------------------------------------------------------
Dick Goran author, http://cfsrexx.com/WebMaven/
C F S Nevada, Inc. author, REXX Reference Summary Handbook
953 E. Sahara Ave, Suite 9B Voice: 702-732-9616
Las Vegas, NV 89104-3012 FAX: 702-732-3847
http://www.cfsrexx.com dgoran*cfsrexx.com (replace *)


Jerry Prather

unread,
Mar 18, 1999, 3:00:00 AM3/18/99
to
:>On Wed, 17 Mar 1999 21:01:50, pra...@infi.net (Jerry Prather) wrote:
:>
:>> What I need to know is:
:>>
:>> (1) If the file is currently being used by another process, what will these
:>> various methods report? Will there be a collision that will require the file
:>> to be protected by a semaphore in order to check for its existence?
:>>
:>> (2) If I use any of these methods (especially the STREAM function), do I have
:>> to explicitly CLOSE the STREAM function after the check?
:>
:>One of the many advantages of REXX is that you can build yourself little
:>test cases (I have hundreds of them) to answer your own questions. I
:>have posted a test case below. STREAM, unless it is used to open a file,
:>does not create a file handle that you are responsible for closing and
:>there are no collisions.

Bingo! Thanks again, Dick, both for the simple answer and the method (which I
should have thougt of using myself) of proving it!

Jeff

unread,
Mar 20, 1999, 3:00:00 AM3/20/99
to
>seen up to now. But a question - is not the reading row by row quite
>unefficient on MVS ?


That was just an example. A further extension, which I have used, is to load
every input file into a stem and loop through the stem for the record by
record processing. This is kinda hard to implement on the PC, but it is my
standard process on the mainframe. Your individual reads can then be changed
to just update a counter rather than an actual read, simulating navigating
the records. Substituting the appropriate process for the appropriate
platform.

>And still - is it not possible to find a solution for Regina among the
>function packages for it ?

Not sure what you mean here, but when you mention REGINA and is function
packages you are talking about platform specific IO functions, thus unless
you have some kind of translator you can never be sure of the results. Even
if you did have a translator there is certain to be small problems.

0 new messages