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

How to quietly check if PDS(E) member exists from Rexx

2,348 views
Skip to first unread message

Farley, Peter x23353

unread,
Apr 29, 2014, 3:36:00 PM4/29/14
to
I know I can use ISPF facilities (LMINIT, LMOPEN, LMMFIND, LMCLOSE, LMFREE) to check if a member exists. I wanted a simpler solution, so I began experimenting and thought I would share my results.

LISTDSI unfortunately returns RC = 0 even if its DSN argument is coded with a member name that does not exist.

"EXECIO 1 DISKR ddname (FINIS STEM trash." where "ddname" was allocated with a member name that does not exist will fail with RC=20, but it also generates an S013 abend and dump, which is very undesirable and certainly not "quiet".

"EXECIO 0 DISKR ddname" returns RC=0 even if the member allocated in "ddname" does not exist.

syscalls('ON')
mbrRC = BPXWUNIX('head -1 "//''TSOUSER.MYLIB('mbrname')''"')

The above will return mbrRC = 1 if mbrname does not exist and mbrRC = 0 if mbrname does exist.

Unfortunately, the "//'DD:DDNAME'" format for file names does not work with the "head" utility when run from BPXWUNIX. When I tried it I got this error message:

"EDC5047I An invalid file name was specified as a function parameter."

I suspect this is because the allocated DD is not passed on to the "head" environment.

The "head -1" solution with full DSN and member is as simple as I have found so far. Other solutions or suggestions welcome.

HTH

Peter

This message and any attachments are intended only for the use of the addressee and may contain information that is privileged and confidential. If the reader of the message is not the intended recipient or an authorized representative of the intended recipient, you are hereby notified that any dissemination of this communication is strictly prohibited. If you have received this communication in error, please notify us immediately by e-mail and delete the message and any attachments from your system.

----------------------------------------------------------------------
For TSO-REXX subscribe / signoff / archive access instructions,
send email to LIST...@VM.MARIST.EDU with the message: INFO TSO-REXX

Altman, Lawrence

unread,
Apr 29, 2014, 3:38:47 PM4/29/14
to
Pete,
Just do an ADDRESS TSO "LISTD 'dsn(member)'". An rc=0 means the member exists, rc=4, means it does not.

Thanks,
Larry
Useful Info:
Lawrence Altman
Met Life IMS/DB2 Database Administration
732-893-4223(desk)
The information contained in this message may be CONFIDENTIAL and is for the intended addressee only. Any unauthorized use, dissemination of the information, or copying of this message is prohibited. If you are not the intended addressee, please notify the sender immediately and delete this message.

Dave Salt

unread,
Apr 29, 2014, 3:39:41 PM4/29/14
to
Try this:

if sysdsn('YOUR.DSN(MEMBER)') = "OK" then say "member exists"

HTH,

Dave Salt

SimpList(tm) - try it; you'll get it!

http://www.mackinney.com/products/program-development/simplist.html


> Date: Tue, 29 Apr 2014 15:35:16 -0400
> From: Peter....@BROADRIDGE.COM
> Subject: How to quietly check if PDS(E) member exists from Rexx
> To: TSO-...@VM.MARIST.EDU

Ted MacNEIL

unread,
Apr 29, 2014, 4:00:23 PM4/29/14
to
You need to wrap it with a msg("OFF") & a msg("OFF") or you will receive a TSO/E message MEMBER NOT FOUND -- if you want it totally clean.

-
-teD
-
� Original Message �
From: Dave Salt
Sent: Tuesday, April 29, 2014 15:42
To: TSO-...@VM.MARIST.EDU
Reply To: TSO REXX Discussion List
Subject: Re: [TSO-REXX] How to quietly check if PDS(E) member exists from Rexx

Farley, Peter x23353

unread,
Apr 29, 2014, 4:19:26 PM4/29/14
to
Actually, my tests showed that "x = SYSDSN(...)" does not output any extraneous message, so msg('OFF') and msg('ON') do not seem to be needed. The odd part of using SYSDSN is that you check for RC = 'OK' rather than RC = 0.

The LISTDS solution does require OUTTRAP off/on around the command to prevent extraneous output from appearing.

Thanks to all for additional solutions.

Peter

Bill Schoen

