line |
stmt |
bran |
cond |
sub |
pod |
time |
code |
1
|
|
|
|
|
|
|
#!/usr/bin/perl |
2
|
1
|
|
|
1
|
|
75748
|
use strict; |
|
1
|
|
|
|
|
2
|
|
|
1
|
|
|
|
|
45
|
|
3
|
|
|
|
|
|
|
#use warnings; |
4
|
|
|
|
|
|
|
#use diagnostics -verbose; |
5
|
|
|
|
|
|
|
## no critic (TestingAndDebugging::RequireUseWarnings) |
6
|
|
|
|
|
|
|
package FCGI::Daemon; |
7
|
|
|
|
|
|
|
our $VERSION = '0.20220206'; |
8
|
1
|
|
|
1
|
|
13
|
use 5.14.2; |
|
1
|
|
|
|
|
3
|
|
9
|
1
|
|
|
1
|
|
1168
|
use English '-no_match_vars'; |
|
1
|
|
|
|
|
4439
|
|
|
1
|
|
|
|
|
6
|
|
10
|
1
|
|
|
1
|
|
828
|
use BSD::Resource; # on Debian available as libbsd-resource-perl |
|
1
|
|
|
|
|
3931
|
|
|
1
|
|
|
|
|
4
|
|
11
|
1
|
|
|
1
|
|
689
|
use FCGI 0.82; # on Debian available as libfcgi-perl |
|
1
|
|
|
|
|
876
|
|
|
1
|
|
|
|
|
27
|
|
12
|
1
|
|
|
1
|
|
430
|
use FCGI::ProcManager 0.28; # on Debian available as libfcgi-procmanager-perl |
|
1
|
|
|
|
|
10045
|
|
|
1
|
|
|
|
|
57
|
|
13
|
1
|
|
|
1
|
|
1815
|
use Getopt::Std; |
|
1
|
|
|
|
|
50
|
|
|
1
|
|
|
|
|
60
|
|
14
|
1
|
|
|
1
|
|
444
|
use autouse 'Pod::Usage'=>qw(pod2usage); |
|
1
|
|
|
|
|
643
|
|
|
1
|
|
|
|
|
6
|
|
15
|
|
|
|
|
|
|
|
16
|
|
|
|
|
|
|
=head1 NAME |
17
|
|
|
|
|
|
|
|
18
|
|
|
|
|
|
|
FCGI::Daemon - Perl-aware Fast CGI daemon for use with nginx web server. |
19
|
|
|
|
|
|
|
|
20
|
|
|
|
|
|
|
=head1 VERSION |
21
|
|
|
|
|
|
|
|
22
|
|
|
|
|
|
|
Version 0.20220206 |
23
|
|
|
|
|
|
|
|
24
|
|
|
|
|
|
|
=begin comment |
25
|
|
|
|
|
|
|
=cut |
26
|
|
|
|
|
|
|
|
27
|
|
|
|
|
|
|
my %o; |
28
|
|
|
|
|
|
|
|
29
|
|
|
|
|
|
|
__PACKAGE__->run() unless caller(); # modulino i.e. executable rather than module |
30
|
|
|
|
|
|
|
|
31
|
|
|
|
|
|
|
=head2 help() |
32
|
|
|
|
|
|
|
print help screen extracted from POD |
33
|
|
|
|
|
|
|
=cut |
34
|
0
|
0
|
|
0
|
1
|
|
sub help { pod2usage(-verbose=>$ARG[0],-noperldoc=>1) and exit; } ## no critic |
35
|
|
|
|
|
|
|
|
36
|
|
|
|
|
|
|
=head2 dieif() |
37
|
|
|
|
|
|
|
exit handler |
38
|
|
|
|
|
|
|
=cut |
39
|
|
|
|
|
|
|
sub dieif { |
40
|
0
|
0
|
|
0
|
1
|
|
if($ARG[0]){ |
41
|
0
|
|
|
|
|
|
my $err=$ARG[1]; |
42
|
0
|
|
|
|
|
|
for my $f ( @o{'pidfile','sockfile'} ) { |
43
|
0
|
0
|
|
|
|
|
unlink $f if -f $f; |
44
|
|
|
|
|
|
|
} |
45
|
0
|
|
|
|
|
|
print "Error - $err:\n",$ARG[0],"\n"; |
46
|
0
|
|
|
|
|
|
exit 1; |
47
|
|
|
|
|
|
|
} |
48
|
|
|
|
|
|
|
} |
49
|
|
|
|
|
|
|
|
50
|
|
|
|
|
|
|
=head2 run() |
51
|
|
|
|
|
|
|
Modulino-style main routine |
52
|
|
|
|
|
|
|
=cut |
53
|
|
|
|
|
|
|
sub run { |
54
|
0
|
0
|
|
0
|
1
|
|
getopts('hde:f:q:p:s:g:u:m:c:l:w:',\%o) or help(0); |
55
|
0
|
0
|
|
|
|
|
help(2) if $o{'h'}; |
56
|
|
|
|
|
|
|
|
57
|
0
|
|
0
|
|
|
|
$o{sockfile}=$o{'s'}||'/var/run/fcgi-daemon.sock'; |
58
|
0
|
0
|
0
|
|
|
|
$o{pidfile}=$o{'p'}||'/var/run/fcgi-daemon.pid' if $o{'d'}; |
59
|
0
|
0
|
|
|
|
|
$o{prefork}=defined $o{'w'} ? $o{'w'} : 1; |
60
|
0
|
0
|
|
|
|
|
$o{queue}=defined $o{'q'} ? $o{'q'} : 96; |
61
|
0
|
|
0
|
|
|
|
$o{rlimit_vmem}=($o{'m'}||512)*1024*1024; |
62
|
0
|
|
0
|
|
|
|
$o{rlimit_cpu}=$o{'c'}||32; |
63
|
0
|
0
|
|
|
|
|
$o{max_evals}=defined $o{'e'} ? $o{'e'} : 10240; #max evals before exit - paranoid to free memory if leaks |
64
|
0
|
|
0
|
|
|
|
$o{file_pattern}=$o{'f'}||qr{\.pl}; |
65
|
0
|
|
0
|
|
|
|
$o{leak_threshold}=$o{'l'}||1.3; |
66
|
|
|
|
|
|
|
|
67
|
0
|
0
|
0
|
|
|
|
if($REAL_USER_ID==$EFFECTIVE_USER_ID and $EFFECTIVE_USER_ID==0){ # if run as root |
68
|
0
|
|
0
|
|
|
|
$o{gid}=$o{g}||'www-data'; $o{gid_num}=scalar getgrnam($o{gid}); |
|
0
|
|
|
|
|
|
|
69
|
0
|
|
0
|
|
|
|
$o{uid}=$o{u}||'www-data'; $o{uid_num}=scalar getpwnam($o{uid}); |
|
0
|
|
|
|
|
|
|
70
|
|
|
|
|
|
|
} |
71
|
|
|
|
|
|
|
|
72
|
|
|
|
|
|
|
local $SIG{INT}= local $SIG{TERM}= sub{ |
73
|
|
|
|
|
|
|
# actually FCGI::ProcManager override our TERM handler so .sock and .pid files will be removed only by sysv script... :( |
74
|
0
|
0
|
|
0
|
|
|
$o{fcgi_pm}->pm_remove_pid_file() if $o{fcgi_pm}; |
75
|
0
|
|
|
|
|
|
for my $f ( @o{'pidfile','sockfile'} ) { |
76
|
0
|
0
|
|
|
|
|
unlink $f if -f $f; |
77
|
|
|
|
|
|
|
} |
78
|
0
|
0
|
|
|
|
|
$o{fcgi_pm}->pm_die() if $o{fcgi_pm}; #pm_die() does not return |
79
|
0
|
|
|
|
|
|
exit 0; |
80
|
0
|
|
|
|
|
|
}; |
81
|
|
|
|
|
|
|
|
82
|
|
|
|
|
|
|
# daemonize |
83
|
0
|
0
|
|
|
|
|
if($o{'d'}){ |
84
|
0
|
|
|
|
|
|
chdir '/'; # this is good practice for unmounting |
85
|
0
|
|
|
|
|
|
local $PROGRAM_NAME='FCGI::Daemon'; |
86
|
0
|
0
|
|
|
|
|
defined(my $pid=fork) or die "Can't fork: $!"; |
87
|
0
|
0
|
|
|
|
|
exit if $pid; |
88
|
1
|
0
|
|
1
|
|
457
|
eval {use POSIX qw(setsid); POSIX::setsid();} or die q{Can't start a new session: }.$OS_ERROR; |
|
1
|
|
|
|
|
7
|
|
|
1
|
|
|
|
|
7
|
|
|
0
|
|
|
|
|
|
|
|
0
|
|
|
|
|
|
|
89
|
0
|
|
|
|
|
|
open *STDIN,'<','/dev/null'; |
90
|
0
|
|
|
|
|
|
open *STDOUT,'>>','/dev/null'; |
91
|
0
|
|
|
|
|
|
open *STDERR,'>>','/dev/null'; |
92
|
0
|
|
|
|
|
|
umask 022; |
93
|
|
|
|
|
|
|
} |
94
|
|
|
|
|
|
|
|
95
|
0
|
|
|
|
|
|
my %req_env; |
96
|
|
|
|
|
|
|
$o{fcgi_pm}=FCGI::ProcManager->new({n_processes=>$o{prefork}, |
97
|
|
|
|
|
|
|
die_timeout=>28, |
98
|
|
|
|
|
|
|
pid_fname=>$o{pidfile} |
99
|
0
|
|
|
|
|
|
}); |
100
|
0
|
|
|
|
|
|
print "Opening socket $o{sockfile}\n"; |
101
|
|
|
|
|
|
|
my $rqst=FCGI::Request(\*STDIN,\*STDOUT,\*STDERR,\%req_env, |
102
|
0
|
0
|
|
|
|
|
FCGI::OpenSocket($o{sockfile},$o{prefork}*$o{queue}), |
103
|
|
|
|
|
|
|
FCGI::FAIL_ACCEPT_ON_INTR()) |
104
|
|
|
|
|
|
|
or die "Error: Unable to create FCGI::Request..."; |
105
|
|
|
|
|
|
|
|
106
|
0
|
0
|
0
|
|
|
|
if(defined $o{gid_num} and defined $o{uid_num}){ # if run as root |
107
|
|
|
|
|
|
|
chown $o{uid_num},$o{gid_num},$o{sockfile} # chown SOCKfile |
108
|
0
|
0
|
|
|
|
|
or dieif($OS_ERROR,'Unable to chown SOCKfile'); |
109
|
|
|
|
|
|
|
} |
110
|
|
|
|
|
|
|
|
111
|
0
|
|
|
|
|
|
$o{fcgi_pm}->pm_manage(); # from now on we are worker process |
112
|
|
|
|
|
|
|
|
113
|
|
|
|
|
|
|
# drop privileges if run as root |
114
|
0
|
0
|
0
|
|
|
|
if(defined $o{gid_num} and defined $o{uid_num}){ |
115
|
0
|
|
|
|
|
|
my $gid = getgrnam($o{gid}); |
116
|
0
|
|
|
|
|
|
$EFFECTIVE_GROUP_ID = "$gid $gid"; |
117
|
0
|
|
|
|
|
|
dieif($OS_ERROR,'Unable to effective group_id to '.$o{gid}); |
118
|
0
|
|
|
|
|
|
$REAL_GROUP_ID = $gid; |
119
|
0
|
|
|
|
|
|
dieif($OS_ERROR,'Unable to change real group_id to '.$o{gid}); |
120
|
0
|
|
|
|
|
|
my $uid = getpwnam($o{uid}); |
121
|
0
|
|
|
|
|
|
$EFFECTIVE_USER_ID = $uid; |
122
|
0
|
|
|
|
|
|
dieif($OS_ERROR,'Unable to change effective user_id to '.$o{uid}); |
123
|
0
|
|
|
|
|
|
$REAL_USER_ID = $uid; |
124
|
0
|
|
|
|
|
|
dieif($OS_ERROR,'Unable to change real user_id to '.$o{uid}); |
125
|
|
|
|
|
|
|
} |
126
|
|
|
|
|
|
|
|
127
|
|
|
|
|
|
|
## set rlimit(s) |
128
|
|
|
|
|
|
|
setrlimit(RLIMIT_AS, $o{rlimit_vmem}, $o{rlimit_vmem}) |
129
|
0
|
0
|
|
|
|
|
or warn "Unable to set RLIMIT_AS.\n"; |
130
|
|
|
|
|
|
|
setrlimit(RLIMIT_CPU, $o{rlimit_cpu}, $o{rlimit_cpu}) |
131
|
0
|
0
|
|
|
|
|
or warn "Unable to set RLIMIT_CPU.\n"; |
132
|
|
|
|
|
|
|
|
133
|
|
|
|
|
|
|
REQ_LOOP: # main loop |
134
|
0
|
|
|
|
|
|
while($rqst->Accept()>=0){ |
135
|
|
|
|
|
|
|
|
136
|
0
|
|
|
|
|
|
$req_env{'PATH_INFO'}=$req_env{'SCRIPT_FILENAME'}; |
137
|
0
|
|
|
|
|
|
$req_env{'SCRIPT_FILENAME'}=get_file_from_path($req_env{SCRIPT_FILENAME}); |
138
|
0
|
|
|
|
|
|
$req_env{'PATH_INFO'}=~s/$req_env{'SCRIPT_FILENAME'}//; |
139
|
0
|
|
|
|
|
|
$req_env{'SCRIPT_NAME'}=$req_env{'SCRIPT_FILENAME'}; |
140
|
0
|
|
|
|
|
|
$req_env{'SCRIPT_NAME'}=~s/$req_env{'DOCUMENT_ROOT'}//; |
141
|
|
|
|
|
|
|
|
142
|
|
|
|
|
|
|
# check if script (exacutable, readable, non-zero size) |
143
|
0
|
0
|
|
|
|
|
unless(-x -s -r $req_env{'SCRIPT_FILENAME'}){ |
144
|
0
|
|
|
|
|
|
print "Content-type: text/plain\r\n\r\n"; |
145
|
0
|
|
|
|
|
|
$_="Error: No such CGI app - $req_env{SCRIPT_FILENAME} may not exist or is not executable by this process.\n"; |
146
|
0
|
|
|
|
|
|
print $_; |
147
|
0
|
|
|
|
|
|
print {*STDERR} $_; |
|
0
|
|
|
|
|
|
|
148
|
0
|
|
|
|
|
|
next; |
149
|
|
|
|
|
|
|
} |
150
|
|
|
|
|
|
|
|
151
|
0
|
|
|
|
|
|
local @ENV{keys %req_env}=values %req_env; |
152
|
0
|
0
|
|
|
|
|
chdir $1 if $req_env{'SCRIPT_FILENAME'}=~m{^(.*)\/}; # cd to the script's local directory |
153
|
|
|
|
|
|
|
|
154
|
|
|
|
|
|
|
# Fast Perl-CGI processing |
155
|
0
|
0
|
0
|
|
|
|
if($o{max_evals}>0 and $req_env{'SCRIPT_FILENAME'}=~m{$o{file_pattern}\z}){ # detect if perl script |
156
|
0
|
|
|
|
|
|
my %allvars; |
157
|
0
|
|
|
|
|
|
@allvars{keys %main::}=(); |
158
|
|
|
|
|
|
|
{ |
159
|
0
|
|
|
0
|
|
|
local *CORE::GLOBAL::exit=sub { die 'notr3a11yeXit' }; |
|
0
|
|
|
|
|
|
|
|
0
|
|
|
|
|
|
|
160
|
0
|
|
|
|
|
|
local $0=$req_env{SCRIPT_FILENAME}; #fixes FindBin (in English $0 means $PROGRAM_NAME) |
161
|
1
|
|
|
1
|
|
506
|
no strict; ## no critic :: default for Perl5 |
|
1
|
|
|
|
|
2
|
|
|
1
|
|
|
|
|
524
|
|
162
|
0
|
|
|
|
|
|
do $0; # do $0; could be enough for strict scripts |
163
|
0
|
0
|
|
|
|
|
if($EVAL_ERROR){ |
164
|
0
|
|
|
|
|
|
$EVAL_ERROR=~s{\n+\z}{}; |
165
|
0
|
0
|
|
|
|
|
print {*STDERR} "$0\n$EVAL_ERROR\n\b" unless $EVAL_ERROR =~ m{^notr3a11yeXit}; |
|
0
|
|
|
|
|
|
|
166
|
|
|
|
|
|
|
} |
167
|
|
|
|
|
|
|
} |
168
|
|
|
|
|
|
|
|
169
|
|
|
|
|
|
|
#untested experimental callback to execute on script exit |
170
|
|
|
|
|
|
|
#$_{$req_env{SCRIPT_FILENAME}}->{SIGTERM}() if defined $_{$req_env{SCRIPT_FILENAME}}->{SIGTERM}; |
171
|
|
|
|
|
|
|
#Perl scripts can cache persistent data in $_{$0}->{mydata} |
172
|
|
|
|
|
|
|
#However if you store too much data it may trigger termination by rlimit |
173
|
|
|
|
|
|
|
#After DO/EVAL $_{$0}->{'SIGTERM'} is being called so termination handler |
174
|
|
|
|
|
|
|
#can be used to close DB connections etc. |
175
|
|
|
|
|
|
|
#$_{$0}->{'SIGTERM'}=sub { print "I closed my handles"; }; |
176
|
|
|
|
|
|
|
|
177
|
0
|
|
|
|
|
|
foreach(keys %main::){ # cleanup garbage after do() |
178
|
0
|
0
|
|
|
|
|
next if exists $allvars{$_}; |
179
|
0
|
0
|
|
|
|
|
next if m{::$}; |
180
|
0
|
0
|
|
|
|
|
next if m{^_}; |
181
|
0
|
|
|
|
|
|
delete $main::{$_}; |
182
|
|
|
|
|
|
|
} |
183
|
|
|
|
|
|
|
|
184
|
0
|
0
|
|
|
|
|
if(open my $STAT,'<',"/proc/$$/status"){ |
185
|
0
|
|
|
|
|
|
my %stat; |
186
|
0
|
|
|
|
|
|
while(my ($k,$v)=split /\:\s+/,<$STAT>){ |
187
|
0
|
|
|
|
|
|
chop $v; |
188
|
0
|
|
|
|
|
|
$stat{$k}=$v; |
189
|
|
|
|
|
|
|
} |
190
|
0
|
|
|
|
|
|
close $STAT; |
191
|
|
|
|
|
|
|
# check if child takes too much resident memory and terminate if necessary |
192
|
0
|
0
|
|
|
|
|
if($stat{VmSize}/$stat{VmRSS}<$o{leak_threshold}){ |
193
|
0
|
|
|
|
|
|
print {*STDERR} 'fcgi-daemon :: terminating child - memory leak? ' |
194
|
0
|
|
|
|
|
|
."VmSize:$stat{VmSize}; VmRSS:$stat{VmRSS}; Ratio:".$stat{VmSize}/$stat{VmRSS}; |
195
|
0
|
|
|
|
|
|
exit; |
196
|
|
|
|
|
|
|
} |
197
|
|
|
|
|
|
|
} |
198
|
0
|
0
|
|
|
|
|
exit unless --$o{max_evals}; |
199
|
0
|
|
|
|
|
|
next REQ_LOOP; |
200
|
|
|
|
|
|
|
} |
201
|
|
|
|
|
|
|
|
202
|
|
|
|
|
|
|
# Normal CGI processing |
203
|
0
|
|
|
|
|
|
$o{fcgi_pm}->pm_pre_dispatch(); |
204
|
0
|
|
|
|
|
|
local $OUTPUT_AUTOFLUSH=1; # select below is equivalent of: my $oldfh=select($CERR); $|=1; select($oldfh); |
205
|
0
|
|
|
|
|
|
pipe my($PERR),my($CERR); select((select($CERR),$OUTPUT_AUTOFLUSH=1)[0]); #prepare child-to-parent pipe and swith off buffering |
|
0
|
|
|
|
|
|
|
206
|
0
|
|
|
|
|
|
pipe my($CIN),my($PIN); select((select($PIN),$OUTPUT_AUTOFLUSH=1)[0]); #prepare parent-to-child pipe and swith off buffering |
|
0
|
|
|
|
|
|
|
207
|
|
|
|
|
|
|
|
208
|
0
|
|
|
|
|
|
my $pid=open my($COUT),"-|"; ## fork and pipe to us |
209
|
0
|
0
|
|
|
|
|
unless(defined $pid){ |
210
|
0
|
|
|
|
|
|
print "Content-type: text/plain\r\n\r\n" |
211
|
|
|
|
|
|
|
."Error: CGI app returned no output - Executing $req_env{SCRIPT_FILENAME} failed !\n"; |
212
|
0
|
|
|
|
|
|
next; |
213
|
|
|
|
|
|
|
} |
214
|
0
|
|
|
|
|
|
$rqst->Detach(); # needed to restore original STDIN,STDOUT,STDERR |
215
|
|
|
|
|
|
|
|
216
|
0
|
0
|
|
|
|
|
unless($pid){ #### Child #### |
217
|
0
|
|
|
|
|
|
close $PIN; # <--perhaps not really necessary |
218
|
0
|
0
|
|
|
|
|
open *STDIN,'<&=',$CIN or die 'unable to reopen STDIN'; |
219
|
0
|
0
|
|
|
|
|
open *STDERR,'>&=',$CERR or die 'unable to reopen STDERR'; |
220
|
0
|
0
|
|
|
|
|
exec $req_env{'SCRIPT_FILENAME'} or die "exec failed"; # running the cgi app (exec does not return so child terminates here) |
221
|
|
|
|
|
|
|
}else{ #### Parent #### |
222
|
0
|
|
|
|
|
|
close $CIN; # <--perhaps not really necessary |
223
|
0
|
|
|
|
|
|
close $CERR; # *must* close child's file handle to avoid deadlock |
224
|
0
|
|
|
|
|
|
$rqst->Attach(); #reattach FCGI's STDIN,STDOUT,STDERR |
225
|
|
|
|
|
|
|
|
226
|
|
|
|
|
|
|
## send STDIN to child |
227
|
0
|
|
|
|
|
|
my $buffer; |
228
|
|
|
|
|
|
|
#print {$PIN} $buffer while (read *STDIN,$buffer,$ENV{'CONTENT_LENGTH'}); ## longer version below may be safer for very long input. |
229
|
0
|
0
|
0
|
|
|
|
if($req_env{'REQUEST_METHOD'} =~ /(?:POST|PUT)/ and $req_env{'CONTENT_LENGTH'}!=0){ |
230
|
0
|
|
|
|
|
|
my $bytes=0; |
231
|
0
|
|
|
|
|
|
while ($bytes<$req_env{'CONTENT_LENGTH'}){ |
232
|
0
|
|
|
|
|
|
$bytes+=read *STDIN,$buffer,($req_env{'CONTENT_LENGTH'}-$bytes); |
233
|
0
|
0
|
0
|
|
|
|
last if ($bytes==0 or not defined $bytes); |
234
|
0
|
|
|
|
|
|
print {$PIN} $buffer; |
|
0
|
|
|
|
|
|
|
235
|
|
|
|
|
|
|
} } |
236
|
0
|
|
|
|
|
|
close $PIN; |
237
|
|
|
|
|
|
|
|
238
|
1
|
|
|
1
|
|
487
|
use IO::Select; # non-blocking read from child's redirected STDOUT and STDERR |
|
1
|
|
|
|
|
1479
|
|
|
1
|
|
|
|
|
487
|
|
239
|
0
|
|
|
|
|
|
my $sel = IO::Select->new($COUT,$PERR); |
240
|
0
|
|
|
|
|
|
while(my @ready=$sel->can_read){ |
241
|
0
|
|
|
|
|
|
for my $FH (@ready){ |
242
|
0
|
0
|
|
|
|
|
if(0==sysread $FH,$buffer,4096){ |
243
|
0
|
|
|
|
|
|
$sel->remove($FH); |
244
|
0
|
|
|
|
|
|
close $FH; |
245
|
|
|
|
|
|
|
}else{ |
246
|
0
|
0
|
|
|
|
|
print {$FH==$COUT ? *STDOUT:*STDERR} $buffer; |
|
0
|
|
|
|
|
|
|
247
|
|
|
|
|
|
|
} } } |
248
|
0
|
|
|
|
|
|
waitpid $pid,0; |
249
|
0
|
|
|
|
|
|
$rqst->Finish(); |
250
|
|
|
|
|
|
|
} |
251
|
0
|
|
|
|
|
|
$o{fcgi_pm}->pm_post_dispatch(); |
252
|
|
|
|
|
|
|
} |
253
|
0
|
|
|
|
|
|
return; |
254
|
|
|
|
|
|
|
} |
255
|
|
|
|
|
|
|
|
256
|
|
|
|
|
|
|
# overriding process names |
257
|
|
|
|
|
|
|
sub FCGI::ProcManager::pm_change_process_name { |
258
|
0
|
|
|
0
|
1
|
|
my ($self,$name)=@_; |
259
|
0
|
|
|
|
|
|
my %p=( 'perl-fcgi-pm' =>'FCGI::Daemon', |
260
|
|
|
|
|
|
|
'perl-fcgi' =>'FCGI::Daemon-worker', |
261
|
|
|
|
|
|
|
); |
262
|
0
|
0
|
|
|
|
|
$0=$p{$name} if $p{$name} ne ''; ## no critic |
263
|
0
|
|
|
|
|
|
return; |
264
|
|
|
|
|
|
|
} |
265
|
|
|
|
|
|
|
|
266
|
|
|
|
|
|
|
=head2 get_file_from_path() |
267
|
|
|
|
|
|
|
Find first file in path |
268
|
|
|
|
|
|
|
=cut |
269
|
|
|
|
|
|
|
sub get_file_from_path { |
270
|
0
|
|
|
0
|
1
|
|
local $_=shift; |
271
|
0
|
|
|
|
|
|
my $file=''; |
272
|
0
|
|
|
|
|
|
for(split '/',$_){ |
273
|
0
|
0
|
|
|
|
|
next if $_ eq ''; |
274
|
0
|
|
|
|
|
|
$file.='/'.$_; |
275
|
0
|
0
|
|
|
|
|
last if -f -s $file; |
276
|
|
|
|
|
|
|
} |
277
|
0
|
|
|
|
|
|
return $file; |
278
|
|
|
|
|
|
|
} |
279
|
|
|
|
|
|
|
|
280
|
|
|
|
|
|
|
1; |
281
|
|
|
|
|
|
|
__END__ |