From: David Resnick on
I've been poking at a script that loses the ability to ready from
<STDIN> after doing a system() call.

I located this
http://perldoc.perl.org/perlfaq8.html#Why-can%27t-my-script-read-from-STDIN-after-I-gave-it-EOF-%28^D-on-Unix,-^Z-on-MS-DOS%29?
which seemed to be the obvious answer to my questions.

But after doing this:
STDIN->clearerr();

or this:

seek STDIN, 0, SEEK_SET

or this
(at program beginning)
my $stdinBegin = tell(STDIN);

Before trying to read STDIN
seek(STDIN, $stdinBegin, 0);

or this
seek(STDIN, 1, 0);
seek(STDIN, 0, 0);


I still find I eternally get undef from <STDIN> after calling this
system command. The system command runs sipp, which does nothing
special as far as I can see. Why would invoking any system command
mess up the parent processes STDIN file handle?

Any suggestions appreciated...
From: David Resnick on
On May 10, 10:41 am, David Resnick <lndresn...(a)gmail.com> wrote:
> I've been poking at a script that loses the ability to ready from
> <STDIN> after doing a system() call.
>
> I located thishttp://perldoc.perl.org/perlfaq8.html#Why-can%27t-my-script-read-from...D-on-Unix,-^Z-on-MS-DOS%29?
> which seemed to be the obvious answer to my questions.
>
> But after doing this:
>   STDIN->clearerr();
>
> or this:
>
> seek STDIN, 0, SEEK_SET
>
> or this
> (at program beginning)
> my $stdinBegin = tell(STDIN);
>
> Before trying to read STDIN
>     seek(STDIN, $stdinBegin, 0);
>
> or this
>     seek(STDIN, 1, 0);
>     seek(STDIN, 0, 0);
>
> I still find I eternally get undef from <STDIN> after calling this
> system command.  The system command runs sipp, which does nothing
> special as far as I can see.  Why would invoking any system command
> mess up the parent processes STDIN file handle?
>
> Any suggestions appreciated...

Very interestingly, I figured out that if I close stdin on the system
command (with 0<&-) it works. Any comments on what I was doing wrong
above or why this works welcom though!
From: Ben Morrow on

Quoth David Resnick <lndresnick(a)gmail.com>:
> I've been poking at a script that loses the ability to ready from
> <STDIN> after doing a system() call.

Please post your code, and also your OS and version of perl. Something
like

perl -E'system "cat"; say scalar <STDIN>;'

works just fine for me here. (The first ^D sends EOF to cat, and any
subsequent lines are happily read by perl.)

> I located this
> http://perldoc.perl.org/perlfaq8.html#Why-can%27t-my-script-read-from-STDIN-after-I-gave-it-EOF-%28^D-on-Unix,-^Z-on-MS-DOS%29?
> which seemed to be the obvious answer to my questions.
>
> But after doing this:
> STDIN->clearerr();
>
> or this:
>
> seek STDIN, 0, SEEK_SET

Nothing involving seek will work on STDIN if STDIN is connected to a
terminal.

> I still find I eternally get undef from <STDIN> after calling this
> system command. The system command runs sipp, which does nothing
> special as far as I can see. Why would invoking any system command
> mess up the parent processes STDIN file handle?

Is it *any* command? What happens if you replace the command with
something innocuous like 'sleep 1'?

Ben

From: David Resnick on
On May 10, 12:56 pm, Ben Morrow <b...(a)morrow.me.uk> wrote:
> Quoth David Resnick <lndresn...(a)gmail.com>:
>
> > I've been poking at a script that loses the ability to ready from
> > <STDIN> after doing a system() call.
>
> Please post your code, and also your OS and version of perl. Something
> like
>
>     perl -E'system "cat"; say scalar <STDIN>;'
>
> works just fine for me here. (The first ^D sends EOF to cat, and any
> subsequent lines are happily read by perl.)
>
> > I located this
> >http://perldoc.perl.org/perlfaq8.html#Why-can%27t-my-script-read-from...D-on-Unix,-^Z-on-MS-DOS%29?
> > which seemed to be the obvious answer to my questions.
>
> > But after doing this:
> >   STDIN->clearerr();
>
> > or this:
>
> > seek STDIN, 0, SEEK_SET
>
> Nothing involving seek will work on STDIN if STDIN is connected to a
> terminal.
>
> > I still find I eternally get undef from <STDIN> after calling this
> > system command.  The system command runs sipp, which does nothing
> > special as far as I can see.  Why would invoking any system command
> > mess up the parent processes STDIN file handle?
>
> Is it *any* command? What happens if you replace the command with
> something innocuous like 'sleep 1'?
>
> Ben