unread,
Apr 29, 2014, 6:32:16 PM4/29/14
to
If you have to run in a non-TSO environment sysdsn() might not be
available to you.
This is a procedure I have been using lately which is an extraction and
slight modification to pdsdir
ftp://public.dhe.ibm.com/s390/zos/tools/pdsdir/pdsdir.txt

***********************************************************************/
locmember: procedure
parse arg dsn,mem
if bpxwdyn('alloc fi(pds) da('dsn') shr msg(2)',
'recfm(f) dsorg(ps) lrecl(256) blksize(256)')<>0 then
return 0
do looking=1 by 0 while looking
address mvs "execio 1 diskr pds (stem dir."
if rc<>0 | dir.0=0 then leave
used = c2d(substr(dir.1,1,2))
do ix=3 by 0 while ix < used /* first entry starts in third byte */
name = substr(dir.1,ix,8)
if substr(dir.1,ix,8) = 'ffffffffffffffff'x | name=mem then
do
looking=0
leave
end
ix = ix + 8 /* skip name */
ttr = substr(dir.1,ix,3)
ix = ix + 3 /* skip ttr */
len = c2d(bitand(substr(dir.1,ix,1),'1f'x))*2 /* get data len */
ix = ix + 1 /* skip info byte */
ix = ix + len /* skip user data */
end
end
address mvs 'execio 0 diskr pds (fini'
call bpxwdyn 'free fi(pds)'
return name=mem

Bill Schoen

Paul Gilmartin

unread,
Apr 30, 2014, 10:08:26 AM4/30/14
to
On 2014-04-29, at 13:35, Farley, Peter x23353 wrote:

> I know I can use ISPF facilities (LMINIT, LMOPEN, LMMFIND, LMCLOSE, LMFREE) to check if a member exists. I wanted a simpler solution, so I began experimenting and thought I would share my results.
>
> LISTDSI unfortunately returns RC = 0 even if its DSN argument is coded with a member name that does not exist.
>
> "EXECIO 1 DISKR ddname (FINIS STEM trash." where "ddname" was allocated with a member name that does not exist will fail with RC=20, but it also generates an S013 abend and dump, which is very undesirable and certainly not "quiet".
>
> "EXECIO 0 DISKR ddname" returns RC=0 even if the member allocated in "ddname" does not exist.
>
Adding the "(open" option gives RC=20, but again it's certainly not "quiet".

> syscalls('ON')
> mbrRC = BPXWUNIX('head -1 "//''TSOUSER.MYLIB('mbrname')''"')
>
> The above will return mbrRC = 1 if mbrname does not exist and mbrRC = 0 if mbrname does exist.
>
That argument to "head" is unsupported. Use at your own risk. But:

mbrRC = BPXWUNIX('cp "//''TSOUSER.MYLIB('mbrname')''" /dev/null')

... (untested) might do what you want and be supported.

> Unfortunately, the "//'DD:DDNAME'" format for file names does not work with the "head" utility when run from BPXWUNIX. When I tried it I got this error message:
>
And that construct is not supported, even as an argument to "cp".

> "EDC5047I An invalid file name was specified as a function parameter."
>
That message is puzzling.

> I suspect this is because the allocated DD is not passed on to the "head" environment.
>
Plausibly. Does BPXWUNIX fork()?

> The "head -1" solution with full DSN and member is as simple as I have found so far. Other solutions or suggestions welcome.
>
But still unsupported. Simply, "DD:DDNAME" is not a data set name.
Try it in a simple JCL batch job to prove it to yourself.

-- gil

Farley, Peter x23353

unread,
Apr 30, 2014, 10:19:13 AM4/30/14
to
Thanks Bill. I do expect to have TSO available to this program for other reasons, but it's good to know I have an alternative when no TSO is available.

Farley, Peter x23353

unread,
Apr 30, 2014, 10:35:09 AM4/30/14
to
> -----Original Message-----
> From: TSO REXX Discussion List [mailto:TSO-...@VM.MARIST.EDU] On
> Behalf Of Paul Gilmartin
> Sent: Wednesday, April 30, 2014 10:08 AM
> To: TSO-...@VM.MARIST.EDU
> Subject: Re: How to quietly check if PDS(E) member exists from Rexx
>
> On 2014-04-29, at 13:35, Farley, Peter x23353 wrote:
<Snipped>
> > syscalls('ON')
> > mbrRC = BPXWUNIX('head -1 "//''TSOUSER.MYLIB('mbrname')''"')
> >
> > The above will return mbrRC = 1 if mbrname does not exist and mbrRC =
> 0 if mbrname does exist.
> >
> That argument to "head" is unsupported. Use at your own risk. But:
>
> mbrRC = BPXWUNIX('cp "//''TSOUSER.MYLIB('mbrname')''" /dev/null')
>
> ... (untested) might do what you want and be supported.

