Skip to content

Commit

Permalink
cmd/syncthing: Work around binary in current dir restriction (fixes #…
Browse files Browse the repository at this point in the history
  • Loading branch information
imsodin committed Aug 14, 2022
1 parent eb81f74 commit 5fd6278
Showing 1 changed file with 35 additions and 10 deletions.
45 changes: 35 additions & 10 deletions cmd/syncthing/monitor.go
Original file line number Diff line number Diff line change
Expand Up @@ -83,6 +83,15 @@ func monitorMain(options serveOptions) {
}

args := os.Args
binary := args[0]
if build.IsWindows {
var err error
binary, err = expandExecutableInCurrentDirectory(binary)
if err != nil {
l.Warnln("Error starting the main Syncthing process:", err)
panic("Error starting the main Syncthing process")
}
}
var restarts [restartCounts]time.Time

stopSign := make(chan os.Signal, 1)
Expand All @@ -104,7 +113,7 @@ func monitorMain(options serveOptions) {
copy(restarts[0:], restarts[1:])
restarts[len(restarts)-1] = time.Now()

cmd := exec.Command(args[0], args[1:]...)
cmd := exec.Command(binary, args[1:]...)
cmd.Env = childEnv

stderr, err := cmd.StderrPipe()
Expand Down Expand Up @@ -180,7 +189,7 @@ func monitorMain(options serveOptions) {
// Restart the monitor process to release the .old
// binary as part of the upgrade process.
l.Infoln("Restarting monitor...")
if err = restartMonitor(args); err != nil {
if err = restartMonitor(binary, args); err != nil {
l.Warnln("Restart:", err)
}
os.Exit(exitCode)
Expand All @@ -203,6 +212,21 @@ func monitorMain(options serveOptions) {
}
}

func expandExecutableInCurrentDirectory(args0 string) (string, error) {
// Works around a restriction added in go1.19 that executables in the
// current directory are not resolved when specifying just an executable
// name (like e.g. "syncthing")
if !strings.ContainsRune(args0, os.PathSeparator) {
// Check if it's in PATH
_, err := exec.LookPath(args0)
if err != nil {
// Try to get the path to the current executable
return os.Executable()
}
}
return args0, nil
}

func copyStderr(stderr io.Reader, dst io.Writer) {
br := bufio.NewReader(stderr)

Expand Down Expand Up @@ -309,7 +333,7 @@ func copyStdout(stdout io.Reader, dst io.Writer) {
}
}

func restartMonitor(args []string) error {
func restartMonitor(binary string, args []string) error {
// Set the STRESTART environment variable to indicate to the next
// process that this is a restart and not initial start. This prevents
// opening the browser on startup.
Expand All @@ -319,19 +343,20 @@ func restartMonitor(args []string) error {
// syscall.Exec is the cleanest way to restart on Unixes as it
// replaces the current process with the new one, keeping the pid and
// controlling terminal and so on
return restartMonitorUnix(args)
return restartMonitorUnix(binary, args)
}

// but it isn't supported on Windows, so there we start a normal
// exec.Command and return.
return restartMonitorWindows(args)
return restartMonitorWindows(binary, args)
}

func restartMonitorUnix(args []string) error {
if !strings.ContainsRune(args[0], os.PathSeparator) {
func restartMonitorUnix(binary string, args []string) error {
if !strings.ContainsRune(binary, os.PathSeparator) {
// The path to the binary doesn't contain a slash, so it should be
// found in $PATH.
binary, err := exec.LookPath(args[0])
var err error
binary, err = exec.LookPath(binary)
if err != nil {
return err
}
Expand All @@ -341,8 +366,8 @@ func restartMonitorUnix(args []string) error {
return syscall.Exec(args[0], args, os.Environ())
}

func restartMonitorWindows(args []string) error {
cmd := exec.Command(args[0], args[1:]...)
func restartMonitorWindows(binary string, args []string) error {
cmd := exec.Command(binary, args[1:]...)
// Retain the standard streams
cmd.Stderr = os.Stderr
cmd.Stdout = os.Stdout
Expand Down

0 comments on commit 5fd6278

Please sign in to comment.