diff --git a/pkg/reexec/command_linux.go b/pkg/reexec/command_linux.go deleted file mode 100644 index 952633c864..0000000000 --- a/pkg/reexec/command_linux.go +++ /dev/null @@ -1,26 +0,0 @@ -package reexec - -import ( - "os/exec" - "syscall" -) - -// Command returns an [*exec.Cmd] which has Path as current binary which, -// on Linux, is set to 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]). -// -// On Linux, the Pdeathsig of [*exec.Cmd.SysProcAttr] is set to SIGTERM. -// This signal will be sent to the process when the OS thread which created -// the process dies. -// -// It is the caller's responsibility to ensure that the creating thread is -// not terminated prematurely. See https://go.dev/issue/27505 for more details. -func Command(args ...string) *exec.Cmd { - return &exec.Cmd{ - Path: Self(), - Args: args, - SysProcAttr: &syscall.SysProcAttr{ - Pdeathsig: syscall.SIGTERM, - }, - } -} diff --git a/pkg/reexec/command_other.go b/pkg/reexec/command_other.go deleted file mode 100644 index b458ef2d20..0000000000 --- a/pkg/reexec/command_other.go +++ /dev/null @@ -1,19 +0,0 @@ -//go:build freebsd || darwin || windows - -package reexec - -import ( - "os/exec" -) - -// Command returns *exec.Cmd with its Path set to the path of the current -// binary using the result of [Self]. For example if current binary is -// "my-binary" at "/usr/bin/" (or "my-binary.exe" at "C:\" on Windows), -// then cmd.Path is set to "/usr/bin/my-binary" and "C:\my-binary.exe" -// respectively. -func Command(args ...string) *exec.Cmd { - return &exec.Cmd{ - Path: Self(), - Args: args, - } -} diff --git a/pkg/reexec/command_unsupported.go b/pkg/reexec/command_unsupported.go deleted file mode 100644 index 3e98b989a3..0000000000 --- a/pkg/reexec/command_unsupported.go +++ /dev/null @@ -1,12 +0,0 @@ -//go:build !linux && !windows && !freebsd && !darwin - -package reexec - -import ( - "os/exec" -) - -// Command is unsupported on operating systems apart from Linux, Windows, and Darwin. -func Command(args ...string) *exec.Cmd { - return nil -} diff --git a/pkg/reexec/reexec.go b/pkg/reexec/reexec.go index b9d11a2a58..c3a0c925e9 100644 --- a/pkg/reexec/reexec.go +++ b/pkg/reexec/reexec.go @@ -3,7 +3,7 @@ // Handlers can be registered with a name and the argv 0 of the exec of // the binary will be used to find and execute custom init paths. // -// It is used in dockerd to work around forking limitations when using Go. +// It is used to work around forking limitations when using Go. package reexec import ( @@ -36,10 +36,29 @@ func Init() bool { return false } -// Self returns the path to the current process's binary. On Linux, it -// returns "/proc/self/exe", which provides the in-memory version of the -// current binary, whereas on other platforms it attempts to looks up the -// absolute path for os.Args[0], or otherwise returns os.Args[0] as-is. +// Command returns an [*exec.Cmd] with its Path set to the path of the current +// binary using the result of [Self]. +// +// On Linux, the Pdeathsig of [*exec.Cmd.SysProcAttr] is set to SIGTERM. +// This signal is sent to the process when the OS thread that created +// the process dies. +// +// It is the caller's responsibility to ensure that the creating thread is +// not terminated prematurely. See https://go.dev/issue/27505 for more details. +func Command(args ...string) *exec.Cmd { + return command(args...) +} + +// Self returns the path to the current process's binary. +// +// On Linux, it returns "/proc/self/exe", which provides the in-memory version +// of the current binary. This makes it safe to delete or replace the on-disk +// binary (os.Args[0]). +// +// On Other platforms, it attempts to look up the absolute path for os.Args[0], +// or otherwise returns os.Args[0] as-is. For example if current binary is +// "my-binary" at "/usr/bin/" (or "my-binary.exe" at "C:\" on Windows), +// then it returns "/usr/bin/my-binary" and "C:\my-binary.exe" respectively. func Self() string { if runtime.GOOS == "linux" { return "/proc/self/exe" diff --git a/pkg/reexec/reexec_linux.go b/pkg/reexec/reexec_linux.go new file mode 100644 index 0000000000..03f600e04f --- /dev/null +++ b/pkg/reexec/reexec_linux.go @@ -0,0 +1,16 @@ +package reexec + +import ( + "os/exec" + "syscall" +) + +func command(args ...string) *exec.Cmd { + return &exec.Cmd{ + Path: Self(), + Args: args, + SysProcAttr: &syscall.SysProcAttr{ + Pdeathsig: syscall.SIGTERM, + }, + } +} diff --git a/pkg/reexec/reexec_other.go b/pkg/reexec/reexec_other.go new file mode 100644 index 0000000000..498d28bc41 --- /dev/null +++ b/pkg/reexec/reexec_other.go @@ -0,0 +1,14 @@ +//go:build !linux + +package reexec + +import ( + "os/exec" +) + +func command(args ...string) *exec.Cmd { + return &exec.Cmd{ + Path: Self(), + Args: args, + } +} diff --git a/pkg/reexec/reexec_test.go b/pkg/reexec/reexec_test.go index 5290c2adb8..0230cad585 100644 --- a/pkg/reexec/reexec_test.go +++ b/pkg/reexec/reexec_test.go @@ -6,8 +6,10 @@ import ( "testing" ) +const testReExec = "test-reexec" + func init() { - Register("reexec", func() { + Register(testReExec, func() { panic("Return Error") }) Init() @@ -16,17 +18,17 @@ func init() { func TestRegister(t *testing.T) { defer func() { if r := recover(); r != nil { - const expected = `reexec func already registered under name "reexec"` + const expected = `reexec func already registered under name "test-reexec"` if r != expected { t.Errorf("got %q, want %q", r, expected) } } }() - Register("reexec", func() {}) + Register(testReExec, func() {}) } func TestCommand(t *testing.T) { - cmd := Command("reexec") + cmd := Command(testReExec) w, err := cmd.StdinPipe() if err != nil { t.Fatalf("Error on pipe creation: %v", err)