addRedir("null"); $cmd->passthru($exitcode); return $exitcode; } static function _start(array $args, Runfile $runfile): bool { if ($runfile->isLocked()) return false; $pid = pcntl_fork(); if ($pid == -1) { # parent, impossible de forker throw new StateException("unable to fork"); } elseif ($pid) { # parent, fork ok return true; } else { ## child, fork ok # Créer un groupe de process, pour pouvoir les tuer toutes en même temps $runfile->tm_startPg(); $exitcode = -776; try { # puis lancer la commande $cmd = new Cmd($args); #XXX fichier de log? #XXX charger /g/init.env $cmd->addSource("/g/init.env"); $cmd->addRedir("null"); $cmd->fork_exec($exitcode); return true; } finally { $runfile->wfStopped($exitcode); } } } static function _stop(Runfile $runfile): void { $data = $runfile->read(); $pid = $data["pg_pid"]; if ($pid === null) { msg::warning("$data[name]: groupe de process inconnu"); return; } msg::action("kill $pid"); if (!posix_kill(-$pid, SIGKILL)) { 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; } $timeout = 10; while ($runfile->tm_isUndead($pid)) { sleep(1); if (--$timeout == 0) { msg::afailure("impossible d'arrêter la tâche"); return; } } $runfile->wfStopped(-778); msg::asuccess(); } }