stopProcess('lethean-wallet-cli', 'Wallet'); $this->stopProcess('lethean-testnet-chain-node', 'Daemon'); return self::SUCCESS; } private function stopProcess(string $name, string $label): void { // Safe: escapeshellarg prevents injection, process names are hardcoded constants exec("pgrep -f " . escapeshellarg($name), $pids); // @codeCoverageIgnore if (empty($pids)) { $this->info("{$label}: not running."); return; } foreach ($pids as $pid) { posix_kill((int) $pid, SIGTERM); } $this->info("{$label}: SIGTERM sent to " . count($pids) . " process(es)."); // Wait up to 10s for graceful shutdown for ($i = 0; $i < 10; $i++) { exec("pgrep -f " . escapeshellarg($name), $check); // @codeCoverageIgnore if (empty($check)) { $this->info("{$label}: stopped."); return; } sleep(1); } $this->warn("{$label}: still running after 10s."); } }