Przeglądaj źródła

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>
Tibor Vass 10 lat temu
rodzic
commit
5aee8807a6

+ 8 - 2
pkg/reexec/command_linux.go

@@ -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
-// 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 {
 func Command(args ...string) *exec.Cmd {
 	return &exec.Cmd{
 	return &exec.Cmd{
 		Path: Self(),
 		Path: Self(),

+ 6 - 0
pkg/reexec/command_windows.go

@@ -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".

+ 1 - 2
pkg/reexec/reexec.go

@@ -30,8 +30,7 @@ func Init() bool {
 	return false
 	return false
 }
 }
 
 
-// Self returns the path to the current processes binary
-func Self() string {
+func naiveSelf() 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 {