commit efadab27819106c4dc6d2995c32ee1d73ec6d226
parent 4e6655bfe55a8e4a5f392f14fcb4098c5f0c61a5
Author: Kyle Milz <kyle@getaddrinfo.net>
Date: Tue, 18 Nov 2014 04:27:41 -0700
search: use double fork() instead of Proc::Daemon
Diffstat:
M | DEPS | | | 1 | - |
M | search.pl | | | 86 | +++++++++++++++++++++++++++++++++++++++++++------------------------------------ |
2 files changed, 47 insertions(+), 40 deletions(-)
diff --git a/DEPS b/DEPS
@@ -7,7 +7,6 @@ p5-Getopt-Std
p5-HTML-Grabber
p5-LWP
p5-POSIX
-p5-Proc-Daemon
p5-SVG
p5-Template-Toolkit
p5-Unix-Syslog
diff --git a/search.pl b/search.pl
@@ -7,7 +7,6 @@ use FCGI;
use Getopt::Std;
use Template;
use PriceChart::Shared;
-use Proc::Daemon;
use Unix::Syslog qw(:macros :subs);
use URI::Escape;
@@ -21,35 +20,58 @@ if (-e $socket_file) {
exit;
}
-openlog("pricechart_search", 0, LOG_DAEMON);
-syslog(LOG_INFO, "startup");
+if (!$args{d} && fork()) {
+ exit;
+}
-my (undef, undef, $www_uid) = getpwnam("www");
-my (undef, undef, undef, $daemon_gid) = getpwnam("daemon");
+openlog("pricechart_search", LOG_PID, LOG_DAEMON);
my $socket = FCGI::OpenSocket($socket_file, 1024);
-chown $www_uid, $daemon_gid, $socket_file;
-syslog(LOG_INFO, "$socket_file created");
+syslog(LOG_DEBUG, "$socket_file created");
+
+if (my $child_pid = fork()) {
+ # keep the parent around to clean up the socket after we're done
+
+ $SIG{INT} = \&parent_sig;
+ $SIG{TERM} = \&parent_sig;
+ sub parent_sig
+ {
+ my $signal = shift;
+ kill $signal, $child_pid;
+ }
+
+ # wait for the child to finish
+ waitpid($child_pid, 0);
+
+ FCGI::CloseSocket($socket);
+ unlink($socket_file) or
+ syslog(LOG_WARNING, "could not unlink $socket_file: $!");
+ closelog();
+ exit;
+}
+
+my $uid = getpwnam("www");
+my $gid = getgrnam("daemon");
+
+# change ownership on socket otherwise httpd can't talk to us
+chown $uid, $gid, $socket_file;
+
+# drop privileges
+$< = $> = $uid;
+$( = $) = "$gid $gid";
my $request = FCGI::Request(\*STDIN, \*STDOUT, \*STDERR, \%ENV,
$socket, FCGI::FAIL_ACCEPT_ON_INTR);
-if ($args{d}) {
- # stay in foreground, catch ctrl-c's
- $SIG{INT} = \&sig_handler;
-}
-else {
- # background
- my $daemon = Proc::Daemon->new(
- setuid => $www_uid,
- work_dir => "/var/www",
- dont_close_fd => [ $socket ],
- );
- $daemon->Init();
-}
+$SIG{INT} = \&child_sig;
+$SIG{TERM} = \&child_sig;
+sub child_sig
+{
+ my $signame = shift;
-# shut down cleanly on kill
-$SIG{TERM} = \&sig_handler;
+ $request->LastCall();
+ syslog(LOG_DEBUG, "caught SIG$signame");
+}
my $config = {
# XXX: this needs to be fixed
@@ -58,13 +80,13 @@ my $config = {
my $template = Template->new($config);
my $dbh = get_dbh();
-syslog(LOG_INFO, "database opened");
+syslog(LOG_DEBUG, "database opened");
my $sql = "select part_num, manufacturer, description from products " .
"where description like ? or part_num like ? or manufacturer like ?";
my $search_sth = $dbh->prepare($sql);
-syslog(LOG_INFO, "ready, listening for connections");
+syslog(LOG_INFO, "startup");
while ($request->Accept() >= 0) {
print "Content-Type: text/html\r\n\r\n";
my (undef, $input) = split("=", $ENV{QUERY_STRING});
@@ -83,19 +105,5 @@ while ($request->Accept() >= 0) {
$template->process("search.html", $vars) || print $template->error();
}
-
-syslog(LOG_INFO, "shutting down");
-
-FCGI::CloseSocket($socket);
-unlink($socket_file) or syslog(LOG_WARNING, "could not unlink $socket_file: $!");
-
-closelog();
+syslog(LOG_INFO, "shut down");
$dbh->disconnect();
-
-sub sig_handler
-{
- my $signame = shift;
-
- $request->LastCall();
- syslog(LOG_INFO, "caught SIG$signame");
-}