You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
162 lines
4.1 KiB
162 lines
4.1 KiB
4 years ago
|
<?php
|
||
|
|
||
3 years ago
|
ini_set('display_errors', 1);
|
||
3 years ago
|
|
||
3 years ago
|
error_reporting(E_ALL);
|
||
|
|
||
3 years ago
|
define('BASE_PATH', __DIR__);
|
||
|
|
||
|
require_once BASE_PATH . '/../config/config.php';
|
||
|
|
||
3 years ago
|
class Daemon
|
||
|
{
|
||
4 years ago
|
|
||
|
private $pidfile;
|
||
3 years ago
|
private $cmdlist = array(
|
||
|
"start",
|
||
|
"stop"
|
||
|
);
|
||
4 years ago
|
|
||
3 years ago
|
function __construct()
|
||
|
{
|
||
4 years ago
|
$this->pidfile = dirname(__FILE__) . '/svnadmind.pid';
|
||
|
}
|
||
|
|
||
3 years ago
|
private function init_daemon()
|
||
|
{
|
||
4 years ago
|
$pid = pcntl_fork();
|
||
|
if ($pid < 0) {
|
||
3 years ago
|
exit("pcntl_fork 错误");
|
||
4 years ago
|
} elseif ($pid > 0) {
|
||
|
exit(0);
|
||
|
}
|
||
|
$sid = posix_setsid();
|
||
|
if (!$sid) {
|
||
3 years ago
|
exit("posix_setsid 错误");
|
||
4 years ago
|
}
|
||
|
$pid = pcntl_fork();
|
||
|
if ($pid < 0) {
|
||
3 years ago
|
exit("pcntl_fork 错误");
|
||
4 years ago
|
} elseif ($pid > 0) {
|
||
|
exit(0);
|
||
|
}
|
||
|
chdir("/");
|
||
|
umask(0);
|
||
|
if (defined('STDIN')) {
|
||
|
fclose(STDIN);
|
||
|
}
|
||
|
if (defined('STDOUT')) {
|
||
|
fclose(STDOUT);
|
||
|
}
|
||
|
if (defined('STDERR')) {
|
||
|
fclose(STDERR);
|
||
|
}
|
||
|
file_put_contents($this->pidfile, getmypid());
|
||
|
return getmypid();
|
||
|
}
|
||
|
|
||
3 years ago
|
private function init_socket()
|
||
|
{
|
||
3 years ago
|
//创建套接字
|
||
3 years ago
|
$socket = socket_create(AF_INET, SOCK_STREAM, SOL_TCP) or die("socket_create 错误");
|
||
3 years ago
|
|
||
|
//绑定地址和端口
|
||
3 years ago
|
socket_bind($socket, IPC_ADDRESS, IPC_PORT) or die("socket_bind 错误");
|
||
3 years ago
|
|
||
|
//设置可重复使用端口号
|
||
|
socket_set_option($socket, SOL_SOCKET, SO_REUSEADDR, 1);
|
||
|
|
||
|
//监听 设置并发队列的最大长度
|
||
3 years ago
|
socket_listen($socket, SOCKET_LISTEN_BACKLOG);
|
||
3 years ago
|
while (true) {
|
||
3 years ago
|
$clien = socket_accept($socket) or die("socket_accept 错误");
|
||
3 years ago
|
|
||
3 years ago
|
//如果父进程不关心子进程什么时候结束 子进程结束后 内核会回收
|
||
3 years ago
|
//避免了正常情况下僵尸进程的产生
|
||
|
pcntl_signal(SIGCHLD, SIG_IGN);
|
||
|
|
||
|
$pid = pcntl_fork();
|
||
|
if ($pid == -1) {
|
||
3 years ago
|
die('pcntl_fork 错误');
|
||
3 years ago
|
} else if ($pid == 0) {
|
||
|
$this->handle_request($clien);
|
||
|
} else {
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
|
||
|
private function handle_request($clien)
|
||
|
{
|
||
|
//接收客户端发送的数据
|
||
3 years ago
|
$data = socket_read($clien, SOCKET_READ_LENGTH);
|
||
3 years ago
|
|
||
|
//执行
|
||
|
$result = shell_exec($data);
|
||
|
|
||
|
//处理没有返回内容的情况 否则 socket_write 遇到空内容会报错
|
||
3 years ago
|
$result = $result == "" ? ISNULL : $result;
|
||
3 years ago
|
|
||
|
//将结果返回给客户端
|
||
|
socket_write($clien, $result, strlen($result)) or die("socket_write error");
|
||
|
|
||
|
//关闭会话
|
||
|
socket_close($clien);
|
||
|
|
||
|
//退出进程
|
||
|
exit();
|
||
4 years ago
|
}
|
||
|
|
||
3 years ago
|
private function start_daemon()
|
||
|
{
|
||
4 years ago
|
if (file_exists($this->pidfile)) {
|
||
3 years ago
|
$pid = file_get_contents($this->pidfile);
|
||
|
$result = trim(shell_exec("ps -ax | awk '{ print $1 }' | grep -e \"^$pid$\""));
|
||
3 years ago
|
if (strstr($result, $pid)) {
|
||
3 years ago
|
echo "进程正在运行中 无需启动\n";
|
||
|
exit(0);
|
||
|
}
|
||
4 years ago
|
}
|
||
|
return $this->init_daemon();
|
||
|
}
|
||
|
|
||
3 years ago
|
private function start()
|
||
|
{
|
||
3 years ago
|
clearstatcache(true, DB_FILE);
|
||
|
if (!file_exists(DB_FILE)) {
|
||
|
echo "数据库文件不存在 请复制数据库文件到指定目录\n";
|
||
|
return;
|
||
|
}
|
||
3 years ago
|
$this->start_daemon();
|
||
|
$this->init_socket();
|
||
4 years ago
|
}
|
||
|
|
||
3 years ago
|
private function stop()
|
||
|
{
|
||
4 years ago
|
if (file_exists($this->pidfile)) {
|
||
|
$pid = file_get_contents($this->pidfile);
|
||
|
posix_kill($pid, 9);
|
||
|
unlink($this->pidfile);
|
||
|
}
|
||
|
}
|
||
|
|
||
3 years ago
|
public function run($argv)
|
||
|
{
|
||
|
if (isset($argv[1])) {
|
||
3 years ago
|
if (!in_array($argv[1], $this->cmdlist)) {
|
||
|
echo "用法: php svnadmind.php [start] [stop]\n";
|
||
|
return;
|
||
|
}
|
||
3 years ago
|
if ($argv[1] == 'start') {
|
||
|
$this->start();
|
||
|
} else if ($argv[1] == 'stop') {
|
||
|
$this->stop();
|
||
|
}
|
||
4 years ago
|
} else {
|
||
3 years ago
|
echo "用法: php svnadmind.php [start] [stop]\n";
|
||
4 years ago
|
}
|
||
|
}
|
||
|
}
|
||
|
|
||
|
$deamon = new Daemon();
|
||
|
$deamon->run($argv);
|