Files
newt/reexec_windows.go
2026-07-01 15:18:29 -04:00

41 lines
1.1 KiB
Go

//go:build windows
package main
import (
"fmt"
"os"
"os/exec"
)
// reexec restarts newt. On Windows, execve is not available, so outside of
// service mode we start a child process and exit (on success this never
// returns since os.Exit terminates the current process).
//
// When running as a Windows service, spawning a detached child would orphan
// it from the Service Control Manager (the SCM only tracks processes it
// started itself), and os.Exit would end the process without ever reporting
// a clean status transition, making the service look like it crashed. So in
// that case we instead delegate to requestServiceRestart, which asks the SCM
// itself to relaunch the service.
func reexec() error {
if isWindowsService() {
return requestServiceRestart()
}
exe, err := os.Executable()
if err != nil {
return fmt.Errorf("failed to get executable path: %w", err)
}
cmd := exec.Command(exe, os.Args[1:]...)
cmd.Stdout = os.Stdout
cmd.Stderr = os.Stderr
cmd.Stdin = os.Stdin
cmd.Env = os.Environ()
if err := cmd.Start(); err != nil {
return fmt.Errorf("failed to start new process: %w", err)
}
os.Exit(0)
return nil // unreachable
}