()
| 271 | } |
| 272 | |
| 273 | public override abort() { |
| 274 | if (!this.isListening) { |
| 275 | return |
| 276 | } |
| 277 | |
| 278 | // Send SIGINT using CTRL+C. |
| 279 | this.terminal.terminal.sendText("\x03") |
| 280 | |
| 281 | // #266: A single Ctrl+C isn't always enough — some processes trap SIGINT |
| 282 | // and keep running. Kick off a bounded retry that re-sends Ctrl+C a few |
| 283 | // times, verifying between attempts whether the process actually exited |
| 284 | // (terminal.busy flips to false on completion). This is intentionally |
| 285 | // fire-and-forget so it never blocks the synchronous cancel path; the |
| 286 | // total retry window is bounded so dispose() is never delayed for long. |
| 287 | if (!this.aborting) { |
| 288 | this.aborting = true |
| 289 | void this.retryAbort() |
| 290 | .finally(() => { |
| 291 | this.aborting = false |
| 292 | }) |
| 293 | .catch((err) => console.error("[TerminalProcess] retryAbort error:", err)) |
| 294 | } |
| 295 | } |
| 296 | |
| 297 | /** |
| 298 | * Re-sends Ctrl+C after the immediate send in abort(), up to CTRL_C_SEND_LIMIT |
no test coverage detected