Adding to DCL$PATH in PERL (89 Views)
Reply
Frequent Advisor
Jimson_1
Posts: 50
Registered: ‎03-20-2007
Message 1 of 14 (89 Views)

Adding to DCL$PATH in PERL

Hi,

I'm trying to extend DCL$PATH in Perl, but having problems with the new definition persisting outside of Perl itself.

I've included the Perl code inside a DCL command script.

Can anyone see what's wrong?


$ PERL SYS$INPUT 'P1'
$ DECK
#!perl -w

my $i;
for ($i=0; defined $ENV{"DCL\$PATH;$i"}; ++$i) {
print $ENV{"DCL\$PATH;$i"} . "\n";
}

$ENV{"DCL\$PATH;$i"} = uc $ARGV[0];

print "\n";
for ($i=0; defined $ENV{"DCL\$PATH;$i"}; ++$i) {
print $ENV{"DCL\$PATH;$i"} . "\n";
}

$ EOD
$!
$ wr ""
$ SHO LOG DCL$PATH
$!


Running the script gives:


$ @addtopath TEST

SCR
BIN

SCR
BIN
TEST

"DCL$PATH" = "SCR" (LNM$PROCESS_TABLE)
= "BIN"
1 "SCR" = "U32$:[BASE.SCR]" (LNM$PROCESS_TABLE)
= "TMPSCR"
= "WORK"
2 "TMPSCR" = "U32$:[BASE.SCR.TMPSCR]" (LNM$PROCESS_TABLE)
1 "BIN" = "U32$:[BASE.BIN]" (LNM$PROCESS_TABLE)
Please use plain text.
Esteemed Contributor
H.Becker
Posts: 354
Registered: ‎04-09-2009
Message 2 of 14 (89 Views)

Re: Adding to DCL$PATH in PERL

Not knowing Perl nor its implementation it's likely that Perl uses a CRTL function to retrieve environment variables: getenv. It is a CRTL feature to make logical names and their translations available as environment variables. It is likely that Perl uses the CRTL functions putenv or setenv to add to the environment. These functions manipulate the run-time environment, which is only valid during the life of the image. Changes in that environment are not written back to the process environment, here your logical DCL$PATH.

This is intended behavior which mimics UNIX behavior, where you can't modify a shell environment variable with setenv or putenv

You need to use or check where Perl uses functions like lib$get_logical and lib$set_logical.
Please use plain text.
Frequent Advisor
Jimson_1
Posts: 50
Registered: ‎03-20-2007
Message 3 of 14 (89 Views)

Re: Adding to DCL$PATH in PERL

Hi,

That's not the case as we can see with this slightly modified version of the above script.

P1 is used to extend DCL$PATH and also to define its own logical.

At the end we can see that 'P1' is defined.


$ PERL SYS$INPUT 'P1'
$ DECK
#!perl -w

my $i;
for ($i=0; defined $ENV{"DCL\$PATH;$i"}; ++$i) {
print $ENV{"DCL\$PATH;$i"} . "\n";
}

$log = uc $ARGV[0];
$ENV{"DCL\$PATH;$i"} = $log;
$ENV{$log} = 'Still Testing';

print "\n";
for ($i=0; defined $ENV{"DCL\$PATH;$i"}; ++$i) {
print $ENV{"DCL\$PATH;$i"} . "\n";
}

$ EOD
$!
$ wr ""
$ SHO LOG DCL$PATH
$ SHO LOG 'P1'
$!

Please use plain text.
Esteemed Contributor
H.Becker
Posts: 354
Registered: ‎04-09-2009
Message 4 of 14 (89 Views)

Re: Adding to DCL$PATH in PERL

Hmm, so I was wrong in assuming Perl only uses getenv and friends: it depends...

Do a show log DCL*, you should see what your script defined.

There is a section in the perlvms documentation which covers $ENV and how you can influence what is used for $ENV by the logical PERL_ENV_TABLES.
Please use plain text.
Honored Contributor
Joseph Huber_1
Posts: 1,082
Registered: ‎02-03-2004
Message 5 of 14 (89 Views)

Re: Adding to DCL$PATH in PERL

In my perlvms help I read:


In either case, only the first
value found searching PERL_ENV_TABLES is altered. It is not possible at present to define a search list logical name via %ENV.

So I assume that
$ENV{"DCL\$PATH;$i"} = uc $ARGV[0];
does not work, but
$ENV{"DCL\$PATH"} = uc $ARGV[0];
redefines the logical by the argument.

I don't know if newer PerlVMS versions allow to insert into a logical name search least, mine (v5.8.6) at least does not.

So to add an item to the searchlist, loop over the existing definition as You do now, but add each item to a local variable, adding a "," to before, then finally add the new variable from the arglist, and do the $ENV() = from that variable.
http://www.mpp.mpg.de/~huber
Please use plain text.
Frequent Advisor
Jimson_1
Posts: 50
Registered: ‎03-20-2007
Message 6 of 14 (89 Views)

Re: Adding to DCL$PATH in PERL

Hmm, still doesn't work.

DCL$PATH becomes equal to the entire concatenated string.

P_CC(H9-ACT)$ sho log DCL$PATH
"DCL$PATH" = "SCR,BIN,TEST" (LNM$PROCESS_TABLE)


Guess I'll just have to download and use the VMS::Logical module.


OK thanks Guys.
Please use plain text.
Honored Contributor
Joseph Huber_1
Posts: 1,082
Registered: ‎02-03-2004
Message 7 of 14 (89 Views)

Re: Adding to DCL$PATH in PERL

