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