Merge pull request #49118 from thaJeztah/reexec_clean

pkg/reexec: some cleaning up in preparation of moving to a separate module
This commit is contained in:
Sebastiaan van Stijn
2024-12-17 17:07:05 +01:00
committed by GitHub
7 changed files with 60 additions and 66 deletions

View File

@@ -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,
},
}
}

View File

@@ -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,
}
}

View File

@@ -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
}

View File

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

View File

@@ -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,
},
}
}

View File

@@ -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,
}
}

View File

@@ -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)