]> Sergey Matveev's repositories - public-inbox.git/blobdiff - lib/PublicInbox/Daemon.pm
daemon: introduce host_with_port for identifying sockets
[public-inbox.git] / lib / PublicInbox / Daemon.pm
index 2878e33b7a155aff13ed0bffdc0c832d7b464c38..c101ecb7ad538313324879c4986587ca30fee0d8 100644 (file)
@@ -1,10 +1,8 @@
 # Copyright (C) 2015 all contributors <meta@public-inbox.org>
 # License: AGPLv3 or later (https://www.gnu.org/licenses/agpl-3.0.txt)
-package PublicInbox::Daemon; # empty class :p
-
 # contains common daemon code for the nntpd and httpd servers.
 # This may be used for read-only IMAP server if we decide to implement it.
-package main;
+package PublicInbox::Daemon;
 use strict;
 use warnings;
 use Getopt::Long qw/:config gnu_getopt no_ignore_case auto_abbrev/;
@@ -67,12 +65,12 @@ sub daemon_prepare ($) {
                        warn "error binding $l: $!\n";
                }
        }
-       die 'No listeners bound' unless @listeners;
+       die "No listeners bound\n" unless @listeners;
 }
 
 sub daemonize () {
-       chdir '/' or die "chdir failed: $!\n";
-       open(STDIN, '+<', '/dev/null') or die "redirect stdin failed: $!\n";
+       chdir '/' or die "chdir failed: $!";
+       open(STDIN, '+<', '/dev/null') or die "redirect stdin failed: $!";
 
        return unless (defined $pid_file || defined $group || defined $user
                        || $daemonize);
@@ -159,20 +157,23 @@ sub reopen_logs {
 
 sub sockname ($) {
        my ($s) = @_;
-       my $n = getsockname($s) or return;
-       my ($port, $addr);
-       if (length($n) >= 28) {
+       my $addr = getsockname($s) or return;
+       my ($host, $port) = host_with_port($addr);
+       "$host:$port";
+}
+
+sub host_with_port ($) {
+       my ($addr) = @_;
+       my ($port, $host);
+       if (length($addr) >= 28) {
                require Socket6;
-               ($port, $addr) = Socket6::unpack_sockaddr_in6($n);
-       } else {
-               ($port, $addr) = Socket::sockaddr_in($n);
-       }
-       if (length($addr) == 4) {
-               $n = Socket::inet_ntoa($addr)
+               ($port, $host) = Socket6::unpack_sockaddr_in6($addr);
+               $host = '['.Socket6::inet_ntop(Socket6::AF_INET6(), $host).']';
        } else {
-               $n = '['.Socket6::inet_ntop(Socket6::AF_INET6(), $addr).']';
+               ($port, $host) = Socket::sockaddr_in($addr);
+               $host = Socket::inet_ntoa($host);
        }
-       $n .= ":$port";
+       ($host, $port);
 }
 
 sub inherit () {
@@ -238,12 +239,10 @@ sub do_fork () {
        my $new = POSIX::SigSet->new;
        $new->fillset;
        my $old = POSIX::SigSet->new;
-       POSIX::sigprocmask(&POSIX::SIG_BLOCK, $new, $old) or
-                               die "SIG_BLOCK: $!\n";
+       POSIX::sigprocmask(&POSIX::SIG_BLOCK, $new, $old) or die "SIG_BLOCK: $!";
        my $pid = fork;
        my $err = $!;
-       POSIX::sigprocmask(&POSIX::SIG_SETMASK, $old) or
-                               die "SIG_SETMASK: $!\n";
+       POSIX::sigprocmask(&POSIX::SIG_SETMASK, $old) or die "SIG_SETMASK: $!";
        ($pid, $err);
 }
 
@@ -254,7 +253,7 @@ sub upgrade_aborted ($) {
        return unless $pid_file;
 
        my $file = $pid_file;
-       $file =~ s/\.oldbin\z// or die "BUG: no '.oldbin' suffix in $file\n";
+       $file =~ s/\.oldbin\z// or die "BUG: no '.oldbin' suffix in $file";
        unlink_pid_file_safe_ish($$, $pid_file);
        $pid_file = $file;
        eval { write_pid($pid_file) };
@@ -289,8 +288,8 @@ sub unlink_pid_file_safe_ish ($$) {
 }
 
 sub master_loop {
-       pipe(my ($p0, $p1)) or die "failed to create parent-pipe: $!\n";
-       pipe(my ($r, $w)) or die "failed to create self-pipe: $!\n";
+       pipe(my ($p0, $p1)) or die "failed to create parent-pipe: $!";
+       pipe(my ($r, $w)) or die "failed to create self-pipe: $!";
        IO::Handle::blocking($w, 0);
        my $set_workers = $worker_processes;
        my @caught;
@@ -363,6 +362,7 @@ sub daemon_loop ($$) {
        my ($refresh, $post_accept) = @_;
        my $parent_pipe;
        if ($worker_processes > 0) {
+               $refresh->(); # preload by default
                $parent_pipe = master_loop(); # returns if in child process
                my $fd = fileno($parent_pipe);
                Danga::Socket->AddOtherFds($fd => sub { kill('TERM', $$) } );
@@ -370,10 +370,10 @@ sub daemon_loop ($$) {
                reopen_logs();
                $set_user->() if $set_user;
                $SIG{USR2} = sub { worker_quit() if upgrade() };
+               $refresh->();
        }
        $uid = $gid = undef;
        reopen_logs();
-       $refresh->();
        $SIG{QUIT} = $SIG{INT} = $SIG{TERM} = *worker_quit;
        $SIG{USR1} = *reopen_logs;
        $SIG{HUP} = $refresh;
@@ -384,7 +384,7 @@ sub daemon_loop ($$) {
 }
 
 
-sub daemon_run ($$$) {
+sub run ($$$) {
        my ($default, $refresh, $post_accept) = @_;
        daemon_prepare($default);
        daemonize();