github.com/rita33cool1/iot-system-gateway@v0.0.0-20200911033302-e65bde238cc5/docker-engine/daemon/exec/exec.go (about) 1 package exec // import "github.com/docker/docker/daemon/exec" 2 3 import ( 4 "runtime" 5 "sync" 6 7 "github.com/containerd/containerd/cio" 8 "github.com/docker/docker/container/stream" 9 "github.com/docker/docker/pkg/stringid" 10 "github.com/sirupsen/logrus" 11 ) 12 13 // Config holds the configurations for execs. The Daemon keeps 14 // track of both running and finished execs so that they can be 15 // examined both during and after completion. 16 type Config struct { 17 sync.Mutex 18 StreamConfig *stream.Config 19 ID string 20 Running bool 21 ExitCode *int 22 OpenStdin bool 23 OpenStderr bool 24 OpenStdout bool 25 CanRemove bool 26 ContainerID string 27 DetachKeys []byte 28 Entrypoint string 29 Args []string 30 Tty bool 31 Privileged bool 32 User string 33 WorkingDir string 34 Env []string 35 Pid int 36 } 37 38 // NewConfig initializes the a new exec configuration 39 func NewConfig() *Config { 40 return &Config{ 41 ID: stringid.GenerateNonCryptoID(), 42 StreamConfig: stream.NewConfig(), 43 } 44 } 45 46 type rio struct { 47 cio.IO 48 49 sc *stream.Config 50 } 51 52 func (i *rio) Close() error { 53 i.IO.Close() 54 55 return i.sc.CloseStreams() 56 } 57 58 func (i *rio) Wait() { 59 i.sc.Wait() 60 61 i.IO.Wait() 62 } 63 64 // InitializeStdio is called by libcontainerd to connect the stdio. 65 func (c *Config) InitializeStdio(iop *cio.DirectIO) (cio.IO, error) { 66 c.StreamConfig.CopyToPipe(iop) 67 68 if c.StreamConfig.Stdin() == nil && !c.Tty && runtime.GOOS == "windows" { 69 if iop.Stdin != nil { 70 if err := iop.Stdin.Close(); err != nil { 71 logrus.Errorf("error closing exec stdin: %+v", err) 72 } 73 } 74 } 75 76 return &rio{IO: iop, sc: c.StreamConfig}, nil 77 } 78 79 // CloseStreams closes the stdio streams for the exec 80 func (c *Config) CloseStreams() error { 81 return c.StreamConfig.CloseStreams() 82 } 83 84 // SetExitCode sets the exec config's exit code 85 func (c *Config) SetExitCode(code int) { 86 c.ExitCode = &code 87 } 88 89 // Store keeps track of the exec configurations. 90 type Store struct { 91 byID map[string]*Config 92 sync.RWMutex 93 } 94 95 // NewStore initializes a new exec store. 96 func NewStore() *Store { 97 return &Store{ 98 byID: make(map[string]*Config), 99 } 100 } 101 102 // Commands returns the exec configurations in the store. 103 func (e *Store) Commands() map[string]*Config { 104 e.RLock() 105 byID := make(map[string]*Config, len(e.byID)) 106 for id, config := range e.byID { 107 byID[id] = config 108 } 109 e.RUnlock() 110 return byID 111 } 112 113 // Add adds a new exec configuration to the store. 114 func (e *Store) Add(id string, Config *Config) { 115 e.Lock() 116 e.byID[id] = Config 117 e.Unlock() 118 } 119 120 // Get returns an exec configuration by its id. 121 func (e *Store) Get(id string) *Config { 122 e.RLock() 123 res := e.byID[id] 124 e.RUnlock() 125 return res 126 } 127 128 // Delete removes an exec configuration from the store. 129 func (e *Store) Delete(id string, pid int) { 130 e.Lock() 131 delete(e.byID, id) 132 e.Unlock() 133 } 134 135 // List returns the list of exec ids in the store. 136 func (e *Store) List() []string { 137 var IDs []string 138 e.RLock() 139 for id := range e.byID { 140 IDs = append(IDs, id) 141 } 142 e.RUnlock() 143 return IDs 144 }