pricecharts

track prices of consumer electronics
Log | Files | Refs | README

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:
MDEPS | 1-
Msearch.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"); -}