+1  A: 

Sounds like you want to do something like the following:

Your CGI web daemon would look something like this: (Not Tested)

use CGI;
my $cgi = new CGI;
if ($cgi->param('action') eq "MyFirstCommand") {
    # perform your actions for this command and output a response to STDOUT
}
elsif ($cgi->param('action') eq "MySecondCommand") {
    # perform your actions for this command and output a response to STDOUT
}

And your script that calls the CGI web daemon would compose a URL to call the daemon in this sort of fashion: (again, Not Tested)

use LWP::Simple;
my $URL = 'http://hostname:port/cgi-bin/daemon-script.cgi?action=MyFirstCommand';
my $http_response = LWP::Simple::get($URL);
# analyze the response for success or failure
Kurt W. Leucht
+1  A: 

In the past, when I've needed to do something like this, I've generally handled the communication in one of two ways:

1) If the response is needed in real-time to send back to the user immediately (as appears to be the case here), then using sockets to talk to the daemon is the way to go. There are other options with shared memory, pipes, and whatnot, but using sockets gives you an easy scalability path for if/when you need to break the front-end web server and back-end daemon out onto separate machines.

2) If the response isn't time-critical, I've tended to shove the incoming commands onto a queue stored in a database table and then had the daemon periodically poll the queue for new tasks. This tends to be a bit easier to implement and scales up even better then the socket-based option, provided you can deal with the limitation of all communication going through the database.

Dave Sherohman
Response is not super time critical but updated values of lets say counters or cpu stats needs to be displayed on a continuous basis. Socket seems to be a viable option. Thanks
mtanish
+1  A: 

You did not explain why the existing perl script can't be run directly from the Perl/CGI script ? This seems the easiest path to me, as it does not involve creating another communication channel:

client ⇒ apache ⇒ your CGIzed existing script ⇒ embedded system

as opposed to:

client ⇒ apache ⇒ new CGI script ⇒ existing script ⇒ embedded system

I assume the reason is that you expect the CGI script to run multiple times simultaneously, and the embedded system is not able to handle multiple connections.

But even in this case, having a daemon for the only purpose of serialization seems overkill. You can use a lock in the CGI script, to protect the critical communication code, as in:

open(my $lock, ">", $lockfilename);
flock($lock, LOCK_EX);
... critical code...
flock($lock, LOCK_UN);

Note that the "crital code" part could either embed your existing script, or execute it.

If, despite all this, you still want to separate the CGI from the command daemon, here are templates for the client and server parts of socket-based communication. First, the client, which is part of the CGI:

use IO::Socket::INET;
$sock = IO::Socket::INET->new('localhost:9000');
print $sock "Comand\n";
$result = <$sock>;
... do something with the result ...
$sock->close;

And this is the main daemon loop:

package MyServer;
use base Net::Server;
sub process_request {
    my $self = shift;
    while (<STDIN>) {
        chomp;
        print "This is my answer to the command '$_'.\r\n";
    }
}
MyServer->run(port => 160);
Jerome
Thanks for your response. I'll take a look.The reason i want them to be separate is that for each embedded system i have a single connection which i want to multiplex for each of the users who send a request to monitor/execute remote commands via the web page. And i have multiple such embedded systems and the users can monitor one or more at the same time on different pages. Also i want to have the flexibility to provide the same functionality via a console based app in future.
mtanish
Oh, so the connection with the embedded system is to remain up for the whole time? I understand now. I think the socket solution for which I provided templates is appropriate. Plus, using the Net::Server package gives you a command server on which you can easily telnet to get a console access.
Jerome