diff --git a/backend/networking/shutdown.go b/backend/networking/shutdown.go index 29494d54..ba5699f9 100644 --- a/backend/networking/shutdown.go +++ b/backend/networking/shutdown.go @@ -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 - } -} diff --git a/backend/networking/shutdown_linux.go b/backend/networking/shutdown_linux.go new file mode 100644 index 00000000..5487483f --- /dev/null +++ b/backend/networking/shutdown_linux.go @@ -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) +} diff --git a/backend/networking/shutdown_other.go b/backend/networking/shutdown_other.go new file mode 100644 index 00000000..99cb7d23 --- /dev/null +++ b/backend/networking/shutdown_other.go @@ -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 +}