Was wanting to send this response to the group and not just to Chuck Lane.
This is way I don't trust me making changes to anything I can't even work a
news reader.  :)

Here is the particulars of my system:
VMS: 7.3-1 with most patches applied
DECC: Compaq C V6.5-001 on OpenVMS Alpha V7.3-1
TCPIP: Compaq TCP/IP Services for OpenVMS Alpha Version V5.3 - ECO 2
on a Compaq AlphaServer ES40 running OpenVMS V7.3-1
I forgot to add that in my last post.

<[EMAIL PROTECTED]> wrote in message
news:<[EMAIL PROTECTED]>...
> I'm not seeing this with the latest bleadperl (5.9.0 @ 18376 on VMS6.2),
> and I *think* they have the same safe_popen. The difference may be in
> the perlio implementation, or the conditions under which you're running
> the script.
>
Are you not seeing the error or is the script actually waiting for input? I
haven't tried 5.9.0 as my company really only wants to use release builds.
> For system(), safe_popen doesn't change SYS$INPUT at all.
>
> Here's a code snippet from safe_popen from where lib$spawn is called:
>
> /* Omit arg 2 (input file) so the child will get the parent's SYS$INPUT
> * and SYS$COMMAND. vmspipe.com will redefine SYS$INPUT, but we'll still
> * have SYS$COMMAND if we need it.
> */
> _ckvmssts(lib$spawn(&vmspipedsc, 0, &nl_desc, &flags,
> 0, &info->pid, &info->completion,
> 0, popen_completion_ast,info,0,0,0));
>
> When handling system(), mode='n' so the "popen_input" symbol passed to
> VMSPIPE.COM is empty (""). So VMSPIPE.COM doesn't set it:
>
> $ pif perl_popen_in .nes. "" then perl_define/user/name_attributes=confine
sys$input 'perl_popen_in'
>
> (pif = "if", perl_define="define/nolog")
>
> So you get whatever the default is from lib$spawn, which is typically
> the DCL script lib$spawn is running (VMSPIPE.COM), as you state.
>
> When the subprocess reads from SYS$INPUT in your test program,
> it should just get an EOF. Perhaps EOFs are being reported as undef's
> and triggering an error message?
>
Yes I get EOF which isn't what I'm expecting. That is why I'm getting the
error message. But my main point was that I shouldn't get EOF. system() is a
blocking call which should allow the child process to inherit the STDIN,
STDOUT, and STDERR of the parent process, or SYS$INPUT and SYS$OUTPUT, which
is the terminal in this case. The issue is that safe_popen is calling
lib$spawn to spawn a DCL script. If it didn't and instead spawned an
executable then SYS$INPUT and SYS$OUTPUT would be set up correctly. I am
aware of why we use the VMSPIPE.COM file, but we need to be aware that using
that DCL script causes SYS$INPUT to be changed which can be unexpected.

