killTree static method

Future<void> killTree(
  1. int pid, {
  2. required bool ownGroup,
})

Terminates pid's whole process tree (issue #517): the process group when the job is its own group leader (one signal — also covers children forked while the kill runs), otherwise a live ps descendant walk; Windows delegates to taskkill /T. TERM first, a short grace, then KILL. Best-effort: never throws.

Implementation

static Future<void> killTree(int pid, {required bool ownGroup}) async {
  try {
    if (Platform.isWindows) {
      await Process.run('taskkill', ['/PID', '$pid', '/T', '/F']);
      return;
    }
    if (ownGroup) {
      Process.killPid(-pid, ProcessSignal.sigterm);
      await Future<void>.delayed(_killGrace);
      Process.killPid(-pid, ProcessSignal.sigkill);
      return;
    }
    // No group leadership on this host (no setsid): walk the live tree.
    var victims = await _descendantsOf(pid);
    if (victims.isEmpty) return;
    await _signalAll(victims, ProcessSignal.sigterm);
    await Future<void>.delayed(_killGrace);
    // Children may have been forked while the first round landed; the
    // walk only roots at a still-observable pid, so a recycled root can
    // never widen the victim set.
    victims = await _descendantsOf(pid);
    await _signalAll(victims, ProcessSignal.sigkill);
  } on Object {
    // Best-effort: stop() still backstops the direct child.
  }
}