Skip to content

Commit 6cac705

Browse files
committed
fix: if perm error terminating children, try sudo
Signed-off-by: Harper, Jason M <[email protected]>
1 parent 716954c commit 6cac705

File tree

1 file changed

+27
-2
lines changed

1 file changed

+27
-2
lines changed

internal/util/util.go

Lines changed: 27 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -19,12 +19,14 @@ import (
1919
"log/slog"
2020
"math"
2121
"os"
22+
"os/exec"
2223
"os/user"
2324
"path/filepath"
2425
"regexp"
2526
"slices"
2627
"strconv"
2728
"strings"
29+
"syscall"
2830
"unicode"
2931
)
3032

@@ -537,13 +539,36 @@ func GetAppDir() string {
537539

538540
// SignalProcess sends a signal to the process with the given PID
539541
func SignalProcess(pid int, sig os.Signal) error {
540-
proc, err := os.FindProcess(pid)
542+
proc, err := os.FindProcess(pid) // FindProcess always succeeds on Linux
541543
if err != nil {
542-
return fmt.Errorf("failed to find process: %w", err)
544+
return fmt.Errorf("this shouldn't happen: failed to find process: %w", err)
545+
}
546+
err = proc.Signal(syscall.Signal(0)) // detect if process exists
547+
if err != nil {
548+
return fmt.Errorf("process with pid %d does not exist: %w", pid, err)
543549
}
544550
slog.Debug("sending signal to process", slog.Int("pid", pid), slog.String("signal", sig.String()))
545551
err = proc.Signal(sig)
546552
if err != nil {
553+
// Check if EPERM - try sudo as fallback
554+
var errno syscall.Errno
555+
if errors.As(err, &errno) && errno == syscall.EPERM {
556+
slog.Debug("permission denied, attempting with sudo", slog.Int("pid", pid))
557+
// Convert os.Signal to signal number
558+
var sigNum int
559+
if s, ok := sig.(syscall.Signal); ok {
560+
sigNum = int(s)
561+
} else {
562+
return fmt.Errorf("unsupported signal type: %T", sig)
563+
}
564+
// Try sudo kill as fallback
565+
cmd := exec.Command("sudo", "-n", "kill", "-"+strconv.Itoa(sigNum), strconv.Itoa(pid))
566+
if cmdErr := cmd.Run(); cmdErr == nil {
567+
slog.Debug("successfully killed process with sudo", slog.Int("pid", pid))
568+
return nil
569+
}
570+
slog.Debug("sudo kill also failed", slog.Int("pid", pid))
571+
}
547572
return fmt.Errorf("failed to send signal to process (pid %d): %w", pid, err)
548573
}
549574
return nil

0 commit comments

Comments
 (0)