>
> It makes sense all right. It's just not clear what the best solution
> might be. But first, a detail:
>
> Take a look at the VMS.C Perl_vmstrnenv routine and docs on
> sys$trnlnm. SYS$INPUT et al are process permanent files, and when
> translated have a 4 byte prefix (IIRC, two bytes are a "this is a PPF"
> flag and the next two are an i/o channel#) If this route is pursued,
> using Perl_vmstrnenv or other `internal' routine would probably be
> better than adding a call to lib$get_logical. There's at least one
> example of calling vmstrnenv to get PPF definitions that can be found
> in VMS.C.
>
Thanks, I have read the LIB and SYS documentation on HP's site and I didn't
see any information on the translation. I haven't been hacking the Perl code
very much so wasn't aware of all support libraries that were available. I
will look into the VMS.C file further.

> But, more importantly, what exactly do you think your test program
> _should_ do? (other than "not give an error message") Read from the
> terminal? Get an EOF?
>
I was expecting the script to receive input and print it out. Without my
change it receives EOF like you state and returns.

> How about when you do:
> perl test.pl <somefile.txt
>
> should the a.pl subprocess grab the next line from "somefile.txt"?
> (doable but a real pain...one has to set up mailbox piping code because
> file i/o isn't generally sharable across processes)
> now generalize to a horde of subprocesses and sub-subprocesses all
> glomming onto one parent input. Or should the redirection be ignored,
> and subprocess input taken from the terminal? How about when Perl is
> run from a batch job?
>
Yes a.pl should grab the next line from somefile.txt. If it doesn't then
scripts can't be portable from one platform to the next. One of the main
reasons we use perl is so that we don't have to have different scripts for
different platforms.

You shouldn't have to set up mailbox piping because the system() call is a
blocking call. Therefore, any sharing of file I/O is not an issue as there
shouldn't be a way to system() off a large number of process all reading
from the same file. That is the reason for the open() call in that it allows
you to redirect input or output or both so that you won't run into the
problem. Using the open call is a bit more dangerous as you can spawn off a
large number of sub-processes all reading from the same file, but the script
writer should be aware of the issue and work around it. If perl is run as a
batch job then SYS$INPUT and/or SYS$OUTPUT would be set to NL or some other
device and that device should be inherited by the children unless the
programmer decides not to let the child have access. When writing a batch
script the script writer can't call interactive scripts or would have to
redirect stdin of the interactive script to some file. The decision should
be up to the programmer to handle how the I/O is set up. Perl shouldn't try
to take functionality away just because it can be use incorrectly in some
cases.

> My own opinion is that when you do system(), the subprocess shouldn't
> be taking any input from sys$input at all...it should have it's input
> set to NL: ... if you want a subprocess that gets input, you should
> be using open(X,'|some_command').
>
What about when you are writing an interactive script and you want to call a
program that also is interactive? I am currently creating a script that will
set up parts of our software but I need to call an upgrade program to let it
do some work. That upgrade program is interactive. So when it runs it
receives EOF which causes it to fail. I could ask the user before hand for
the input, but that means that my script now becomes very closely tied to
the upgrade program. If the upgrade program changes and requires more input
then that forces me to go back into the script and make the appropriate
changes.

> A more unixy point of view is that a subprocess spawned with system()
> should inherit stdin, stdout and stderr from its parent. But, as
> mentioned above, that can be a pain on VMS and may violate the
> "rule of least suprises".
>
> The system() implentation in safe_popen() was based on the previous
> standalone system() implementation...which just called lib$spawn
> with little to no "massaging" of PPF definitions. In particular,
> I think the handling of sys$input is identical to the previous
> implementation. (Not that it's right...we probably should do better).
>
Yes, subprocess should inherit stdin, stdout and stderr. And they will
unless you wrap them in a DCL script. Also on version 5.6.1 we didn't have
this problem. The code ran as it does with my fix added. I tried looking
through the code for 5.6.1 and all I could see was that there wasn't a "n"
case in the safe_popen, it was handled by the "w" case or by some other
means. I also tried making the 5.8.0 code work the same but it didn't work.
Also, just to add one more point to my argument, if you write some c code to
call the C RTL system() call then you get the same results as what I'm
describing. I can't get access to my system due to Microsoft's stupid news
reader so I can't verify if this code is 100% correct but it should be
close.

TEST.C
#include<stdlib.h>
int
main()
{
    system("a.exe");
}

A.C
#include <stdio.h>
int
main()
{
    char input;
    scanf("%c", &input);
    printf("Received: %c\n", input);
}

If you compile both programs and run test.exe then you should be blocked in
the child waiting for input. It should then print out the first character.
This is how I expect the perl code to work. Also why don't we use the C RTL
routines? Both system() and popen() are available. I do know that prior to
version 7.2 of VMS many of the C RTL routines are missing or have problems,
but in the current version of VMS the C RTL seems to be well supported and
has most of the bugs worked out of it.
Really I'm coming from the point of view of portability. If Perl doesn't
work similar on one platform as it does on the other then I'd say we are
losing a large part of what makes Perl so great.

> And the test suite doesn't really test these things very well, IMO.
> --
> Chuck Lane [EMAIL PROTECTED]
I agree, possibly creating a new test for these issues should be looked at.

I'm hoping for more input on this problem as I have just recently started
looking into the guts of VMS Perl. I have programmed on VMS extensively but
would think that others would be more familiar with the VMS code. Right now
we only have systems running 7.2 or better and we likely will be moving
everything to 7.3-1 as it seems to have the best support for threads and the
C RTL. So testing on earlier versions is a bit hard for me.

Thanks a lot for your info, especially on the LIB$GET_LOGICAL problem as it
wasn't making too much sense to me.

Michael Downey
MegaSys Computer Technologies


Reply via email to