wfPrepare($pid); $logfile = $runfile->getLogfile() ?? "/tmp/NULIB_APP_app_start.log"; $exitcode = app2::EC_FORK_CHILD; try { # puis lancer la commande $cmd = new Cmd($args); $cmd->addSource("/g/init.env"); $cmd->addRedir("both", $logfile, true); $cmd->fork_exec($exitcode, false); sh::_waitpid(-$pid, $exitcode); } finally { $runfile->wfReaped($exitcode); } } } private static function kill(int $pid, int $signal): bool { if (!posix_kill($pid, $signal)) { switch (posix_get_last_error()) { case PCNTL_ESRCH: msg::afailure("process inexistant"); break; case PCNTL_EPERM: msg::afailure("process non accessible"); break; case PCNTL_EINVAL: msg::afailure("signal invalide"); break; } return false; } return true; } static function _stop(Runfile $runfile): bool { $data = $runfile->read(); $pid = $runfile->_getCid($data); $stopped = false; msg::action("term $pid"); $timeout = 10; $delay = 300000; while (--$timeout >= 0) { if (!self::kill($pid, SIGTERM)) { msg::afailure(); return false; } usleep($delay); $delay = 1000000; // attendre 1 seconde à partir de la deuxième fois if (!$runfile->_isRunning($data)) { msg::asuccess(); $stopped = true; break; } } if (!$stopped) { msg::action("kill $pid"); $timeout = 3; $delay = 300000; while (--$timeout >= 0) { if (!self::kill($pid, SIGKILL)) { msg::afailure(); return false; } usleep($delay); $delay = 1000000; // attendre 1 seconde à partir de la deuxième fois if (!$runfile->_isRunning($data)) { msg::asuccess(); $stopped = true; break; } } } if ($stopped) { sh::_waitpid($pid, $exitcode); $runfile->wfReaped($exitcode); } return $stopped; } }