- 论坛徽章:
- 0
|
这个server代码有什么问题,为什么不接受TERM信号,也不回收僵尸进程
<?php
/*
PHP forked daemon
Standalone PHP binary must be compiled with --enable-sockets and --enable-pcntl
Dave M. -2002
Online Services USA
*/
function sig_handler($signo) {
switch($signo) {
case SIGTERM:
// handle shutdown tasks
exit;
break;
case SIGHUP:
// handle restart tasks
break;
case SIGUSR1:
print "Caught SIGUSR1...\n";
break;
case SIGCHLD:
while( pcntl_waitpid(-1,$status,WNOHANG)>0 ) {
}
break;
case SIGINT:
exit;
default:
// not implemented yet...
break;
}
}
function interact($sock) {
if (false === ($buf = socket_read($sock, 2048, PHP_NORMAL_READ))) {
echo "socket_read() failed: reason: " . socket_strerror(socket_last_error($sock)) . "\n";
break 2;
}
$talkback = "Server echo: $buf , PID:".posix_getpid();
socket_write($sock, $talkback, strlen($talkback));
close($sock);
return 0;
}
function become_daemon() {
$child = pcntl_fork();
if($child) {
exit; // kill parent
}
posix_setsid(); // become session leader
chdir("/");
umask(0); // clear umask
return posix_getpid();
}
function open_pid_file($file) {
if(file_exists($file)) {
$fp = fopen($file,"r");
$pid = fgets($fp,1024);
fclose($fp);
if(posix_kill($pid,0)) {
print "Server already running with PID: $pid\n";
exit;
}
print "Removing PID file for defunct server process $pid\n";
if(!unlink($file)) {
print "Cannot unlink PID file $file\n";
exit;
}
}
if($fp = fopen($file,"w")) {
return $fp;
} else {
print "Unable to open PID file $file for writing...\n";
exit;
}
}
function change_identity($uid,$gid) {
global $pid_file;
if(!posix_setgid($gid)) {
print "Unable to setgid to $gid!\n";
unlink($pid_file);
exit;
}
if(!posix_setuid($uid)) {
print "Unable to setuid to $uid!\n";
unlink($pid_file);
exit;
}
}
error_reporting (4);
set_time_limit (0);
ob_implicit_flush ();
$pid_file = '/tmp/php_daemon.pid';
$underpriv_uid = '99'; // uid 99 == user nobody, at least on my system.
$underpriv_gid = '99';
$port = 8888;
$address = 0; // 0 binds to all addresses, may not work on fbsd
$quit = 0;
pcntl_signal(SIGCHLD, "sig_handler");
pcntl_signal(SIGTERM, "sig_handler");
pcntl_signal(SIGINT, "sig_handler");
$fh = open_pid_file($pid_file);
if (($sock = socket_create (AF_INET, SOCK_STREAM, 0)) < 0) {
print "socket_create() failed: reason: " . socket_strerror ($sock) . "\n";
}
if (($ret = socket_bind ($sock, $address, $port)) < 0) {
print "socket_bind() failed: reason: " . socket_strerror ($ret) . "\n";
}
if (($ret = socket_listen ($sock, 0)) < 0) {
print "socket_listen() failed: reason: " . socket_strerror ($ret) . "\n";
}
change_identity($underpriv_uid,$underpriv_gid);
print "Server ready. Waiting for connections.....\n";
$pid = become_daemon();
fputs($fh,$pid);
fclose($fh);
while(!$quit) {
if (($connection = socket_accept($sock)) < 0) {
next;
}
if( ($child = pcntl_fork()) == -1 ) {
print "Could not fork!!\n";
print "Dying...\n";
$quit++;
}
elseif($child == 0) {
socket_close($sock);
interact($connection);
exit;
}
socket_close($connection);
}
if(posix_getpid() == $pid) {
unlink($pid_file);
}
?> |
|