windows specific code
This commit is contained in:
parent
c6a0d0e985
commit
12f9d81ecd
3 changed files with 82 additions and 42 deletions
47
cli/htmgo/tasks/process/pid_unix.go
Normal file
47
cli/htmgo/tasks/process/pid_unix.go
Normal 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
|
||||||
|
}
|
||||||
31
cli/htmgo/tasks/process/pid_windows.go
Normal file
31
cli/htmgo/tasks/process/pid_windows.go
Normal 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
|
||||||
|
}
|
||||||
|
|
@ -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
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue