From 264e16318f72ea28de04cbb86db4101ef65a39df Mon Sep 17 00:00:00 2001 From: Tibor Vass Date: Fri, 24 Jul 2015 13:51:51 -0400 Subject: [PATCH] reexec: Use in-memory binary on linux instead of os.Args[0] This keeps reexec working properly even if the on-disk binary was replaced. Signed-off-by: Tibor Vass --- reexec/command_linux.go | 10 ++++++++-- reexec/command_windows.go | 6 ++++++ reexec/reexec.go | 3 +-- 3 files changed, 15 insertions(+), 4 deletions(-) diff --git a/reexec/command_linux.go b/reexec/command_linux.go index e22a023..3c3a73a 100644 --- a/reexec/command_linux.go +++ b/reexec/command_linux.go @@ -7,10 +7,16 @@ import ( "syscall" ) +// Self returns the path to the current process's binary. +// Returns "/proc/self/exe". +func Self() string { + return "/proc/self/exe" +} + // Command returns *exec.Cmd which have Path as current binary. Also it setting // SysProcAttr.Pdeathsig to SIGTERM. -// For example if current binary is "docker" at "/usr/bin", then cmd.Path will -// be set to "/usr/bin/docker". +// This will use the in-memory version (/proc/self/exe) of the current binary, +// it is thus safe to delete or replace the on-disk binary (os.Args[0]). func Command(args ...string) *exec.Cmd { return &exec.Cmd{ Path: Self(), diff --git a/reexec/command_windows.go b/reexec/command_windows.go index a2a7aa9..8d65e0a 100644 --- a/reexec/command_windows.go +++ b/reexec/command_windows.go @@ -6,6 +6,12 @@ import ( "os/exec" ) +// Self returns the path to the current process's binary. +// Uses os.Args[0]. +func Self() string { + return naiveSelf() +} + // Command returns *exec.Cmd which have Path as current binary. // For example if current binary is "docker.exe" at "C:\", then cmd.Path will // be set to "C:\docker.exe". diff --git a/reexec/reexec.go b/reexec/reexec.go index a5f01a2..20491e0 100644 --- a/reexec/reexec.go +++ b/reexec/reexec.go @@ -30,8 +30,7 @@ func Init() bool { return false } -// Self returns the path to the current processes binary -func Self() string { +func naiveSelf() string { name := os.Args[0] if filepath.Base(name) == name { if lp, err := exec.LookPath(name); err == nil {