Velocity Reviews - Computer Hardware Reviews

Velocity Reviews > Newsgroups > Programming > Perl > Perl Misc > problem writing to stdin of child process

Reply
Thread Tools

problem writing to stdin of child process

 
 
john
Guest
Posts: n/a
 
      03-14-2005
Hello everyone,

I have a program which forks multiple children and needs to have
bidirectional communication with each child. Each child needs to use
STDIN and STDOUT to talk back to the parent.

The problem is that I'm having trouble connecting the pipe to STDIN of
the child. I've tried various approaches. A simple testcase is below.
In this case, the child seems to read the number (I think) of the pipe
file descriptor rather than the string I send down the pipe.

perl -v shows...
This is perl, v5.8.2 built for aix-thread-multi

Can anyone tell me where I'm going wrong ?
Thanks in advance.



#!/usr/bin/perl
use strict;
use warnings;

use IO::Handle;
use IO:ipe;

my $cr = IO::Handle->new(); # child reader
my $pw = IO::Handle->new(); # child writer

new IO:ipe($cr, $pw) or die 'pr/cw pipe';

my $pid = fork();
if ($pid > 0) {

# Parent

print {$pw} "hello!\n"; # sending to the child
close($pw);

} else {
# Child

# Connect stdin to pipe

close($pw);
my $fd = fileno($cr);
open(my $stdin, "<", \$fd) or die "STDIN open: $!";
*STDIN = $stdin;

my $line = <STDIN>; # hopefully reading from the parent
chomp $line;
print "child received: ($line)\n";
close($cr);
exit(0);
}

wait;
 
Reply With Quote
 
 
 
 
Big and Blue
Guest
Posts: n/a
 
      03-15-2005
john wrote:

> #!/usr/bin/perl
> use strict;
> use warnings;
>
> use IO::Handle;
> use IO:ipe;
>
> my $cr = IO::Handle->new(); # child reader
> my $pw = IO::Handle->new(); # child writer
>
> new IO:ipe($cr, $pw) or die 'pr/cw pipe';


Have you read the IO:ipe documentation?
(e.g. http://search.cpan.org/~nwclark/perl...lib/IO/Pipe.pm)

It starts with (almost) exactly what you want under the SYNOPSIS. (It
has the child writing to the parent - just swap the if/else codew blocks).

No need to mention IO::Handle (IO:ipe gets them for you).


> my $fd = fileno($cr);
> open(my $stdin, "<", \$fd) or die "STDIN open: $!";
> *STDIN = $stdin;
>
> my $line = <STDIN>; # hopefully reading from the parent


Not sure why you would want to do this anyway. You shouldn't be
reading from STDIN - you want to read from the read-side of the pipe opened
in the parent. Don't assume that just because your want to read from it
you have to make it STDIN. STDIN is "STanDard INput" - reading from a pipe
isn't "standard" in this sense.



--
Just because I've written it doesn't mean that
either you or I have to believe it.
 
Reply With Quote
 
 
 
 
john
Guest
Posts: n/a
 
      03-15-2005
Big and Blue <(E-Mail Removed)> wrote in message news:<(E-Mail Removed)>...
> john wrote:
>
> > #!/usr/bin/perl
> > use strict;
> > use warnings;
> >
> > use IO::Handle;
> > use IO:ipe;
> >
> > my $cr = IO::Handle->new(); # child reader
> > my $pw = IO::Handle->new(); # child writer
> >
> > new IO:ipe($cr, $pw) or die 'pr/cw pipe';

>
> Have you read the IO:ipe documentation?
> (e.g. http://search.cpan.org/~nwclark/perl...lib/IO/Pipe.pm)
>
> It starts with (almost) exactly what you want under the SYNOPSIS. (It
> has the child writing to the parent - just swap the if/else codew blocks).


I've seen this on my travels, but for some reason it didn't sink in
that this was what I needed. Terms such as "re-blessed" confuse me and
I've been sticking to stuff that I *thought* I understood. Anyway
you're right. This is exactly what I need and it'll make my code a lot
neater. I was going to post the modified and working testcase, however
it's so close to the example in the IOipe doc that there doesn't
seem much point.

>
> No need to mention IO::Handle (IO:ipe gets them for you).


I'm using autoflush in my larger program, but you're right; it's not
needed in this testcase.

>
>
> > my $fd = fileno($cr);
> > open(my $stdin, "<", \$fd) or die "STDIN open: $!";
> > *STDIN = $stdin;
> >
> > my $line = <STDIN>; # hopefully reading from the parent

>
> Not sure why you would want to do this anyway. You shouldn't be
> reading from STDIN - you want to read from the read-side of the pipe opened
> in the parent. Don't assume that just because your want to read from it
> you have to make it STDIN. STDIN is "STanDard INput" - reading from a pipe
> isn't "standard" in this sense.


The children will each exec an external command which will read from
stdin, and the parent has to manage sending data to each.

Thanks for your help "Big and Blue".
 
Reply With Quote
 
Anno Siegel
Guest
Posts: n/a
 
      03-15-2005
john <(E-Mail Removed)> wrote in comp.lang.perl.misc:
> Hello everyone,
>
> I have a program which forks multiple children and needs to have
> bidirectional communication with each child. Each child needs to use
> STDIN and STDOUT to talk back to the parent.


Have you considered IPC::Open2?

Anno
 
Reply With Quote
 
john
Guest
Posts: n/a
 
      03-15-2005
http://www.velocityreviews.com/forums/(E-Mail Removed) (john) wrote in message news:<(E-Mail Removed). com>...
> Big and Blue <(E-Mail Removed)> wrote in message news:<(E-Mail Removed)>...
> > john wrote:
> >
> > > #!/usr/bin/perl
> > > use strict;
> > > use warnings;
> > >
> > > use IO::Handle;
> > > use IO:ipe;
> > >
> > > my $cr = IO::Handle->new(); # child reader
> > > my $pw = IO::Handle->new(); # child writer
> > >
> > > new IO:ipe($cr, $pw) or die 'pr/cw pipe';

> >
> > Have you read the IO:ipe documentation?
> > (e.g. http://search.cpan.org/~nwclark/perl...lib/IO/Pipe.pm)
> >
> > It starts with (almost) exactly what you want under the SYNOPSIS. (It
> > has the child writing to the parent - just swap the if/else codew blocks).

>
> I've seen this on my travels, but for some reason it didn't sink in
> that this was what I needed. Terms such as "re-blessed" confuse me and
> I've been sticking to stuff that I *thought* I understood. Anyway
> you're right. This is exactly what I need and it'll make my code a lot
> neater. I was going to post the modified and working testcase, however
> it's so close to the example in the IOipe doc that there doesn't
> seem much point.
>
> >
> > No need to mention IO::Handle (IO:ipe gets them for you).

>
> I'm using autoflush in my larger program, but you're right; it's not
> needed in this testcase.
>
> >
> >
> > > my $fd = fileno($cr);
> > > open(my $stdin, "<", \$fd) or die "STDIN open: $!";
> > > *STDIN = $stdin;
> > >
> > > my $line = <STDIN>; # hopefully reading from the parent

> >
> > Not sure why you would want to do this anyway. You shouldn't be
> > reading from STDIN - you want to read from the read-side of the pipe opened
> > in the parent. Don't assume that just because your want to read from it
> > you have to make it STDIN. STDIN is "STanDard INput" - reading from a pipe
> > isn't "standard" in this sense.

>
> The children will each exec an external command which will read from
> stdin, and the parent has to manage sending data to each.
>
> Thanks for your help "Big and Blue".



Sorry, I spoke too soon. I'm still left with my original problem of
how to attach the pipe to STDIN of the child. The various approaches
I've tried either raise an invalid argument error or the child appears
to read the number of the file descriptor rather than the data.
 
Reply With Quote
 
john
Guest
Posts: n/a
 
      03-15-2005
http://www.velocityreviews.com/forums/(E-Mail Removed)-berlin.de (Anno Siegel) wrote in message news:<d16ekt$5mo$(E-Mail Removed)-Berlin.DE>...
> john <(E-Mail Removed)> wrote in comp.lang.perl.misc:
> > Hello everyone,
> >
> > I have a program which forks multiple children and needs to have
> > bidirectional communication with each child. Each child needs to use
> > STDIN and STDOUT to talk back to the parent.

>
> Have you considered IPC::Open2?
>
> Anno


This is close to what I want because it connects the reader and writer
filehandles to STDIN and STDOUT of the child, however I wanted to
control the exec of the child myself, so that I could have a test
harness within the same program file which simulates the child
behaviour.

I still don't understand why what I'm trying to do doesn't work but if
no-one has any better ideas I'll try with IPC::Open2 (or maybe Open3
if I need STDERR) as suggested.

Thanks for tip.
 
Reply With Quote
 
Big and Blue
Guest
Posts: n/a
 
      03-15-2005
john wrote:
>
> Sorry, I spoke too soon. I'm still left with my original problem of
> how to attach the pipe to STDIN of the child. The various approaches
> I've tried either raise an invalid argument error or the child appears
> to read the number of the file descriptor rather than the data.


Hav a look at the documentation for open. It gives (or gave...) an
example of saving STDOUT and STDERR, opening somethign else on them and
then restoring the original.

Rearrange as appropriate for STDIN.



--
Just because I've written it doesn't mean that
either you or I have to believe it.
 
Reply With Quote
 
john
Guest
Posts: n/a
 
      03-16-2005
Big and Blue <(E-Mail Removed)> wrote in message news:<(E-Mail Removed)>...
> john wrote:
> >
> > Sorry, I spoke too soon. I'm still left with my original problem of
> > how to attach the pipe to STDIN of the child. The various approaches
> > I've tried either raise an invalid argument error or the child appears
> > to read the number of the file descriptor rather than the data.

>
> Hav a look at the documentation for open. It gives (or gave...) an
> example of saving STDOUT and STDERR, opening somethign else on them and
> then restoring the original.
>
> Rearrange as appropriate for STDIN.


Once again, I may be speaking too soon...
It's not obvious from the perdoc, but the following seems to work with
the IO:ipe version of the testcase...

my $fd = fileno($pipe);
open(STDIN, "<&$fd") or die "STDIN open: $!";

I'll plug this back into my original program and see if it keeps
working
Thanks for your help.

Here's the modified code...

#!/usr/bin/perl
use strict;
use warnings;

use IO:ipe;

my $pipe = new IO:ipe or die 'pipe';

my $pid = fork();
if ($pid > 0) {

# Parent
$pipe->writer();

print $pipe "hello!\n"; # to the child
close($pipe);

} else {
# Child

# Connect stdin to pipe

$pipe->reader();

my $fd = fileno($pipe);
open(STDIN, "<&$fd") or die "STDIN open: $!";

my $line = <STDIN>; # from the pipe ?
chomp $line;
print "child received: ($line)\n";
close($pipe);
exit(0);
}

wait;
 
Reply With Quote
 
 
 
Reply

Thread Tools

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is On
HTML code is Off
Trackbacks are On
Pingbacks are On
Refbacks are Off


Similar Threads
Thread Thread Starter Forum Replies Last Post
pexpect on windows - child process of another child process - quickquestion Z W Python 0 03-09-2013 10:00 PM
How to pass stdin of a C++ program to the stdin of a process createdwith ShellExecute() Ben C Programming 2 08-29-2009 09:47 PM
stdin & stdout of child process Java 2 08-29-2005 11:15 PM
Help with controlling stdin/stdout for a child process Mike Finister C++ 1 07-24-2004 06:02 PM
Help with controlling stdin/stdout for a child process Mike Finister C Programming 3 07-24-2004 04:11 PM



Advertisments