in internal/platform/utils/cmd.go [200:242]
func handleSignals(cmd *exec.Cmd, waitCh <-chan error, timeout time.Duration, timeoutExitCode int) (int, error) {
sigChan := make(chan os.Signal, 1)
signal.Notify(sigChan, os.Interrupt, syscall.SIGINT, syscall.SIGTERM)
defer func() {
signal.Stop(sigChan) // Use Stop to prevent panics
close(sigChan)
}()
var timeoutCh = time.After(timeout)
for {
select {
case <-sigChan:
if err := RequestTermination(cmd.Process); err != nil && !errors.Is(
err,
os.ErrProcessDone,
) { // Use errors.Is for semantic comparison
log.Error("Error terminating process: ", err)
}
case <-timeoutCh:
if err := RequestTermination(cmd.Process); err != nil {
log.Fatal("failed to kill process on timeout: ", err)
}
_, _ = cmd.Process.Wait()
return timeoutExitCode, nil
case ret := <-waitCh:
var exitError *exec.ExitError
if errors.As(ret, &exitError) {
log.Println(ret)
waitStatus := exitError.Sys().(syscall.WaitStatus)
if waitStatus.Exited() {
return waitStatus.ExitStatus(), nil
}
log.Println("Process killed (OOM?)")
return QodanaOutOfMemoryExitCode, nil
}
if ret != nil {
log.Println(ret)
}
return cmd.ProcessState.ExitCode(), ret
}
}
}