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
import (
"errors"
"fmt"
"log/slog"
"os"
"os/exec"
"path/filepath"
"runtime"
"slices"
"strings"
"syscall"
"time"
)
@ -84,8 +81,7 @@ func KillAll(skipFlag ...RunFlag) {
if shouldSkipKilling(command.flags, skipFlag) {
continue
}
pid := command.cmd.Process.Pid
err := syscall.Kill(-pid, syscall.SIGKILL)
err := KillProcess(command.cmd.Process)
if err != nil {
continue
}
@ -100,12 +96,9 @@ func KillAll(skipFlag ...RunFlag) {
if shouldSkipKilling(c.flags, skipFlag) {
continue
}
exists, err := PidExists(int32(c.cmd.Process.Pid))
if err != nil {
finished = false
}
exists := PidExists(int32(c.cmd.Process.Pid))
if exists {
syscall.Kill(-c.cmd.Process.Pid, syscall.SIGKILL)
KillProcess(c.cmd.Process)
finished = false
}
}
@ -122,35 +115,6 @@ func KillAll(skipFlag ...RunFlag) {
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) {
_ = Run(command, ExitOnError)
}
@ -180,9 +144,7 @@ func Run(command string, flags ...RunFlag) error {
parts := strings.Fields(command)
cmd := exec.Command(parts[0], parts[1:]...)
if runtime.GOOS != "windows" {
cmd.SysProcAttr = &syscall.SysProcAttr{Setpgid: true}
}
PrepareCommand(cmd)
if slices.Contains(flags, Silent) {
cmd.Stdout = nil