, resource.cgi:
use warnings;
use strict;
use Reader;
use CGI qw/ :standard /;
print header("text/plain"),
"Contents:\n",
Reader::data,
"-" x 40, "\n";
Content-Type: text/plain; charset=ISO-8859-1
Contents:
This is a data file
with some very interesting
bits.
----------------------------------------
Reader.pm, :
package Reader;
use warnings;
use strict;
use Fcntl qw/ :DEFAULT :flock :seek /;
use POSIX qw/ setsid /;
:
my $PIDFILE = "/tmp/reader.pid";
my $DATA = "/tmp/file.dat";
my $PIPE = "/tmp/reader.pipe";
Sub import use Module. , . $PIDFILE.
sub import {
return unless my $fh = take_lock();
my $child = fork;
die "$0: fork: $!" unless defined $child;
if ($child) {
print $fh "$child\n" or die "$0: write $PIDFILE: $!";
close $fh or die "$0: close $PIDFILE: $!";
return;
}
close $fh;
chdir "/";
open STDIN, "<", "/dev/null";
open STDOUT, ">", "/dev/null";
open STDERR, ">", "/dev/null";
setsid;
open $fh, "<", $DATA or die;
undef $/;
my $data = <$fh>;
close $fh;
while (1) {
open my $fh, ">", $PIPE or die;
print $fh $data or die;
close $fh;
}
}
, $PIDFILE. , , , , .
sub take_lock {
sysopen my $fh, $PIDFILE, O_RDWR | O_CREAT or die "$0: open $PIDFILE: $!";
flock $fh => LOCK_EX or die "$0: flock $PIDFILE: $!";
my $pid = <$fh>;
if (defined $pid) {
chomp $pid;
if (kill 0 => $pid) {
close $fh;
return;
}
}
else {
die "$0: readline $PIDFILE: $!" if $!;
}
sysseek $fh, 0, SEEK_SET or die "$0: sysseek $PIDFILE: $!";
truncate $fh, 0 or die "$0: truncate $PIDFILE: $!";
unless (-p $PIPE) {
system("mknod", $PIPE, "p") == 0
or die "$0: mknod exited " . ($? >> 8);
}
$fh;
}
, :
sub data {
open my $fh, "<", $DATA or die "$0: open $DATA: $!";
local $/;
scalar <$fh>;
}
:
1;
, . - , .
, , , , .