File Coverage

blib/lib/App/CLI/Plugin/Daemonize.pm
Criterion Covered Total %
statement 12 35 34.2
branch 0 22 0.0
condition n/a
subroutine 4 6 66.6
pod 1 2 50.0
total 17 65 26.1


line stmt bran cond sub pod time code
1             package App::CLI::Plugin::Daemonize;
2              
3             =head1 NAME
4              
5             App::CLI::Plugin::Daemonize - for App::CLI::Plugin::Extension daemonize plugin module
6              
7             =head1 VERSION
8              
9             1.0
10              
11             =head1 SYNOPSIS
12              
13             # MyApp.pm
14             package MyApp;
15            
16             use strict;
17             use base qw(App::CLI::Extension);
18            
19             # extension method
20             __PACKAGE__->load_plugins(qw(Daemonize));
21            
22             # extension method
23             __PACKAGE__->config( deemonize => 1 );
24            
25             1;
26            
27             # MyApp/Daemonize.pm
28             package MyApp::Daemonize;
29            
30             use strict;
31             use base qw(App::CLI::Command);
32            
33             sub options { return ("daemonize" => "daemonize") };
34            
35             sub run {
36            
37             my($self, @argv) = @_;
38             # anything to do...
39             }
40            
41             1;
42            
43             # myapp
44             #!/usr/bin/perl
45            
46             use strict;
47             use MyApp;
48            
49             MyApp->dispatch;
50            
51             # daemon execute
52             [kurt@localhost ~] ./myapp daemonize
53              
54             =head1 DESCRIPTION
55              
56             App::CLI::Plugin::Daemonize - daemonize plugin module
57              
58             daemonize method setting
59              
60             # enable daemonize
61             __PACKAGE__->config( daemonize => 1 );
62              
63             or if --daemonize option is defined. it applies.
64              
65             # in MyApp/**.pm
66             sub options {
67             return ( "daemonize" => "daemonize" ) ;
68             }
69            
70             # execute
71             [kurt@localhost ~] ./myapp daemonize --daemonize
72              
73             =head1 METHOD
74              
75             =head2 daemonize
76              
77             Enable daemonize. It usually runs in the setup method, no explicit attempt to
78              
79             =cut
80              
81 1     1   6 use strict;
  1         1  
  1         37  
82 1     1   5 use warnings;
  1         1  
  1         33  
83 1     1   5 use File::Spec;
  1         1  
  1         29  
84 1     1   1184 use POSIX qw(setsid);
  1         11487  
  1         8  
85              
86             our $VERSION = '1.0';
87              
88             sub setup {
89              
90 0     0 0   my($self, @argv) = @_;
91              
92 0 0         my $daemonize = (exists $self->config->{daemonize}) ? $self->config->{daemonize} : 0;
93 0 0         if (exists $self->{daemonize}) {
94 0           $daemonize = $self->{daemonize};
95             }
96              
97 0 0         if ($daemonize) {
98 0           $self->daemonize;
99             }
100              
101 0           $self->maybe::next::method(@argv);
102             }
103              
104             sub daemonize {
105              
106 0     0 1   my $self = shift;
107              
108 0           my $devnull = File::Spec->devnull;
109              
110             # detach parent process
111 0           $SIG{CHLD} = 'IGNORE';
112 0 0         defined(my $pid = fork) or $self->throw("can not fork. $!");
113 0 0         if ($pid < 0) {
114 0           $self->throw("cat not fork. pid:$pid");
115             }
116 0 0         if ($pid) {
117 0           exit;
118             }
119              
120             # change umask
121 0           umask 0;
122              
123             # pgrp and session leader
124 0           my $sid = POSIX::setsid;
125 0 0         if($sid < 0) {
126 0           $self->throw("can not setsid. sid:$sid");
127             }
128              
129             # chdir /
130 0 0         chdir "/" or $self->throw("can not chdir /. $!");
131              
132 0 0         open STDIN, "<", $devnull or $self->throw("can not open STDIN");
133 0 0         open STDOUT, ">", $devnull or $self->throw("can not open STDOUT");
134 0 0         open STDERR, ">&STDOUT" or $self->throw("can not open STDERR");
135             }
136              
137             1;
138              
139             __END__