File handlings

G

Glodalec

Hi !

My B program is a simple script, which reads a string from STDIN,
converts it to uppercase and prints it to STDOUT.

B.pl
#!/bin/perl
use strict ;
my $string=<STDIN>;
print STDOUT uc $string,"\n" ;

Now, I have A program, which listens on a TCP socket. Whenever string
come over socket, it should be put on STDIN buffer (yes, STDIN), forking
a new child, redirecting the parent SOCKET to child's STDOUT and exec
B.pl. (The same way Apache & CGI modules work). I was trying to use
select() but no luck.

A.pl
#!/bin/perl
use strict ;
....
SOCKET CREATION, LISTENING, GETTING LINE FROM A SOCKET INTO $LINE
....

TCP settings....
.......
if (my $pid=fork)
{
waitpid($pid,0); # Ok, here is parent
} else
{
my $string="This must be put in STDIN buffer" ; << Don't know how
my $old=select(SOCKET) ; << This is not working
exec("A.pl"); # and child
select $oldstdout ;
}

Any help would be appreciated
 
B

Ben Morrow

Glodalec said:
Now, I have A program, which listens on a TCP socket. Whenever string
come over socket, it should be put on STDIN buffer (yes, STDIN), forking
a new child, redirecting the parent SOCKET to child's STDOUT and exec
B.pl. (The same way Apache & CGI modules work). I was trying to use
select() but no luck.

No, that's not how filehandles work at all. You can't push stuff back
onto them: if you want to pass stuff to your child you have to use a
pipe.
A.pl
#!/bin/perl
use strict ;
...
SOCKET CREATION, LISTENING, GETTING LINE FROM A SOCKET INTO $LINE
...

TCP settings....
......
if (my $pid=fork)

fork can fail, in which case it returns undef.
{
waitpid($pid,0); # Ok, here is parent
} else
{
my $string="This must be put in STDIN buffer" ; << Don't know how
my $old=select(SOCKET) ; << This is not working
exec("A.pl"); # and child
select $oldstdout ;
}

Any help would be appreciated

my $pid = open my $TOCHILD, '|-', 'A.pl'
or die "fork failed: $!";

print $TOCHILD "The child will read this on its STDIN";

See perldoc -f open.

Ben
 
G

Glodalec

No, that's not how filehandles work at all. You can't push stuff back
onto them: if you want to pass stuff to your child you have to use a
pipe.
Had never used them (except on command line), will read about them.
fork can fail, in which case it returns undef.
I know, this script has been arranged a lot when posting here.
my $pid = open my $TOCHILD, '|-', 'A.pl'
or die "fork failed: $!";

print $TOCHILD "The child will read this on its STDIN";
THanks for advice. How about a child exec, which should actually write
to parent's SESSION handler (got from accept()), instead of its own
STDOUT.?
 
B

Ben Morrow

Glodalec said:
THanks for advice. How about a child exec, which should actually write
to parent's SESSION handler (got from accept()), instead of its own
STDOUT.?

It's probably easiest to do that manually, viz (untested):

accept my $NEWCONN, $LISTENER or die "accept failed: $!";

# or you'd probably be better off using IO::Socket::INET
my $NEWCONN = $LISTENER->accept or die "accept failed: $!";

pipe my ($FROMPARENT, $TOCHILD) or die "pipe failed: $!";

my $pid = fork;
defined $pid or die "fork failed: $!";
unless ($pid) {
open STDIN, '<&', $FROMPARENT or die "dup2 to STDIN failed: $!";
open STDOUT, '>&', $NEWCONN or die "dup2 to STDOUT failed: $!";
exec 'A.pl' or die "exec failed: $!";
}

close $FROMPARENT;
close $NEWCONN;

Obviously you want to put all this in a sub, so you can say

my $TOCHILD = accept_new_child($LISTENER);

If you get errors from the open '<&' syntax, you may need a newer
version of perl; or you can replace them with

open STDIN, '<&' . fileno $FROMPARENT or ...

Ben
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,995
Messages
2,570,226
Members
46,815
Latest member
treekmostly22

Latest Threads

Top