Follow Techotopia on Twitter

On-line Guides
All Guides
eBook Store
iOS / Android
Linux for Beginners
Office Productivity
Linux Installation
Linux Security
Linux Utilities
Linux Virtualization
Linux Kernel
System/Network Admin
Scripting Languages
Development Tools
Web Development
GUI Toolkits/Desktop
Mail Systems
Eclipse Documentation

How To Guides
General System Admin
Linux Security
Linux Filesystems
Web Servers
Graphics & Desktop
PC Hardware
Problem Solutions
Privacy Policy




B.17. Core Apache Modules

B.17.3. Apache::SubProcess—Interface to Apache Subprocess API

The output of system( ), exec( ), and open(PIPE,"|program") calls will not be sent to the browser unless your Perl interpreter was configured with sfio.

One workaround is to use backticks:

print `command here`;

But a cleaner solution is provided by the Apache::SubProcess module. It overrides the exec( ) and system( ) calls with calls that work correctly under mod_perl.

Let's look at a few examples. This example overrides the built-in system( ) function and sends the output to the browser:

use Apache::SubProcess qw(system);
my $r = shift;

system "/bin/echo hi there";

This example overrides the built-in exec( ) function and sends the output to the browser. As you can guess, the printstatement after the exec( ) call will never be executed.

use Apache::SubProcess qw(exec);
my $r = shift;

exec "/usr/bin/cal"; 

print "NOT REACHED\n";

The env( ) function sets an environment variable that can be seen by the main process and subprocesses, then it executes the /bin/env program via call_exec( ). The main code spawns a process, and tells it to execute the env( ) function. This call returns an output file handle from the spawned child process. Finally, it takes the output generated by the child process and sends it to the browser via send_fd( ), which expects the file handle as an argument:

use Apache::SubProcess ( );
my $r = shift;

my $efh = $r->spawn_child(\&env);

sub env {
    my $fh = shift;
    $fh->subprocess_env(HELLO => 'world');

This example is very similar to the previous example, but it shows how you can pass arguments to the external process. It passes the string to print as a banner via a subprocess:

use Apache::SubProcess ( );
my $r = shift;

my $fh = $r->spawn_child(\&banner);

sub banner {
    my $fh = shift;
    # /usr/games/banner on many Unices

The last example shows how you can have full access to the STDIN, STDOUT, and STDERRstreams of the spawned subprocess, so that you can pipe data to a program and send its output to the browser:

use Apache::SubProcess ( );
my $r = shift;

use vars qw($string);
$string = "hello world";
my($out, $in, $err) = $r->spawn_child(\&echo);
print $out $string;

sub echo {
    my $fh = shift;
    $fh->subprocess_env(CONTENT_LENGTH => length $string);

The echo( ) function is similar to the earlier example's env( ) function. /tmp/pecho is as follows:

print "STDIN: '$buf' ($ENV{CONTENT_LENGTH})\n";

In the last example, a string is defined as a global variable, so its length could be calculated in the echo( ) function. The subprocess reads from STDIN, to which the main process writes the string ("hello world"). It reads only the number of bytes specified by the CONTENT_LENGTH environment variable. Finally, the external program prints the data that it read to STDOUT, and the main program intercepts it and sends it to the client's socket (i.e., to the browser).

This module is also discussed in Chapter 10.

Available from CPAN. See the module manpage for more information.

Copyright © 2003 O'Reilly & Associates. All rights reserved.

  Published courtesy of O'Reilly Design by Interspire