|
  
|
1#
发表于 2009-12-30 19:49
| 只看该作者
Forked PHP Daemon Example
- <?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) {
- // Custom code goes here... e.g: socket_read() socket_write()...
- }
- 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 = 10000;
- $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);
- }
- ?>
复制代码 |
|