reexec.go 1.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051
  1. // Package reexec facilitates the busybox style reexec of the docker binary that
  2. // we require because of the forking limitations of using Go. Handlers can be
  3. // registered with a name and the argv 0 of the exec of the binary will be used
  4. // to find and execute custom init paths.
  5. package reexec // import "github.com/docker/docker/pkg/reexec"
  6. import (
  7. "fmt"
  8. "os"
  9. "os/exec"
  10. "path/filepath"
  11. )
  12. var registeredInitializers = make(map[string]func())
  13. // Register adds an initialization func under the specified name
  14. func Register(name string, initializer func()) {
  15. if _, exists := registeredInitializers[name]; exists {
  16. panic(fmt.Sprintf("reexec func already registered under name %q", name))
  17. }
  18. registeredInitializers[name] = initializer
  19. }
  20. // Init is called as the first part of the exec process and returns true if an
  21. // initialization function was called.
  22. func Init() bool {
  23. initializer, exists := registeredInitializers[os.Args[0]]
  24. if exists {
  25. initializer()
  26. return true
  27. }
  28. return false
  29. }
  30. func naiveSelf() string {
  31. name := os.Args[0]
  32. if filepath.Base(name) == name {
  33. if lp, err := exec.LookPath(name); err == nil {
  34. return lp
  35. }
  36. }
  37. // handle conversion of relative paths to absolute
  38. if absName, err := filepath.Abs(name); err == nil {
  39. return absName
  40. }
  41. // if we couldn't get absolute name, return original
  42. // (NOTE: Go only errors on Abs() if os.Getwd fails)
  43. return name
  44. }