Yes it is an obsolete parameter, but unsupported? Not yet anyway, and I would guess never.

However, it is no trouble at all to use "-n 1" instead of just "-1".

> > Unfortunately, the "//'DD:DDNAME'" format for file names does not
> work with the "head" utility when run from BPXWUNIX. When I tried it I
> got this error message:
> >
> And that construct is not supported, even as an argument to "cp".

Yes, I know, but I was hoping z/OS head was programmed to use fopen and thus support the construct like z/OS awk was, at least at one point in its life.

Lately the //'DD:ddname' construct has been ever harder to use effectively, or at all for that matter, with z/OS Unix utilities.

> > "EDC5047I An invalid file name was specified as a function
> parameter."
> >
> That message is puzzling.
>
> > I suspect this is because the allocated DD is not passed on to the
> "head" environment.
> >
> Plausibly. Does BPXWUNIX fork()?

No clue, but I would not be surprised. It does execute "sh -c" to run the command you pass in, so I'm guessing that's done with fork.

> > The "head -1" solution with full DSN and member is as simple as I
> have found so far. Other solutions or suggestions welcome.
> >
> But still unsupported. Simply, "DD:DDNAME" is not a data set name.
> Try it in a simple JCL batch job to prove it to yourself.

Of course "DD:DDNAME" is not a data set name in JCL, but it is *supposed* to be available in z/OS Unix, especially in a shell environment, as a *substitute* for a data set name.

IMHO the fact that it is not universally available is a crying shame.

Just my USD$0.02 worth.

Peter

This message and any attachments are intended only for the use of the addressee and may contain information that is privileged and confidential. If the reader of the message is not the intended recipient or an authorized representative of the intended recipient, you are hereby notified that any dissemination of this communication is strictly prohibited. If you have received this communication in error, please notify us immediately by e-mail and delete the message and any attachments from your system.

Paul Gilmartin

unread,
Apr 30, 2014, 1:18:27 PM4/30/14
to
On 2014-04-29, at 13:35, Farley, Peter x23353 wrote:
>
> Unfortunately, the "//'DD:DDNAME'" format for file names does not work with the "head" utility when run from BPXWUNIX. When I tried it I got this error message:
>
> "EDC5047I An invalid file name was specified as a function parameter."
>
> I suspect this is because the allocated DD is not passed on to the "head" environment.
>
You might circumvent that with _BPX_SHAREAS=MUST; address SYSCALL spawn cp ...
The setup for spawn is slightly more tedious than for BPXWUNIX.

Still, head is not documented as supporting //DSN; neither head nor cp is
documented as supporting //DD:.

-- gil

Bob Bridges

unread,
Apr 30, 2014, 5:58:57 PM4/30/14
to
SYSDSN is usually my choice, too. But Dave, I think if the answer is NOT
"OK", it displays it to the terminal as well as returning the result to the
program - at least, I know I've seen that sometimes. So I always turn MSG
off temporarily if I don't want to see errors - and Peter specified
"quietly". I don't have to do this very often, so I may be mistaken, but I
think it's MSG I'm talking about.

---
Bob Bridges
robhb...@gmail.com, cell 336 382-7313
rbri...@InfoSecInc.com

/* Write a wise saying and your name will live forever. -Unknown */

-----Original Message-----
From: TSO REXX Discussion List [mailto:TSO-...@VM.MARIST.EDU] On Behalf Of
Dave Salt
Sent: Tuesday, April 29, 2014 15:39

Try this:

if sysdsn('YOUR.DSN(MEMBER)') = "OK" then say "member exists"

> ---
> Date: Tue, 29 Apr 2014 15:35:16 -0400
> From: Peter....@BROADRIDGE.COM
>

Paul Gilmartin

