windows specific code

This commit is contained in:
maddalax 2024-09-23 15:06:59 -05:00
parent c6a0d0e985
commit 12f9d81ecd
3 changed files with 82 additions and 42 deletions

View file

@ -0,0 +1,47 @@
//go:build linux || darwin
package process
import (
"errors"
"os"
"os/exec"
"syscall"
)
func KillProcess(process *os.Process) error {
return syscall.Kill(-process.Pid, syscall.SIGKILL)
}
func PrepareCommand(command *exec.Cmd) {
command.SysProcAttr = &syscall.SysProcAttr{Setpgid: true}
}
func PidExists(pid int32) bool {
if pid <= 0 {
return false
}
proc, err := os.FindProcess(int(pid))
if err != nil {
return false
}
err = proc.Signal(syscall.Signal(0))
if err == nil {
return true
}
if err.Error() == "os: process already finished" {
return false
}
var errno syscall.Errno
ok := errors.As(err, &errno)
if !ok {
return false
}
switch errno {
case syscall.ESRCH:
return false
case syscall.EPERM:
return true
}
return false
}

View file

@ -0,0 +1,31 @@
package process
import (
"os"
"os/exec"
)
import "golang.org/x/sys/windows"
func KillProcess(process *os.Process) error {
return process.Kill()
}
func PrepareCommand(command *exec.Cmd) {
}
func PidExists(pid int32) bool {
var handle, err = windows.OpenProcess(windows.PROCESS_QUERY_INFORMATION, false, uint32(pid))
if err != nil {
return false
}
defer windows.CloseHandle(handle)
var exitCode uint32
err = windows.GetExitCodeProcess(handle, &exitCode)
if err != nil {
return false
}
return exitCode == 259
}

View file

@ -1,16 +1,13 @@
package process package process
import ( import (
"errors"
"fmt" "fmt"
"log/slog" "log/slog"
"os" "os"
"os/exec" "os/exec"
"path/filepath" "path/filepath"
"runtime"
"slices" "slices"
"strings" "strings"
"syscall"
"time" "time"
) )
@ -84,8 +81,7 @@ func KillAll(skipFlag ...RunFlag) {
if shouldSkipKilling(command.flags, skipFlag) { if shouldSkipKilling(command.flags, skipFlag) {
continue continue
} }
pid := command.cmd.Process.Pid err := KillProcess(command.cmd.Process)
err := syscall.Kill(-pid, syscall.SIGKILL)
if err != nil { if err != nil {
continue continue
} }
@ -100,12 +96,9 @@ func KillAll(skipFlag ...RunFlag) {
if shouldSkipKilling(c.flags, skipFlag) { if shouldSkipKilling(c.flags, skipFlag) {
continue continue
} }
exists, err := PidExists(int32(c.cmd.Process.Pid)) exists := PidExists(int32(c.cmd.Process.Pid))
if err != nil {
finished = false
}
if exists { if exists {
syscall.Kill(-c.cmd.Process.Pid, syscall.SIGKILL) KillProcess(c.cmd.Process)
finished = false finished = false
} }
} }
@ -122,35 +115,6 @@ func KillAll(skipFlag ...RunFlag) {
slog.Debug("all processes killed\n") slog.Debug("all processes killed\n")
} }
func PidExists(pid int32) (bool, error) {
if pid <= 0 {
return false, fmt.Errorf("invalid pid %v", pid)
}
proc, err := os.FindProcess(int(pid))
if err != nil {
return false, err
}
err = proc.Signal(syscall.Signal(0))
if err == nil {
return true, nil
}
if err.Error() == "os: process already finished" {
return false, nil
}
var errno syscall.Errno
ok := errors.As(err, &errno)
if !ok {
return false, err
}
switch errno {
case syscall.ESRCH:
return false, nil
case syscall.EPERM:
return true, nil
}
return false, err
}
func RunOrExit(command string) { func RunOrExit(command string) {
_ = Run(command, ExitOnError) _ = Run(command, ExitOnError)
} }
@ -180,9 +144,7 @@ func Run(command string, flags ...RunFlag) error {
parts := strings.Fields(command) parts := strings.Fields(command)
cmd := exec.Command(parts[0], parts[1:]...) cmd := exec.Command(parts[0], parts[1:]...)
if runtime.GOOS != "windows" { PrepareCommand(cmd)
cmd.SysProcAttr = &syscall.SysProcAttr{Setpgid: true}
}
if slices.Contains(flags, Silent) { if slices.Contains(flags, Silent) {
cmd.Stdout = nil cmd.Stdout = nil