exec.go 1.3 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859
  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. // TODO(vishh): Add support for running in privileged mode.
  14. func (d *driver) Exec(c *execdriver.Command, processConfig *execdriver.ProcessConfig, pipes *execdriver.Pipes, startCallback execdriver.StartCallback) (int, error) {
  15. active := d.activeContainers[c.ID]
  16. if active == nil {
  17. return -1, fmt.Errorf("No active container exists with ID %s", c.ID)
  18. }
  19. p := &libcontainer.Process{
  20. Args: append([]string{processConfig.Entrypoint}, processConfig.Arguments...),
  21. Env: c.ProcessConfig.Env,
  22. Cwd: c.WorkingDir,
  23. User: processConfig.User,
  24. }
  25. config := active.Config()
  26. if err := setupPipes(&config, processConfig, p, pipes); err != nil {
  27. return -1, err
  28. }
  29. if err := active.Start(p); err != nil {
  30. return -1, err
  31. }
  32. if startCallback != nil {
  33. pid, err := p.Pid()
  34. if err != nil {
  35. p.Signal(os.Kill)
  36. p.Wait()
  37. return -1, err
  38. }
  39. startCallback(&c.ProcessConfig, pid)
  40. }
  41. ps, err := p.Wait()
  42. if err != nil {
  43. exitErr, ok := err.(*exec.ExitError)
  44. if !ok {
  45. return -1, err
  46. }
  47. ps = exitErr.ProcessState
  48. }
  49. return utils.ExitStatus(ps.Sys().(syscall.WaitStatus)), nil
  50. }