"Michael Downey" <[EMAIL PROTECTED]> writes: > I am currently trying to get 5.8.0 to work on VMS 7.3 and having a problem > with how SYS$INPUT is getting set-up when calling system. Here is the code > I'm testing: > test.pl > ------- > system("perl a.pl"); > > a.pl > ----- > $a = $ENV{'SYS$INPUT'}; > $b = $ENV{'SYS$COMMAND'}; > $c = $ENV{'SYS$OUTPUT'}; > print "INPUT: $a\n"; > print "COMMAND: $b\n"; > print "OUTPUT: $c\n"; > $answer = <STDIN>; > print "Received: $answer\n"; > > Both files are in the same directory. With a standard build of PERL 5.8.0 > this is what I get back when I do >>perl test.pl > INPUT: _TST5$DKA100: > COMMAND: _TST5$FTA195: > OUTPUT: _TST5$FTA195: > Use of uninitialized value in concatenation (.) or string at a.pl line 8. > Received:
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. > I tracked this down to the safe_popen call and I believe that the spawning > of the vmspipe.com file is causing SYS$INPUT to be set up incorrectly. I > believe that spawning a DCL script causes SYS$INPUT to be set to the script > itself. 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? > So I changed VMS.C to have the following code: > static PerlIO * > safe_popen(pTHX_ char *cmd, char *in_mode, int *psts) > { > ..... > unsigned short len = 0; > .... > $DESCRIPTOR(d_input, "SYS$INPUT"); > > } else if (*mode == 'n') { /* separate subprocess, no Perl i/o */ > /* Translate SYS$INPUT so we can pass it to the DCL script and > override the SYS$INPUT which will get set to the script itself. > */ > d_symbol.dsc$w_length = MAX_DCL_SYMBOL; > _ckvmssts(lib$get_logical(&d_input, &d_symbol, &len, 0, 0, 0, 0, > 0)); > symbol[len] = '\0'; > /* Don't know why but lib$get_logical puts something in the first 4 > characters and then puts the logical translation. */ > strncpy(in, symbol+4, 512); > > ... > } > ... > } > I hope that all makes sense. I'd do a better diff but my diff skills > are poor. Once I recompiled perl everything worked as planned with test.pl. > I'm not too sure if I'm missing something as this is a fairly important bug > if it is a bug. I'm compiling perl with just the standard configure and all > the tests passed except for the few known tests that don't. If anyone could > verify that I'm not out to lunch that would be much appreciated. Also if > anyone would know what lib$get_logical puts in the first 4 characters of the > array that would also be helpful. 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. 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? 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? 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'). 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). And the test suite doesn't really test these things very well, IMO. -- Chuck Lane [EMAIL PROTECTED]