public function start() { if (!ProcessContainer::dup2_available()) { $cmd = "{$this->process_path} {$this->process_params}"; if ($this->is_php) { $cmd = "{$this->php_path} {$cmd}"; } $descriptorspec = array(0 => array("pipe", "r"), 1 => array("pipe", "w"), 2 => array("pipe", "w")); $process = proc_open($cmd, $descriptorspec, $pipes, dirname($this->process_path)); if (!is_resource($process)) { return FALSE; } $status = proc_get_status($process); $this->process_pid = $status['pid']; // 关闭输入 fclose($pipes[0]); $this->process_stdout = $pipes[1]; $this->process_stderr = $pipes[2]; $this->process = $process; return TRUE; } else { $pipes = array(1 => $this->pipe_open('w+'), 2 => $this->pipe_open('w+')); // 利用 dup2 重定向管道 $pid = pcntl_fork(); if ($pid == -1) { return FALSE; } else { if ($pid) { $this->process_pid = $pid; $this->process_stdout = $pipes[1]; $this->process_stderr = $pipes[2]; return TRUE; } } // 子进程 if ($this->child_init_handler) { call_user_func($this->child_init_handler); } $params = explode(' ', $this->process_params); if ($this->is_php) { $path = $this->php_path; array_unshift($params, $this->process_path); } else { $path = $this->process_path; } chdir(dirname($this->process_path)); //fildes_dup2(fildes_fileno($pipes[0]), fildes_fileno(STDIN)); fildes_dup2(fildes_fileno($pipes[1]), fildes_fileno(STDOUT)); fildes_dup2(fildes_fileno($pipes[2]), fildes_fileno(STDERR)); pcntl_exec($path, $params); exit; } }
public function run() { if ($this->socket) { return TRUE; } if (!$this->listen()) { return FALSE; } if (!$this->init_shm()) { return FALSE; } if (!$this->init_config()) { return FALSE; } if ($this->event_handlers['server_inited']) { foreach ($this->event_handlers['server_inited'] as $handler) { if (!call_user_func($handler)) { return FALSE; } } } // 关闭终端输出 $this->server_muted = TRUE; if (function_exists('fildes_dup2')) { $errorlog_path = $this->log_path . '/server/error'; if (!is_dir($errorlog_path)) { mkdir($errorlog_path, 0777); } $errorlog_fd = fopen($errorlog_path . '/error.log', 'a+'); fildes_dup2(fildes_fileno($errorlog_fd), fildes_fileno(STDERR)); } return $this->loop(); }