To invalidate my own suggestion:
no, defining a search list using $ENV() apparently does not work.
e.g.
$ENV{"TEST"} = "sys$login:,sys$manager:";
does define the logical literally, not as a search list, i.e. it is not equivalent to DCL
DEFINE TEST sys$login:,sys$manager:

Sorry, no perl solution.
http://www.mpp.mpg.de/~huber
Please use plain text.
Frequent Advisor
Jimson_1
Posts: 50
Registered: ‎03-20-2007
Message 8 of 14 (89 Views)

Re: Adding to DCL$PATH in PERL

Nearly a Perl solution...

I did what you said and then passed back to DCL the concatenated string as a local symbol, using the DCLSym module.

This I then simply expanded into a DCL DEFINE command.

And here it is:


$ PERL SYS$INPUT 'P1'
$ DECK

#!perl -w
use VMS::DCLsym;
tie %sym, VMS::DCLsym;

my $i;
for ($i=0; defined $ENV{"DCL\$PATH;$i"}; ++$i) {
push @tab, $ENV{"DCL\$PATH;$i"};
}

push @tab, uc $ARGV[0];

$sym{dcl_path} = join ",", @tab;

$ EOD
$!
$ define /nolog /process DCL$PATH 'dcl_path'
$!
Please use plain text.
Honored Contributor
Hoff
Posts: 4,905
Registered: ‎01-29-2006
Message 9 of 14 (89 Views)

Re: Adding to DCL$PATH in PERL

When this:

$ define /nolog /process DCL$PATH 'dcl_path'

is invoked within the context of a spawned subprocess, the definition will immediately vaporize upon subprocess exit.

You could use /JOB to get broader definition, and which will be retained after subprocess (and main process) termination.

If you want to alter the current process context, then use a call to lib$set_logical or analogous.

if you're going to work within this area of OpenVMS, you will need to know some details of how DCL symbols and logical names and subprocesses work (and don't work) together, or you're going to get confused. (Well, I got confused when I first ran into this stuff.) This whole area is a little cryptic when first encountered (and particularly if you're used to how Unix works), but the propagation (inheritance) rules aren't all that complex within OpenVMS. But they can also and most definitely derail some design approaches.
Please use plain text.
Frequent Advisor
Jimson_1
Posts: 50
Registered: ‎03-20-2007
Message 10 of 14 (89 Views)

Re: Adding to DCL$PATH in PERL

The above solution works fine!

Running Perl does not spawn a sub process and thus a JOB logical is not required.

Its Perl I'm learning, not VMS.

And FYI I've been programming on VMS environments for 20 years.


Please use plain text.
Honored Contributor
Craig A Berry
Posts: 491
Registered: ‎05-06-2003
Message 11 of 14 (89 Views)

Re: Adding to DCL$PATH in PERL

As folks have figured out, you can't create search list logicals using %ENV within Perl. There is a syntax for *reading* search list logicals, but not creating them.

The reason for that is that in order to get past the 255-byte limitation on equivalence names, all of the elements of a search list are treated as one big long string so you effectively have 255 * 127 bytes for your value. In other words, if you assign a value to %ENV longer than 255 bytes, the pieces will be broken into chunks and stored as elements of the search list, then transparently pasted back together on lookup;

$ perl -e "$ENV{FOO} = 'Z' x (255 * 3);"
$ sho log foo
"FOO" = "ZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZ
ZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZ
ZZZ" (LNM$PROCESS_TABLE)
= "ZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZ
ZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZ
ZZ"
= "ZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZ
ZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZ
ZZ"
$ perl -e "print $ENV{FOO};"
ZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZ
ZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZ
ZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZ
ZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZ
ZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZ
ZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZ
$

The exception is the special PERL5LIB logical that tells Perl where to look for libraries: that one is always treated as a genuine search list.

The problem at hand is probably best solved by VMS::Logical. FWIW, Perl 5.10.1 is current.
Please use plain text.
Honored Contributor
John Gillings
Posts: 2,992
Registered: ‎07-31-2003
Message 12 of 14 (89 Views)

Re: Adding to DCL$PATH in PERL

>Running Perl does not spawn a sub process
> and thus a JOB logical is not required.

but what access mode does Perl use to define logical names? If they're in the process table at user mode, they will vaporise on image exit.

Use SHOW LOGICAL/FULL to include access mode, and add a wildcard to the end of the name to display the name at all access modes.

You might be able to SPAWN (ie Perl "system()") a SHOW LOGICAL/FULL command to see your user mode definition. Although you'll be looking at the process table of the subprocess, it should be a clone of the parent's table.
A crucible of informative mistakes
Please use plain text.
Honored Contributor
Craig A Berry
Posts: 491
Registered: ‎05-06-2003
Message 13 of 14 (89 Views)

Re: Adding to DCL$PATH in PERL

When Perl is storing the environment array in logical names (not the only option) it sets those logicals in supervisor mode. This is handy when mixing and matching Perl with native VMS utilities and helps make Perl a viable DCL replacement in some circumstances. It causes trouble when scripts ported from Unix assume that the contents of the environment array disappear at program exit.

I've sometimes wondered whether we should implement a mode option so that people who want the logicals to go away at image run-down would have the ability to do so.
Please use plain text.
Trusted Contributor
Cass Witkowski
Posts: 344
Registered: ‎01-12-2004
Message 14 of 14 (89 Views)

Re: Adding to DCL$PATH in PERL

Isn't that USER mode?
Please use plain text.
The opinions expressed above are the personal opinions of the authors, not of HP. By using this site, you accept the Terms of Use and Rules of Participation