/** * Returns text of last system error * * @return string */ public function error() { if (!function_exists('posix_get_last_error')) { return 'n/a'; } return posix_strerror(posix_get_last_error()); }
/** * Initializes exception. * * @param string $message Error message. * @param int $code Error code. * @param \Exception $previous Previous exception. * @version 0.0.1 * @since 0.0.1 */ public function __construct($message = null, $code = null, \Exception $previous = null) { // detect POSIX error info $code = isset($code) ? $code : \posix_get_last_error(); $message = isset($message) ? $message : \posix_strerr($code); parent::__construct($message, $code, $previous); }
protected function handleStop() { $pidFile = APPLICATION_PATH . '/runtime/jobserver.pid'; if (file_exists($pidFile)) { $pids = explode("|", file_get_contents($pidFile)); $del = 1; foreach ($pids as $pid) { $rs = posix_kill($pid, 15); if (!$rs) { $del = 0; echo "del_fail\r\n"; print_r(posix_get_last_error()); echo "\r\n"; } } if ($del) { echo "del_ok\r\n"; print_r(posix_get_last_error()); echo "\r\n"; do { unlink($pidFile); usleep(100000); } while (file_exists($pidFile)); return 0; } } return 1; }
/** * Constructor. * * @param Master $master The master object * @param integer $pid The child process id or null if this is the child * * @throws \Exception * @throws \RuntimeException */ public function __construct(Master $master, $pid = null) { $this->master = $master; $directions = array('up', 'down'); if (null === $pid) { // child $pid = posix_getpid(); $pPid = posix_getppid(); $modes = array('write', 'read'); } else { // parent $pPid = null; $modes = array('read', 'write'); } $this->pid = $pid; $this->ppid = $pPid; foreach (array_combine($directions, $modes) as $direction => $mode) { $fifo = $this->getPath($direction); if (!file_exists($fifo) && !posix_mkfifo($fifo, 0600) && 17 !== ($error = posix_get_last_error())) { throw new \Exception(sprintf('Error while creating FIFO: %s (%d)', posix_strerror($error), $error)); } $this->{$mode} = fopen($fifo, $mode[0]); if (false === ($this->{$mode} = fopen($fifo, $mode[0]))) { throw new \RuntimeException(sprintf('Unable to open %s FIFO.', $mode)); } } }
/** * 尝试开始任务 * * @return boolean */ protected function tryStart() { // 检查是否达到预定时间 try { if (!$this->testTimer()) { return false; } } catch (\Exception $ex) { $this->log('error', 'Job testTimer() error', ['error' => $ex->getMessage()]); return false; } // 上下文中是否保存了前一个任务pid if (!($recent_proc_id = $this->getContext(self::KEY_PROC_ID))) { return true; } // 检查进程ID是否真正存在 if (!posix_kill($recent_proc_id, 0)) { $errno = posix_get_last_error(); if ($errno === 3) { return true; } $this->log('warning', 'Job kill error', ['error' => posix_strerror($errno)]); return false; } // 如果上一个任务还没有超时就放弃当前任务 $recent_proc_time = $this->getContext(self::KEY_PROC_TIME); if (time() - $recent_proc_time < $this->timeout) { $this->log('notice', 'Job cancel, previous job still run', ['previous_proc_id' => $recent_proc_id]); return false; } // 中止超时任务 posix_kill($recent_proc_id, SIGKILL); $this->log('warning', 'Job killed by timeout', ['previous_proc_id' => $recent_proc_id]); return true; }
public function open($fifoFile) { $this->fifoFile = $fifoFile; $dir = pathinfo($this->fifoFile, PATHINFO_DIRNAME); umask(0); $this->selfCreated = false; if (!is_dir($dir)) { if (!mkdir($dir, 0777, true)) { throw new \Exception("Could not create directory {$dir}"); } } // If pipe was not create on another side if (!file_exists($this->fifoFile)) { if (!posix_mkfifo($this->fifoFile, 0777)) { throw new \Exception("Could not create {$this->fifoFile}: " . posix_strerror(posix_get_last_error())); } else { $this->selfCreated = true; } } log::debug("Creating stream for {$this->fifoFile}"); $stream = fopen($this->fifoFile, "c+"); log::debug("Stream {$stream} = {$this->fifoFile}"); $this->valid = (bool) $stream; parent::open($stream); $this->setBlocking(false); }
/** * Daemonize the current process so it can run in the background. * * If $pidfile is supplied, the process ID is written there. * Provide absolute path names for the parameters to avoid file not found errors or logs inside the source code folder. * * If an error occurred, a RuntimeException is thrown. * * @param string $pidfile File to write the process ID of the daemon to * @param string $stderr File to redirect STDERR to * @param string $stdout File to redirect STDOUT to * @param string $stdin File to read STDIN from * @throws \RuntimeException * @return true */ public static function daemonize($pidfile = null, $stderr = '/dev/null', $stdout = '/dev/null', $stdin = '/dev/null') { // Allow only cli scripts to daemonize, otherwise you may confuse your webserver if (\php_sapi_name() !== 'cli') { throw new \RuntimeException('Can only daemonize a CLI process!'); } self::checkPID($pidfile); self::reopenFDs($stdin, $stdout, $stderr); if (($pid1 = @\pcntl_fork()) < 0) { throw new \RuntimeException('Failed to fork, reason: "' . \pcntl_strerror(\pcntl_get_last_error()) . '"'); } elseif ($pid1 > 0) { exit; } if (@posix_setsid() === -1) { throw new \RuntimeException('Failed to become session leader, reason: "' . \posix_strerror(\posix_get_last_error()) . '"'); } if (($pid2 = @\pcntl_fork()) < 0) { throw new \RuntimeException('Failed to fork, reason: "' . \pcntl_strerror(\pcntl_get_last_error()) . '"'); } elseif ($pid2 > 0) { exit; } chdir('/'); umask(022); self::writePID($pidfile); return true; }
public static function setUid($uid, $gid) { if (!posix_setgid($gid)) { // 必须先设置GID, 再设置UID throw new Exception("Unable to set GID: " . posix_strerror(posix_get_last_error())); } if (!posix_setuid($uid)) { throw new Exception("Unable to set UID: " . posix_strerror(posix_get_last_error())); } }
function kill_concentrator() { $result = posix_kill($this->concentrator_pid, SIGTERM); if ($result === FALSE) { $errno = posix_get_last_error(); throw new Exception("Error killing off mysql concentrator: {$errno}: " . posix_strerror($errno) . "\n"); } $status = null; $result = pcntl_waitpid($this->concentrator_pid, $status); if ($result == -1) { $errno = posix_get_last_error(); throw new Exception("Error waiting for concentrator ({$this->concentrator_pid}): {$errno}: " . posix_strerror($errno) . "\n"); } }
/** * Wait for all child processes to complete */ public function wait() { // Wait for all children to return foreach ($this->child_pid_list as $child_pid) { if (pcntl_waitpid($child_pid, $status) < 0) { error_log(posix_strerror(posix_get_last_error())); } // Check to see if the child died a graceful death $status = 0; if (pcntl_wifsignaled($status)) { $return_code = pcntl_wexitstatus($status); $term_sig = pcntl_wtermsig($status); error_log("Child terminated with return code {$return_code} and signal {$term_sig}"); } } }
function __getpid() { $pid_file = '/tmp/swoole.pid'; if (defined('SWOOLE_PID')) { $pid_file = SWOOLE_PID; } $pid = file_exists($pid_file) ? file_get_contents($pid_file) : 0; // 检查进程是否真正存在 if ($pid && !posix_kill($pid, 0)) { $errno = posix_get_last_error(); if ($errno === 3) { $pid = 0; } } return $pid; }
/** * @param int $pool_size * The number of worker processes to create * * @param array $task_data_iterator * An array of task data items to be divided up among the * workers * * @param \Closure $startup_closure * A closure to execute upon starting a child * * @param \Closure $task_closure * A method to execute on each task data * * @param \Closure $shutdown_closure * A closure to execute upon shutting down a child */ public function __construct(int $pool_size, array $task_data_iterator, \Closure $startup_closure, \Closure $task_closure, \Closure $shutdown_closure) { assert($pool_size > 1, 'The pool size must be >= 2 to use the fork pool.'); assert(extension_loaded('pcntl'), 'The pcntl extension must be loaded in order for Phan to be able to fork.'); // We'll keep track of if this is the parent process // so that we can tell who will be doing the waiting $is_parent = false; // Fork as many times as requested to get the given // pool size for ($proc_id = 0; $proc_id < $pool_size; $proc_id++) { // Fork $pid = 0; if (($pid = pcntl_fork()) < 0) { error_log(posix_strerror(posix_get_last_error())); exit(EXIT_FAILURE); } // Parent if ($pid > 0) { $is_parent = true; $this->child_pid_list[] = $pid; continue; } // Child if ($pid === 0) { $is_parent = false; break; } } // If we're the parent, return if ($is_parent) { return; } // Execute anything the children wanted to execute upon // starting up $startup_closure(); // Otherwise, take on a slice of the task list foreach ($task_data_iterator as $i => $task_data) { if ($i % $pool_size === $proc_id) { $task_closure($i, $task_data); } } // Execute each child's shutdown closure before // exiting the process $shutdown_closure(); // Children exit after completing their work exit(EXIT_SUCCESS); }
public static function isProcessRunning($pid) { if (!$pid) { return false; } // This may fail if we can't signal the process because we are running as // a different user (for example, we are 'apache' and the process is some // other user's, or we are a normal user and the process is root's), but // we can check the error code to figure out if the process exists. $is_running = posix_kill($pid, 0); if (posix_get_last_error() == 1) { // "Operation Not Permitted", indicates that the PID exists. If it // doesn't, we'll get an error 3 ("No such process") instead. $is_running = true; } return $is_running; }
public function stop() { if (!$this->getPid()) { throw new \Exception("Process not running"); } foreach (range(1, 10) as $i) { switch ($i) { case 1: $this->logger->debug('Sending SIGTERM'); posix_kill($this->getPid(), SIGTERM); if (posix_get_last_error() == SOCKET_EPERM) { throw new \Exception("You do not have permission to stop this process"); } if ($this->status() != self::RUNNING_OK) { $this->logger->debug('First attempt results in full stop!'); break 2; } break; case 10: $this->logger->debug('Sending SIGKILL!!'); posix_kill($this->getPid(), SIGKILL); if ($this->status() != self::RUNNING_OK) { $this->logger->debug('Results in full stop!'); break 2; } break; default: $this->logger->debug('Sending another SIGTERM'); posix_kill($this->getPid(), SIGTERM); if ($this->status() != self::RUNNING_OK) { $this->logger->debug('Results in full stop!'); break 2; } break; } sleep(3); } if ($this->status() == self::RUNNING_OK) { throw new \Exception("There was an error attempting to end the process"); } $this->clearPid(); }
public function action_exit() { if (file_exists($this->_config['pid_path'])) { $pid = file_get_contents($this->_config['pid_path']); if ($pid !== 0) { Kohana::$log->add('debug', 'Sending SIGTERM to pid ' . $pid); echo 'Sending SIGTERM to pid ' . $pid . PHP_EOL; posix_kill($pid, SIGTERM); if (posix_get_last_error() === 0) { echo "Signal send SIGTERM to pid " . $pid . PHP_EOL; } else { echo "An error occured while sending SIGTERM" . PHP_EOL; unlink($this->_config['pid_path']); } } else { Kohana::$log->add("debug", "Could not find MangoQueue pid in file :" . $this->_config['pid_path']); echo "Could not find task_queue pid in file :" . $this->_config['pid_path'] . PHP_EOL; } } else { Kohana::$log->add("error", "MangoQueue pid file " . $this->_config['pid_path'] . " does not exist"); echo "MangoQueue pid file " . $this->_config['pid_path'] . " does not exist" . PHP_EOL; } }
<?php echo "Basic test of POSIX times function\n"; $times = posix_times(); var_dump($times); if ($times == FALSE) { $errno = posix_get_last_error(); var_dump(posix_strerror($errno)); } ?> ===DONE====
/** * Close an open tunnel. * * @param array $tunnel * * @return bool * True on success, false on failure. */ protected function closeTunnel(array $tunnel) { $success = true; if (isset($tunnel['pid']) && function_exists('posix_kill')) { $success = posix_kill($tunnel['pid'], SIGTERM); if (!$success) { $this->stdErr->writeln(sprintf('Failed to kill process <error>%d</error> (POSIX error %s)', $tunnel['pid'], posix_get_last_error())); } } $pidFile = $this->getPidFile($tunnel); if (file_exists($pidFile)) { $success = unlink($pidFile) && $success; } $this->tunnelInfo = array_filter($this->tunnelInfo, function ($info) use($tunnel) { return !$this->tunnelsAreEqual($info, $tunnel); }); $this->saveTunnelInfo(); return $success; }
function stdapi_sys_process_kill($req, &$pkt) { # The existence of posix_kill is unlikely (it's a php compile-time option # that isn't enabled by default, but better to try it and avoid shelling # out when unnecessary. my_print("doing kill"); $pid_tlv = packet_get_tlv($req, TLV_TYPE_PID); $pid = $pid_tlv['value']; if (is_callable('posix_kill')) { $ret = posix_kill($pid, 9); $ret = $ret ? ERROR_SUCCESS : posix_get_last_error(); if ($ret != ERROR_SUCCESS) { my_print(posix_strerror($ret)); } } else { $ret = ERROR_FAILURE; if (is_windows()) { my_cmd("taskkill /f /pid {$pid}"); # Don't know how to check for success yet, so just assume it worked $ret = ERROR_SUCCESS; } else { if ("foo" == my_cmd("kill -9 {$pid} && echo foo")) { $ret = ERROR_SUCCESS; } } } return $ret; }
/** * * Shutdown function is call if script terminates try to make a restart if needed * * Prepare the job for start * * @internal param int the signal that terminates the job */ public function shutdown() { //Put last error to log if one $lasterror = error_get_last(); if ($lasterror['type'] === E_ERROR || $lasterror['type'] === E_PARSE || $lasterror['type'] === E_CORE_ERROR || $lasterror['type'] === E_CORE_WARNING || $lasterror['type'] === E_COMPILE_ERROR || $lasterror['type'] === E_COMPILE_WARNING) { $this->log($lasterror['type'], $lasterror['message'], $lasterror['file'], $lasterror['line']); } $error = false; if (function_exists('pcntl_get_last_error')) { $error = pcntl_get_last_error(); if (!empty($error)) { $error_msg = pcntl_strerror($error); if (!empty($error_msg)) { $error = '(' . $error . ') ' . $error_msg; } } if (!empty($error)) { $this->log(sprintf(__('System: %s', 'backwpup'), $error), E_USER_ERROR); } } if (function_exists('posix_get_last_error') && !$error) { $error = posix_get_last_error(); if (!empty($error)) { $error_msg = posix_strerror($error); if (!empty($error_msg)) { $error = '(' . $error . ') ' . $error_msg; } } if (!empty($error)) { $this->log(sprintf(__('System: %s', 'backwpup'), $error), E_USER_ERROR); } } $this->do_restart(true); }
/** * Terminate a process and any of its children. */ private static function terminate_proc($proc) { $status = proc_get_status($proc); $master_pid = $status['pid']; $output = `ps -o ppid,pid,command | grep ^{$master_pid}`; foreach (explode("\n", $output) as $line) { if (preg_match('/^(\\d+)\\s+(\\d+)/', $line, $matches)) { $parent = $matches[1]; $child = $matches[2]; if ($parent == $master_pid) { if (!posix_kill($child, 9)) { throw new RuntimeException(posix_strerror(posix_get_last_error())); } } } } posix_kill($master_pid, 9); }
// check whether the process has been idle for too long $idled = $last < time() - $idletime ? true : false; if ($reload || $idled) { // record confirmed gap gap_record($role, $last, time()); if ($running) { if ($reload) { $restartmsg = "enforcing reload of config for {$role}"; } else { $restartmsg = "script {$role} was idle for more than " . $idletime . " seconds - killing and starting"; } logit("controller.log", $restartmsg); if (function_exists('posix_kill')) { // check whether the process was started by another user posix_kill($pid, 0); if (posix_get_last_error() == 1) { logit("controller.log", "unable to kill {$role}, it seems to be running under another user\n"); exit; } // kill script $role logit("controller.log", "sending a TERM signal to {$role} for {$pid}"); posix_kill($pid, SIGTERM); // test whether the process really has been killed $i = 0; $sleep = 5; // while we can still signal the pid while (posix_kill($pid, 0)) { logit("controller.log", "waiting for graceful exit of script {$role} with pid {$pid}"); // we need some time to allow graceful exit sleep($sleep); $i++;
public function run() { proc_nice(Daemon::$settings['workerpriority']); Daemon::$worker = $this; $this->microsleep = Daemon::$settings['microsleep']; $this->autoReloadLast = time(); $this->reloadDelay = Daemon::$parsedSettings['mpmdelay'] + 2; $this->setStatus(4); Thread::setproctitle(Daemon::$runName . ': worker process' . (Daemon::$settings['pidfile'] !== Daemon::$settings['defaultpidfile'] ? ' (' . Daemon::$settings['pidfile'] . ')' : '')); register_shutdown_function(array($this, 'shutdown')); if (Daemon::$settings['autogc'] > 0) { gc_enable(); } else { gc_disable(); } if (isset(Daemon::$settings['group'])) { $sg = posix_getgrnam(Daemon::$settings['group']); } if (isset(Daemon::$settings['user'])) { $su = posix_getpwnam(Daemon::$settings['user']); } if (Daemon::$settings['chroot'] !== '/') { if (posix_getuid() != 0) { Daemon::log('You must have the root privileges to change root.'); exit(0); } elseif (!chroot(Daemon::$settings['chroot'])) { Daemon::log('Couldn\'t change root to \'' . Daemon::$settings['chroot'] . '\'.'); exit(0); } } if (isset(Daemon::$settings['group'])) { if ($sg === FALSE) { Daemon::log('Couldn\'t change group to \'' . Daemon::$settings['group'] . '\'. You must replace config-variable \'group\' with existing group.'); exit(0); } elseif ($sg['gid'] != posix_getgid() && !posix_setgid($sg['gid'])) { Daemon::log('Couldn\'t change group to \'' . Daemon::$settings['group'] . "'. Error (" . ($errno = posix_get_last_error()) . '): ' . posix_strerror($errno)); exit(0); } } if (isset(Daemon::$settings['user'])) { if ($su === FALSE) { Daemon::log('Couldn\'t change user to \'' . Daemon::$settings['user'] . '\', user not found. You must replace config-variable \'user\' with existing username.'); exit(0); } elseif ($su['uid'] != posix_getuid() && !posix_setuid($su['uid'])) { Daemon::log('Couldn\'t change user to \'' . Daemon::$settings['user'] . "'. Error (" . ($errno = posix_get_last_error()) . '): ' . posix_strerror($errno)); exit(0); } } if (Daemon::$settings['cwd'] !== '.') { if (!@chdir(Daemon::$settings['cwd'])) { Daemon::log('WORKER ' . $this->pid . '] Couldn\'t change directory to \'' . Daemon::$settings['cwd'] . '.'); } } $this->setStatus(6); $this->eventBase = event_base_new(); Daemon::$appResolver->preload(); foreach (Daemon::$appInstances as $app) { foreach ($app as $appInstance) { if (!$appInstance->ready) { $this->ready = TRUE; $appInstance->onReady(); } } } $this->setStatus(1); $ev = event_new(); event_set($ev, STDIN, EV_TIMEOUT, function () { }, array()); event_base_set($ev, $this->eventBase); $this->timeoutEvent = $ev; while (TRUE) { pcntl_signal_dispatch(); if (($s = $this->checkState()) !== TRUE) { $this->closeSockets(); if (sizeof($this->queue) === 0) { return $s; } } event_add($this->timeoutEvent, $this->microsleep); event_base_loop($this->eventBase, EVLOOP_ONCE); do { for ($i = 0, $s = sizeof($this->eventsToAdd); $i < $s; ++$i) { event_add($this->eventsToAdd[$i]); unset($this->eventsToAdd[$i]); } $this->readPool(); $processed = $this->runQueue(); } while ($processed || $this->readPoolState || $this->eventsToAdd); } }
/** * * Shutdown function is call if script terminates try to make a restart if needed * * Prepare the job for start * * @internal param int the signal that terminates the job */ public function shutdown() { $args = func_get_args(); //Put last error to log if one $lasterror = error_get_last(); if ($lasterror['type'] == E_ERROR or $lasterror['type'] == E_PARSE or $lasterror['type'] == E_CORE_ERROR or $lasterror['type'] == E_CORE_WARNING or $lasterror['type'] == E_COMPILE_ERROR or $lasterror['type'] == E_COMPILE_WARNING) { $this->log($lasterror['type'], $lasterror['message'], $lasterror['file'], $lasterror['line']); } //Put signals to log if (!empty($args[0])) { $signals = array('SIGHUP', 'SIGINT', 'SIGQUIT', 'SIGILL', 'SIGTRAP', 'SIGABRT', 'SIGBUS', 'SIGFPE', 'SIGKILL', 'SIGSEGV', 'SIGPIPE', 'SIGALRM', 'SIGTERM', 'SIGSTKFLT', 'SIGUSR1', 'SIGUSR2', 'SIGCHLD', 'SIGCONT', 'SIGSTOP', 'SIGTSTP', 'SIGTTIN', 'SIGTTOU', 'SIGURG', 'SIGXCPU', 'SIGXFSZ', 'SIGVTALRM', 'SIGPROF', 'SIGWINCH', 'SIGIO', 'SIGPWR', 'SIGSYS'); foreach ($signals as $signal) { if (defined($signal) && $args[0] === constant($signal)) { $this->log(sprintf(__('Signal "%s" is sent to script!', 'backwpup'), $signal), E_USER_ERROR); break; } } } if (function_exists('pcntl_get_last_error')) { $error = pcntl_get_last_error(); if (!empty($error)) { $error_msg = pcntl_strerror($error); if (!empty($error_msg)) { $error = '(' . $error . ') ' . $error_msg; } } if (!empty($error)) { $this->log(sprintf(__('System: %s', 'backwpup'), $error), E_USER_ERROR); } } if (function_exists('posix_get_last_error') && empty($error)) { $error = posix_get_last_error(); if (!empty($error)) { $error_msg = posix_strerror($error); if (!empty($error_msg)) { $error = '(' . $error . ') ' . $error_msg; } } if (!empty($error)) { $this->log(sprintf(__('System: %s', 'backwpup'), $error), E_USER_ERROR); } } $this->do_restart(TRUE); }
function __getpid() { $config = __getconfig(); $pid_file = $config['server']['pid_file']; $pid = file_exists($pid_file) ? file_get_contents($pid_file) : 0; // 检查进程是否真正存在 if ($pid && !posix_kill($pid, 0)) { $errno = posix_get_last_error(); if ($errno === 3) { $pid = 0; } } return $pid; }
/** * Setup settings on start. * @return void */ protected function prepareSystemEnv() { proc_nice(Daemon::$config->workerpriority->value); register_shutdown_function(function () { $this->shutdown(true); }); $this->setTitle(Daemon::$runName . ': worker process' . (Daemon::$config->pidfile->value !== Daemon::$config->defaultpidfile->value ? ' (' . Daemon::$config->pidfile->value . ')' : '')); if (isset(Daemon::$config->group->value)) { $sg = posix_getgrnam(Daemon::$config->group->value); } if (isset(Daemon::$config->user->value)) { $su = posix_getpwnam(Daemon::$config->user->value); } $flushCache = false; if (Daemon::$config->chroot->value !== '/') { if (posix_getuid() != 0) { Daemon::log('You must have the root privileges to change root.'); exit(0); } elseif (!chroot(Daemon::$config->chroot->value)) { Daemon::log('Couldn\'t change root to \'' . Daemon::$config->chroot->value . '\'.'); exit(0); } $flushCache = true; } if (isset(Daemon::$config->group->value)) { if ($sg === FALSE) { Daemon::log('Couldn\'t change group to \'' . Daemon::$config->group->value . '\'. You must replace config-variable \'group\' with existing group.'); exit(0); } elseif ($sg['gid'] != posix_getgid() && !posix_setgid($sg['gid'])) { Daemon::log('Couldn\'t change group to \'' . Daemon::$config->group->value . "'. Error (" . ($errno = posix_get_last_error()) . '): ' . posix_strerror($errno)); exit(0); } $flushCache = true; } if (isset(Daemon::$config->user->value)) { if ($su === FALSE) { Daemon::log('Couldn\'t change user to \'' . Daemon::$config->user->value . '\', user not found. You must replace config-variable \'user\' with existing username.'); exit(0); } elseif ($su['uid'] != posix_getuid() && !posix_setuid($su['uid'])) { Daemon::log('Couldn\'t change user to \'' . Daemon::$config->user->value . "'. Error (" . ($errno = posix_get_last_error()) . '): ' . posix_strerror($errno)); exit(0); } $flushCache = true; } if ($flushCache) { clearstatcache(true); } if (Daemon::$config->cwd->value !== '.') { if (!@chdir(Daemon::$config->cwd->value)) { Daemon::log('Couldn\'t change directory to \'' . Daemon::$config->cwd->value . '.'); } clearstatcache(true); } }
protected function workingPid() { return ($this->pidfile and is_file($this->pidfile) and $pid = (int) file_get_contents($this->pidfile) and (posix_kill($pid, 0) or 3 !== posix_get_last_error())) ? $pid : false; }
/** * Entry-point for Erebot. * * \return * This method never returns. * Instead, the program exits with an appropriate * return code when Erebot is stopped. */ public static function run() { // Apply patches. \Erebot\Patches::patch(); // Load the configuration for the Dependency Injection Container. $dic = new \Symfony\Component\DependencyInjection\ContainerBuilder(); $dic->setParameter('Erebot.src_dir', __DIR__); $loader = new \Symfony\Component\DependencyInjection\Loader\XmlFileLoader($dic, new \Symfony\Component\Config\FileLocator(getcwd())); $dicConfig = dirname(__DIR__) . DIRECTORY_SEPARATOR . 'data' . DIRECTORY_SEPARATOR . 'defaults.xml'; $dicCwdConfig = getcwd() . DIRECTORY_SEPARATOR . 'defaults.xml'; if (!strncasecmp(__FILE__, 'phar://', 7)) { if (!file_exists($dicCwdConfig)) { copy($dicConfig, $dicCwdConfig); } $dicConfig = $dicCwdConfig; } elseif (file_exists($dicCwdConfig)) { $dicConfig = $dicCwdConfig; } $loader->load($dicConfig); // Determine availability of PHP extensions // needed by some of the command-line options. $hasPosix = in_array('posix', get_loaded_extensions()); $hasPcntl = in_array('pcntl', get_loaded_extensions()); $logger = $dic->get('logging'); $localeGetter = $dic->getParameter('i18n.default_getter'); $coreTranslatorCls = $dic->getParameter('core.classes.i18n'); $translator = new $coreTranslatorCls("Erebot\\Core"); $categories = array('LC_MESSAGES', 'LC_MONETARY', 'LC_TIME', 'LC_NUMERIC'); foreach ($categories as $category) { $locales = call_user_func($localeGetter); $locales = empty($locales) ? array() : array($locales); $localeSources = array('LANGUAGE' => true, 'LC_ALL' => false, $category => false, 'LANG' => false); foreach ($localeSources as $source => $multiple) { if (!isset($_SERVER[$source])) { continue; } if ($multiple) { $locales = explode(':', $_SERVER[$source]); } else { $locales = array($_SERVER[$source]); } break; } $translator->setLocale($translator->nameToCategory($category), $locales); } // Also, include some information about the version // of currently loaded PHAR modules, if any. $version = 'dev-master'; if (!strncmp(__FILE__, 'phar://', 7)) { $phar = new \Phar(\Phar::running(true)); $md = $phar->getMetadata(); $version = $md['version']; } if (defined('Erebot_PHARS')) { $phars = unserialize(Erebot_PHARS); ksort($phars); foreach ($phars as $module => $metadata) { if (strncasecmp($module, 'Erebot_Module_', 14)) { continue; } $version .= "\n with {$module} version {$metadata['version']}"; } } \Console_CommandLine::registerAction('StoreProxy', '\\Erebot\\Console\\StoreProxyAction'); $parser = new \Console_CommandLine(array('name' => 'Erebot', 'description' => $translator->gettext('A modular IRC bot written in PHP'), 'version' => $version, 'add_help_option' => true, 'add_version_option' => true, 'force_posix' => false)); $parser->accept(new \Erebot\Console\MessageProvider()); $parser->renderer->options_on_different_lines = true; $defaultConfigFile = getcwd() . DIRECTORY_SEPARATOR . 'Erebot.xml'; $parser->addOption('config', array('short_name' => '-c', 'long_name' => '--config', 'description' => $translator->gettext('Path to the configuration file to use instead ' . 'of "Erebot.xml", relative to the current ' . 'directory.'), 'help_name' => 'FILE', 'action' => 'StoreString', 'default' => $defaultConfigFile)); $parser->addOption('daemon', array('short_name' => '-d', 'long_name' => '--daemon', 'description' => $translator->gettext('Run the bot in the background (daemon).' . ' [requires the POSIX and pcntl extensions]'), 'action' => 'StoreTrue')); $noDaemon = new \Erebot\Console\ParallelOption('no_daemon', array('short_name' => '-n', 'long_name' => '--no-daemon', 'description' => $translator->gettext('Do not run the bot in the background. ' . 'This is the default, unless the -d option ' . 'is used or the bot is configured otherwise.'), 'action' => 'StoreProxy', 'action_params' => array('option' => 'daemon'))); $parser->addOption($noDaemon); $parser->addOption('pidfile', array('short_name' => '-p', 'long_name' => '--pidfile', 'description' => $translator->gettext("Store the bot's PID in this file."), 'help_name' => 'FILE', 'action' => 'StoreString', 'default' => null)); $parser->addOption('group', array('short_name' => '-g', 'long_name' => '--group', 'description' => $translator->gettext('Set group identity to this GID/group during ' . 'startup. The default is to NOT change group ' . 'identity, unless configured otherwise.' . ' [requires the POSIX extension]'), 'help_name' => 'GROUP/GID', 'action' => 'StoreString', 'default' => null)); $parser->addOption('user', array('short_name' => '-u', 'long_name' => '--user', 'description' => $translator->gettext('Set user identity to this UID/username during ' . 'startup. The default is to NOT change user ' . 'identity, unless configured otherwise.' . ' [requires the POSIX extension]'), 'help_name' => 'USER/UID', 'action' => 'StoreString', 'default' => null)); try { $parsed = $parser->parse(); } catch (\Exception $exc) { $parser->displayError($exc->getMessage()); exit(1); } // Parse the configuration file. $config = new \Erebot\Config\Main($parsed->options['config'], \Erebot\Config\Main::LOAD_FROM_FILE, $translator); $coreCls = $dic->getParameter('core.classes.core'); $bot = new $coreCls($config, $translator); $dic->set('bot', $bot); // Use values from the XML configuration file // if there is no override from the command line. $overrides = array('daemon' => 'mustDaemonize', 'group' => 'getGroupIdentity', 'user' => 'getUserIdentity', 'pidfile' => 'getPidfile'); foreach ($overrides as $option => $func) { if ($parsed->options[$option] === null) { $parsed->options[$option] = $config->{$func}(); } } /* Handle daemonization. * See also: * - http://www.itp.uzh.ch/~dpotter/howto/daemonize * - http://andytson.com/blog/2010/05/daemonising-a-php-cli-script */ if ($parsed->options['daemon']) { if (!$hasPosix) { $logger->error($translator->gettext('The posix extension is required in order ' . 'to start the bot in the background')); exit(1); } if (!$hasPcntl) { $logger->error($translator->gettext('The pcntl extension is required in order ' . 'to start the bot in the background')); exit(1); } foreach (array('SIGCHLD', 'SIGUSR1', 'SIGALRM') as $signal) { if (defined($signal)) { pcntl_signal(constant($signal), array(__CLASS__, 'startupSighandler')); } } $logger->info($translator->gettext('Starting the bot in the background...')); $pid = pcntl_fork(); if ($pid < 0) { $logger->error($translator->gettext('Could not start in the background (unable to fork)')); exit(1); } if ($pid > 0) { pcntl_wait($dummy, WUNTRACED); pcntl_alarm(2); pcntl_signal_dispatch(); exit(1); } $parent = posix_getppid(); // Ignore some of the signals. foreach (array('SIGTSTP', 'SIGTOU', 'SIGTIN', 'SIGHUP') as $signal) { if (defined($signal)) { pcntl_signal(constant($signal), SIG_IGN); } } // Restore the signal handlers we messed with. foreach (array('SIGCHLD', 'SIGUSR1', 'SIGALRM') as $signal) { if (defined($signal)) { pcntl_signal(constant($signal), SIG_DFL); } } umask(0); if (umask() != 0) { $logger->warning($translator->gettext('Could not change umask')); } if (posix_setsid() == -1) { $logger->error($translator->gettext('Could not start in the background (unable to setsid)')); exit(1); } // Prevent the child from ever acquiring a controlling terminal. // Not required under Linux, but required by at least System V. $pid = pcntl_fork(); if ($pid < 0) { $logger->error($translator->gettext('Could not start in the background (unable to fork)')); exit(1); } if ($pid > 0) { exit(0); } // Avoid locking up the current directory. if (!chdir(DIRECTORY_SEPARATOR)) { $logger->error($translator->gettext('Could not chdir to "%(path)s"'), array('path' => DIRECTORY_SEPARATOR)); } // Explicitly close the magic stream-constants (just in case). foreach (array('STDIN', 'STDOUT', 'STDERR') as $stream) { if (defined($stream)) { fclose(constant($stream)); } } // Re-open them with the system's blackhole. /** * \todo * should be made portable, but the requirement on the POSIX * extension prevents this, so this is okay for now. */ $stdin = fopen('/dev/null', 'r'); $stdout = fopen('/dev/null', 'w'); $stderr = fopen('/dev/null', 'w'); if (defined('SIGUSR1')) { posix_kill($parent, SIGUSR1); } $logger->info($translator->gettext('Successfully started in the background')); } try { /// @TODO: Check the interface or something like that. $identd = $dic->get('identd'); } catch (\InvalidArgumentException $e) { $identd = null; } try { /// @TODO: Check the interface or something like that. $prompt = $dic->get('prompt'); } catch (\InvalidArgumentException $e) { $prompt = null; } // Change group identity if necessary. if ($parsed->options['group'] !== null && $parsed->options['group'] != '') { if (!$hasPosix) { $logger->warning($translator->gettext('The posix extension is needed in order ' . 'to change group identity.')); } elseif (posix_getuid() !== 0) { $logger->warning($translator->gettext('Only root can change group identity! ' . 'Your current UID is %(uid)d'), array('uid' => posix_getuid())); } else { if (ctype_digit($parsed->options['group'])) { $info = posix_getgrgid((int) $parsed->options['group']); } else { $info = posix_getgrnam($parsed->options['group']); } if ($info === false) { $logger->error($translator->gettext('No such group "%(group)s"'), array('group' => $parsed->options['group'])); exit(1); } if (!posix_setgid($info['gid'])) { $logger->error($translator->gettext('Could not set group identity ' . 'to "%(name)s" (%(id)d)'), array('id' => $info['gid'], 'name' => $info['name'])); exit(1); } $logger->debug($translator->gettext('Successfully changed group identity ' . 'to "%(name)s" (%(id)d)'), array('name' => $info['name'], 'id' => $info['gid'])); } } // Change user identity if necessary. if ($parsed->options['user'] !== null || $parsed->options['user'] != '') { if (!$hasPosix) { $logger->warning($translator->gettext('The posix extension is needed in order ' . 'to change user identity.')); } elseif (posix_getuid() !== 0) { $logger->warning($translator->gettext('Only root can change user identity! ' . 'Your current UID is %(uid)d'), array('uid' => posix_getuid())); } else { if (ctype_digit($parsed->options['user'])) { $info = posix_getpwuid((int) $parsed->options['user']); } else { $info = posix_getpwnam($parsed->options['user']); } if ($info === false) { $logger->error($translator->gettext('No such user "%(user)s"'), array('user' => $parsed->options['user'])); exit(1); } if (!posix_setuid($info['uid'])) { $logger->error($translator->gettext('Could not set user identity ' . 'to "%(name)s" (%(id)d)'), array('name' => $info['name'], 'id' => $info['uid'])); exit(1); } $logger->debug($translator->gettext('Successfully changed user identity ' . 'to "%(name)s" (%(id)d)'), array('name' => $info['name'], 'id' => $info['uid'])); } } // Write new pidfile. if ($parsed->options['pidfile'] !== null && $parsed->options['pidfile'] != '') { $pid = @file_get_contents($parsed->options['pidfile']); // If the file already existed, the bot may already be started // or it may contain data not related to Erebot at all. if ($pid !== false) { $pid = (int) rtrim($pid); if (!$pid) { $logger->error($translator->gettext('The pidfile (%(pidfile)s) contained garbage. ' . 'Exiting'), array('pidfile' => $parsed->options['pidfile'])); exit(1); } else { posix_kill($pid, 0); $res = posix_errno(); switch ($res) { case 0: // No error. $logger->error($translator->gettext('Erebot is already running ' . 'with PID %(pid)d'), array('pid' => $pid)); exit(1); case 3: // ESRCH. $logger->warning($translator->gettext('Found stalled PID %(pid)d in pidfile ' . '"%(pidfile)s". Removing it'), array('pidfile' => $parsed->options['pidfile'], 'pid' => $pid)); @unlink($parsed->options['pidfile']); break; case 1: // EPERM. $logger->error($translator->gettext('Found another program\'s PID %(pid)d in ' . 'pidfile "%(pidfile)s". Exiting'), array('pidfile' => $parsed->options['pidfile'], 'pid' => $pid)); exit(1); default: $logger->error($translator->gettext('Unknown error while checking for ' . 'the existence of another running ' . 'instance of Erebot (%(error)s)'), array('error' => posix_get_last_error())); exit(1); } } } $pidfile = fopen($parsed->options['pidfile'], 'wt'); flock($pidfile, LOCK_EX | LOCK_NB, $wouldBlock); if ($wouldBlock) { $logger->error($translator->gettext('Could not lock pidfile (%(pidfile)s). ' . 'Is the bot already running?'), array('pidfile' => $parsed->options['pidfile'])); exit(1); } $pid = sprintf("%u\n", getmypid()); $res = fwrite($pidfile, $pid); if ($res !== strlen($pid)) { $logger->error($translator->gettext('Unable to write PID to pidfile (%(pidfile)s)'), array('pidfile' => $parsed->options['pidfile'])); exit(1); } $logger->debug($translator->gettext('PID (%(pid)d) written into %(pidfile)s'), array('pidfile' => $parsed->options['pidfile'], 'pid' => getmypid())); // Register a callback to remove the pidfile upon exit. register_shutdown_function(array(__CLASS__, 'cleanupPidfile'), $pidfile, $parsed->options['pidfile']); } // Display a desperate warning when run as user root. if ($hasPosix && posix_getuid() === 0) { $logger->warning($translator->gettext('You SHOULD NOT run Erebot as root!')); } if ($identd !== null) { $identd->connect(); } if ($prompt !== null) { $prompt->connect(); } // This doesn't return until we purposely // make the bot drop all active connections. $bot->start($dic->get('factory.connection')); exit(0); }
<?php $folder = $_SERVER['DOCUMENT_ROOT'] . 'pf-2016/data'; $file_name = 'file_test.txt'; $file = $folder . '' . $file_name; if (posix_access($folder, POSIX_R_OK | POSIX_W_OK) && $_POST['data']) { $handler = fopen($file, 'a+'); $decode = json_decode($_POST['data'], true); // var_dump($_POST['data']); $addr = $_SERVER['DOCUMENT_ROOT'] . 'pf-2016/data/' . $decode['name'] . '.json'; // echo $addr; $file = fopen($addr, 'a+'); fwrite($file, $_POST['data']); fclose($file); echo '<div id="send_mail">message envoyé</div>'; } else { $error = posix_get_last_error(); echo 'Erreur ' . $error . ' :' . posix_strerror($error) . '<br />'; echo '</br />Contact Root for rights mofo<br />'; }
/** * Retrieve the error number set by the last posix function that failed * * @return int */ public function getLastError() : int { return posix_get_last_error(); }
public function updateStopTime($rec_id, $stop_time) { $pid_file = $this->getRecPidFile($rec_id); if (!is_file($pid_file)) { return true; } $pid = intval(file_get_contents($pid_file)); if (posix_kill($pid, 0)) { $kill_result = posix_kill($pid, 14); if (!$kill_result) { throw new IOException('Send signal to pid "' . $pid . '" failed on ' . $this->storage_name . ': ' . posix_strerror(posix_get_last_error())); } return $kill_result; } else { return true; } }