exec.go 1.3 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162
  1. // +build linux
  2. package native
  3. import (
  4. "fmt"
  5. "os"
  6. "os/exec"
  7. "syscall"
  8. "github.com/docker/docker/daemon/execdriver"
  9. "github.com/docker/libcontainer"
  10. _ "github.com/docker/libcontainer/nsenter"
  11. "github.com/docker/libcontainer/utils"
  12. )
  13. func (d *driver) Exec(c *execdriver.Command, processConfig *execdriver.ProcessConfig, pipes *execdriver.Pipes, startCallback execdriver.StartCallback) (int, error) {
  14. active := d.activeContainers[c.ID]
  15. if active == nil {
  16. return -1, fmt.Errorf("No active container exists with ID %s", c.ID)
  17. }
  18. p := &libcontainer.Process{
  19. Args: append([]string{processConfig.Entrypoint}, processConfig.Arguments...),
  20. Env: c.ProcessConfig.Env,
  21. Cwd: c.WorkingDir,
  22. User: processConfig.User,
  23. }
  24. if processConfig.Privileged {
  25. p.Capabilities = execdriver.GetAllCapabilities()
  26. }
  27. config := active.Config()
  28. if err := setupPipes(&config, processConfig, p, pipes); err != nil {
  29. return -1, err
  30. }
  31. if err := active.Start(p); err != nil {
  32. return -1, err
  33. }
  34. if startCallback != nil {
  35. pid, err := p.Pid()
  36. if err != nil {
  37. p.Signal(os.Kill)
  38. p.Wait()
  39. return -1, err
  40. }
  41. startCallback(&c.ProcessConfig, pid)
  42. }
  43. ps, err := p.Wait()
  44. if err != nil {
  45. exitErr, ok := err.(*exec.ExitError)
  46. if !ok {
  47. return -1, err
  48. }
  49. ps = exitErr.ProcessState
  50. }
  51. return utils.ExitStatus(ps.Sys().(syscall.WaitStatus)), nil
  52. }