As I mentioned in the follow up, closing stdin on the system command
fixed it.

It does not apply to any command, I discovered that early on. Once I
saw that the "system" command is what seemed to mess up my STDIN, I
tried the "date" run via system, didn't cause the issue.

The relevant part of the code is here. Note sipp is an open source
tool to handle SIP traffic. When run normally it does look for input
in STDIN.

getline("hit return when ready to execute test $testName\n");

my $sippCommand = "$vobBase/thparty3/sipp/sipp -sf " .
"$sippFile $remoteIpAddress -trace_msg -m 1 -l 1 -key
testname $testName -key testdir $outputDirRoot/$testName" .
" > /dev/null 2> /dev/null 0<&-";

my $sippReturnValue = mysystem("$sippCommand");

sub mysystem
{
my $cmd = $_[0];
my $result = 0;
debug("issuing command '$cmd'\n");

if (($result = system("$cmd")) != 0) {
warn "command '$cmd' failed";
}

return $result;
}

sub debug
{
if ($debug != 0) {
print STDERR "@_";
}

}

sub getline()
{
my $prompt = "@_[0]";
print $prompt;
my $line = <STDIN>;
chomp($line);
return $line;
}

********************

If I don't do the 0<&- in the system call, all future calls to <STDIN>
return eof. But that seems to fix my problem, so I'm now merely just
curious as to why this happens. I'm still mystified as to why, as I
thought that system would create an independent process that couldn't
alter its parents file descriptor state in any way.

My perl version is: perl, v5.8.8 built for i386-linux-thread-multi

Thanks,
-David
From: Ben Morrow on

Quoth David Resnick <lndresnick(a)gmail.com>:
> On May 10, 12:56�pm, Ben Morrow <b...(a)morrow.me.uk> wrote:
> > Quoth David Resnick <lndresn...(a)gmail.com>:
> >
> > > I've been poking at a script that loses the ability to ready from
> > > <STDIN> after doing a system() call.
> >
> > Please post your code, and also your OS and version of perl. Something
> > like
> >
> > � � perl -E'system "cat"; say scalar <STDIN>;'
> >
> > works just fine for me here. (The first ^D sends EOF to cat, and any
> > subsequent lines are happily read by perl.)
>
> As I mentioned in the follow up, closing stdin on the system command
> fixed it.
>
> It does not apply to any command, I discovered that early on. Once I
> saw that the "system" command is what seemed to mess up my STDIN, I
> tried the "date" run via system, didn't cause the issue.
>
> The relevant part of the code is here. Note sipp is an open source
> tool to handle SIP traffic. When run normally it does look for input
> in STDIN.
>
> getline("hit return when ready to execute test $testName\n");
>
> my $sippCommand = "$vobBase/thparty3/sipp/sipp -sf " .
> "$sippFile $remoteIpAddress -trace_msg -m 1 -l 1 -key
> testname $testName -key testdir $outputDirRoot/$testName" .
> " > /dev/null 2> /dev/null 0<&-";

It's generally safer to redirect stdin from /dev/null rather than
closing it. Closing it means the first file sipp opens will appear on
its fd 0, which may have unfortunate consequences.

> If I don't do the 0<&- in the system call, all future calls to <STDIN>
> return eof. But that seems to fix my problem, so I'm now merely just
> curious as to why this happens. I'm still mystified as to why, as I
> thought that system would create an independent process that couldn't
> alter its parents file descriptor state in any way.

It does create a separate process, but the two filehandles are still
somewhat connected. I can't see, off the top of my head, what sipp could
be doing to cause your STDIN to return EOF, but if you're interested you
could run the whole thing under strace to find out what it actually does
to fd 0.

Ben