unread,
Apr 30, 2014, 8:45:56 PM4/30/14
to
On 2014-04-30 08:33, Farley, Peter x23353 wrote:
>>
>>> mbrRC = BPXWUNIX('head -1 "//''TSOUSER.MYLIB('mbrname')''"')
>>>
>>> The above will return mbrRC = 1 if mbrname does not exist and mbrRC =
>> 0 if mbrname does exist.
>>>
>> That argument to "head" is unsupported. Use at your own risk. But:
>>
>> mbrRC = BPXWUNIX('cp "//''TSOUSER.MYLIB('mbrname')''" /dev/null')
>>
>> ... (untested) might do what you want and be supported.
>
> Yes it is an obsolete parameter, but unsupported? Not yet anyway, and I would guess never.
>
I meant the use of a data set name as a parameter to "head" is
unsupported; nowhere documented.

>>> Unfortunately, the "//'DD:DDNAME'" format for file names does not
>> work with the "head" utility when run from BPXWUNIX. When I tried it I
>> got this error message:
>>>
>> And that construct is not supported, even as an argument to "cp".
>
> Yes, I know, but I was hoping z/OS head was programmed to use fopen and thus support the construct like z/OS awk was, at least at one point in its life.
>
When? Cite. You appear to be conflating "supported", as in
documented, so problems are APARable, with "works by happenstance",
use at your own risk.

> Lately the //'DD:ddname' construct has been ever harder to use effectively, or at all for that matter, with z/OS Unix utilities.
>
And that is the hazard of using constructs that were never documented
as supported.

BTW, I routinely use UNIX directories in my SYSEXEC catenation.
Also unsupported, but very useful. I accept the risk, and
don't do it in code distributed to clients. An RFE might be
in order.

> Of course "DD:DDNAME" is not a data set name in JCL, but it is *supposed* to be available in z/OS Unix, especially in a shell environment, as a *substitute* for a data set name.
>
Cite.

> IMHO the fact that it is not universally available is a crying shame.
>
I agree. By "universally available" do you mean that DDNAMEs should
be inherited by forked children? Ain't gonna happen. (Well, maybe
the scope of ENQs should be made "job" (whatever that means), as
opposed to address space. I'm not holding my breath.)

As an alternative, I would like to see the entire z/OS Classic data
set space made available as a mountable Virtual File System.

-- gil

Karl-Heinz Wittemann

unread,
May 1, 2014, 5:14:54 AM5/1/14
to
in z/OS 2.1 you can use a new function to trap the IRX-messages:

/* REXX */
call trapmsg "ON"
call outtrap "INFO."
"alloc dd(tmp) da(DEMO.EXEC(NOMEM)) shr reuse"
"execio * diskr tmp (finis"
if RC > 0 then do
   say "Member did not exist"
   say "Messages from EXECIO:"
   do §=1 to INFO.0
      say INFO.§
   end
   exit
end
/* whatever */
exit

Zitat von Paul Gilmartin <PaulGB...@aim.com>:
--

Mobil: +49(0)176 562 44 567

Mainframe - 2nd to NONE

Paul Gilmartin

unread,
May 1, 2014, 7:13:47 PM5/1/14
to
On 2014-05-01 03:14, Karl-Heinz Wittemann wrote:
> in z/OS 2.1 you can use a new function to trap the IRX-messages:
>
> /* REXX */
> call trapmsg "ON"
>
Does this work only under TSO?

> call outtrap "INFO."
> "alloc dd(tmp) da(DEMO.EXEC(NOMEM)) shr reuse"
> "execio * diskr tmp (finis"
>
"*" is overkill, especially if you're looping over members.
Does it put everything on the stack? I'd prefer:
"execio 0 diskr tmp (open finis"

> if RC > 0 then do
> say "Member did not exist"
> say "Messages from EXECIO:"
> do §=1 to INFO.0
> say INFO.§
> end
> exit
> end
> /* whatever */
> exit

-- gil

----------------------------------------------------------------------

Karl-Heinz Wittemann

unread,
May 2, 2014, 3:36:00 AM5/2/14
to
Sorry, I did not think about, how stupid I am. It's a TSO-function, so
also SYSDSN() could be used.

Shame on me,
Heinz

Zitat von Paul Gilmartin <PaulGB...@aim.com>:

--

Mobil: +49(0)176 562 44 567

Mainframe - 2nd to NONE

0 new messages