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 <tibor@docker.com>
This commit is contained in:
Tibor Vass 2015-07-24 13:51:51 -04:00
parent 0cec613de9
commit 264e16318f
3 changed files with 15 additions and 4 deletions

View file

@ -7,10 +7,16 @@ import (
"syscall" "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 // Command returns *exec.Cmd which have Path as current binary. Also it setting
// SysProcAttr.Pdeathsig to SIGTERM. // SysProcAttr.Pdeathsig to SIGTERM.
// For example if current binary is "docker" at "/usr/bin", then cmd.Path will // This will use the in-memory version (/proc/self/exe) of the current binary,
// be set to "/usr/bin/docker". // it is thus safe to delete or replace the on-disk binary (os.Args[0]).
func Command(args ...string) *exec.Cmd { func Command(args ...string) *exec.Cmd {
return &exec.Cmd{ return &exec.Cmd{
Path: Self(), Path: Self(),

View file

@ -6,6 +6,12 @@ import (
"os/exec" "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. // Command returns *exec.Cmd which have Path as current binary.
// For example if current binary is "docker.exe" at "C:\", then cmd.Path will // For example if current binary is "docker.exe" at "C:\", then cmd.Path will
// be set to "C:\docker.exe". // be set to "C:\docker.exe".

View file

@ -30,8 +30,7 @@ func Init() bool {
return false return false
} }
// Self returns the path to the current processes binary func naiveSelf() string {
func Self() string {
name := os.Args[0] name := os.Args[0]
if filepath.Base(name) == name { if filepath.Base(name) == name {
if lp, err := exec.LookPath(name); err == nil { if lp, err := exec.LookPath(name); err == nil {