github.com/scorpionis/docker@v1.6.0-rc7/daemon/execdriver/native/exec.go (about) 1 // +build linux 2 3 package native 4 5 import ( 6 "fmt" 7 "os" 8 "os/exec" 9 "syscall" 10 11 "github.com/docker/docker/daemon/execdriver" 12 "github.com/docker/libcontainer" 13 _ "github.com/docker/libcontainer/nsenter" 14 "github.com/docker/libcontainer/utils" 15 ) 16 17 // TODO(vishh): Add support for running in priviledged mode and running as a different user. 18 func (d *driver) Exec(c *execdriver.Command, processConfig *execdriver.ProcessConfig, pipes *execdriver.Pipes, startCallback execdriver.StartCallback) (int, error) { 19 active := d.activeContainers[c.ID] 20 if active == nil { 21 return -1, fmt.Errorf("No active container exists with ID %s", c.ID) 22 } 23 24 var term execdriver.Terminal 25 var err error 26 27 p := &libcontainer.Process{ 28 Args: append([]string{processConfig.Entrypoint}, processConfig.Arguments...), 29 Env: c.ProcessConfig.Env, 30 Cwd: c.WorkingDir, 31 User: c.ProcessConfig.User, 32 } 33 34 if processConfig.Tty { 35 config := active.Config() 36 rootuid, err := config.HostUID() 37 if err != nil { 38 return -1, err 39 } 40 cons, err := p.NewConsole(rootuid) 41 if err != nil { 42 return -1, err 43 } 44 term, err = NewTtyConsole(cons, pipes, rootuid) 45 } else { 46 p.Stdout = pipes.Stdout 47 p.Stderr = pipes.Stderr 48 p.Stdin = pipes.Stdin 49 term = &execdriver.StdConsole{} 50 } 51 if err != nil { 52 return -1, err 53 } 54 55 processConfig.Terminal = term 56 57 if err := active.Start(p); err != nil { 58 return -1, err 59 } 60 61 if startCallback != nil { 62 pid, err := p.Pid() 63 if err != nil { 64 p.Signal(os.Kill) 65 p.Wait() 66 return -1, err 67 } 68 startCallback(&c.ProcessConfig, pid) 69 } 70 71 ps, err := p.Wait() 72 if err != nil { 73 exitErr, ok := err.(*exec.ExitError) 74 if !ok { 75 return -1, err 76 } 77 ps = exitErr.ProcessState 78 } 79 return utils.ExitStatus(ps.Sys().(syscall.WaitStatus)), nil 80 }