fix: seperate platform specific process killing #266

This commit is contained in:
seriousm4x
2023-10-19 12:21:22 +02:00
parent 62e20969b5
commit fc3e6e6e90
3 changed files with 49 additions and 29 deletions

View File

@@ -4,13 +4,10 @@ import (
"bytes"
"context"
"fmt"
"os"
"os/exec"
"runtime"
"time"
"golang.org/x/sys/unix"
"github.com/pocketbase/pocketbase/models"
"github.com/seriousm4x/upsnap/logger"
)
@@ -35,12 +32,8 @@ func ShutdownDevice(device *models.Record) error {
ctx := context.Background()
ctx, cancel := context.WithCancel(ctx)
cmd := exec.CommandContext(ctx, shell, shell_arg, shutdown_cmd)
if runtime.GOOS == "linux" {
// set group id for child processes, windows doesn't support this
// used to avoid zombie processes
cmd.SysProcAttr = &unix.SysProcAttr{Setpgid: true}
}
SetProcessAttributes(cmd)
logger.Debug.Println(cmd)
var stderr bytes.Buffer
cmd.Stderr = &stderr
@@ -60,7 +53,7 @@ func ShutdownDevice(device *models.Record) error {
select {
case <-time.After(1 * time.Second):
if time.Since(start) >= 2*time.Minute {
if err := killProcess(cmd.Process); err != nil {
if err := KillProcess(cmd.Process); err != nil {
logger.Error.Println(err)
}
cancel()
@@ -68,7 +61,7 @@ func ShutdownDevice(device *models.Record) error {
}
isOnline := PingDevice(device)
if !isOnline {
if err := killProcess(cmd.Process); err != nil {
if err := KillProcess(cmd.Process); err != nil {
logger.Error.Println(err)
}
cancel()
@@ -76,7 +69,7 @@ func ShutdownDevice(device *models.Record) error {
}
case err := <-done:
if err != nil {
if err := killProcess(cmd.Process); err != nil {
if err := KillProcess(cmd.Process); err != nil {
logger.Error.Println(err)
}
cancel()
@@ -85,20 +78,3 @@ func ShutdownDevice(device *models.Record) error {
}
}
}
// Kills child processes on Linux. Windows doesn't provide a direct way to kill child processes, so we kill just the main process.
func killProcess(process *os.Process) error {
if runtime.GOOS == "linux" {
pgid, err := unix.Getpgid(process.Pid)
logger.Debug.Println(pgid)
if err != nil {
return err
}
return unix.Kill(-pgid, unix.SIGKILL)
} else {
if err := process.Kill(); err != nil {
return err
}
return nil
}
}

View File

@@ -0,0 +1,25 @@
package networking
import (
"os"
"os/exec"
"golang.org/x/sys/unix"
"github.com/seriousm4x/upsnap/logger"
)
// Set platform specifiy custom process attributes
func SetProcessAttributes(cmd *exec.Cmd) {
cmd.SysProcAttr = &unix.SysProcAttr{Setpgid: true}
}
// Kills child processes on Linux. Windows doesn't provide a direct way to kill child processes, so we kill just the main process.
func KillProcess(process *os.Process) error {
pgid, err := unix.Getpgid(process.Pid)
logger.Debug.Println(pgid)
if err != nil {
return err
}
return unix.Kill(-pgid, unix.SIGKILL)
}

View File

@@ -0,0 +1,19 @@
//go:build !linux
package networking
import (
"os"
"os/exec"
)
// Set platform specifiy custom process attributes
func SetProcessAttributes(cmd *exec.Cmd) {}
// Kills child processes on Linux. Windows doesn't provide a direct way to kill child processes, so we kill just the main process.
func KillProcess(process *os.Process) error {
if err := process.Kill(); err != nil {
return err
}
return nil
}