1827798 Members
2377 Online
109969 Solutions
New Discussion

perl file handles refs

 
Fred Ruffet
Honored Contributor

perl file handles refs

This one is dedicated to Procura :)

I can't achive something in perl and I can't find any solution anywhere... but I know it can be done.

I am writing a package. In this package a function is passed 2 args : the "read" part of a pipe, and the "write" part of another pipe. Those pipes are reopened as STDIN and STDOUT. function forks and do its job.
Problem is that I can't seem to be able to reopen those pipes.

Here is a test implementation of what I try to do. It has been simplified to let only the problematic part.

=====
# tst.pm
package tst;

use strict;
no strict "refs";

sub new {
my $class=shift;
my $self={};

$self->{pipe2Write}=$_[0];
bless($self,$class);
return $self;
}

sub hello {
my $self=shift;
my $message=join("",@_);
my $pipeHandlerRef=$self->{pipe2Write};
my $pipeHandler=$$pipeHandlerRef;
open STDOUT,">",$pipeHandler;
print $message,"\n";
# Comment the 2 preceding line and uncomment
# the following works great
# print $pipeHandler $message,"\n";
return 0;
}

return 1;


=====
#hello.pl

#!/opt/perl/bin/perl

use strict;
use tst;
use IO::Handle;

my $readPipe;
my $writePipe;
pipe $readPipe,$writePipe;
$readPipe->autoflush(1);
$writePipe->autoflush(1);

my $myTst=tst->new(\$writePipe);
$myTst->hello("Hello");
$myTst->hello("World");
$myTst->hello("!!!");
close $writePipe;
while (<$readPipe>) {
print "READ from pipe : $_";
}
close $readPipe;

=====

So, what's the problem (may be a missing & or something like that)

Regards,

Fred
--

"Reality is just a point of view." (P. K. D.)
14 REPLIES 14
harry d brown jr
Honored Contributor

Re: perl file handles refs

Fred,

The "readPipe" (filehandle=4) and "writePipe" (filehandle=7) have nothing to do with STDIN or STDOUT, they are simply a PAIR of related read/write pipes:

main::(./hello.pl:11): $readPipe->autoflush(1);
DB<1> x $readPipe
0 GLOB(0x403f32e4)
->
FileHandle({*main::$readPipe}) => fileno(4)
DB<2> x $writePipe
0 GLOB(0x4001eaec)
->
FileHandle({*main::$writePipe}) => fileno(7)
DB<3>


I used "use Data::Dumper;" and the -d option to get into debug mode.

live free or die
harry d brown jr
Live Free or Die
Fred Ruffet
Honored Contributor

Re: perl file handles refs

Well... it looks like a "you can't" answer :(

I thought pipes were treated as files. I can use them as "print myFifo ..." or "$a=;" so it looks like file handle.

Isn't there a way to implement what I want ?

Regards,

Fred
--

"Reality is just a point of view." (P. K. D.)
harry d brown jr
Honored Contributor

Re: perl file handles refs

Pipes are "LIKE" files, wherein you can read and write from/to them, but reads are destructive (a read drains data from the pipe), writes can clog the pipe (if the pipe becomes full).

Also, have you "man perlipc" ?

live free or die
harry d brown jr
Live Free or Die
Fred Ruffet
Honored Contributor

Re: perl file handles refs

using www.perldoc.com instead of "man perlipc" (I like to waste bandwidth :)

I know about those problems, but I wanted to communicate with a background process (send commands, read output) and pipes seemed to be the right way.

Regards,

Fred
--

"Reality is just a point of view." (P. K. D.)
harry d brown jr
Honored Contributor

Re: perl file handles refs

Fred, thats very possible:

From perldoc perlipc

Safe Pipe Opens

Another interesting approach to IPC is making your single program go multiprocess and communicate between (or even amongst) yourselves. The open() function will accept a file argument of either "-|" or "|-" to do a very interesting thing: it forks a child connected to the filehandle you've opened. The child is running the same program as the parent. This is useful for safely opening a file when running under an assumed UID or GID, for example. If you open a pipe to minus, you can write to the filehandle you opened and your kid will find it in his STDIN. If you open a pipe from minus, you can read from the filehandle you opened whatever your kid writes to his STDOUT.


live free or die
harry d brown jr
Live Free or Die
harry d brown jr
Honored Contributor

Re: perl file handles refs


Fred,

If you want to "talk" to a background process, say one that is continously running (say some daemon process), you can use sockets or named pipes to "talk" to it.

live free or die
harry d brown jr
Live Free or Die
Fred Ruffet
Honored Contributor

Re: perl file handles refs

About the "Safe Pipe Open" : It only allowed a single way communication. You can have a child you write to, or one you read from, but not a child you can talk to.

I think I will go for named pipes, but it doesn't seem as transparent than the pipe command to me.

Regards,

Fred
--

"Reality is just a point of view." (P. K. D.)
harry d brown jr
Honored Contributor

Re: perl file handles refs


If you open a pipe from minus, you can read from the filehandle you opened whatever your kid (child) writes to his STDOUT.


live free or die
harry d brown jr
Live Free or Die
Fred Ruffet
Honored Contributor

Re: perl file handles refs

Yes, but what I'd like would be :
father sends commands to child,
child sends result to father.

So, |- or -| can't do as it runs a one-way communication.

I have now implemented with named pipes. It requires more, cause I need to check for uniqueness of pipe's names (multiple instances of my object may be running). So if anybody has any idea to go with unnamed pipes...

Thanks Harry for your time and good advices,

Fred
--

"Reality is just a point of view." (P. K. D.)
Ralph Grothe
Honored Contributor

Re: perl file handles refs

I bet you already have read "perldoc perlipc" as it has been metioned here already several times?
But didn't you go as far down as where the sections on bidirectional pipes start?
There they also mention the function socketpair() (perldoc -f socketpair).

As for passing file handles.
They are usually passed as either globs or globrefs to subs.
There in the subs they are assigned to scalars and are used straight forward, afaik.
See perldoc perlsub and the section "Pass by Reference"
Madness, thy name is system administration
Ralph Grothe
Honored Contributor

Re: perl file handles refs

What looks strange to me at first sight is that you pass ordinary lexically scoped scalars you just declared and haven't initialized to pipe() in hello.pl
Try passing globs or globrefs.
Afaik globs live in the (global) symbol table while lexical scalars don't.
Madness, thy name is system administration
Ralph Grothe
Honored Contributor

Re: perl file handles refs

Or try declaring $readPipe and $writePipe as package globals like

our ($readPipe, $writePipe)

or

use vars qw($readPipe $writePipe)
Madness, thy name is system administration
Vali Ticau
New Member

Re: perl file handles refs

"It only allowed a single way communication. You can have a child you write to, or one you read from, but not a child you can talk to."

Does the following FAQ helps ?

perldoc -q pipe
"How can I open a pipe both to and from a command?"

__Vali
Fred Ruffet
Honored Contributor

Re: perl file handles refs

Well, well... we are going out of initial subject. My problem is not to create pipes or to communicate with child process. I know about many ways for doing this. My problem is to pass a reference to a pipe between a main program and an object/package.

Regards,

Fred
--

"Reality is just a point of view." (P. K. D.)