1// +build !windows 2 3package proc 4 5import ( 6 "context" 7 8 "github.com/containerd/console" 9 "github.com/pkg/errors" 10) 11 12type execCreatedState struct { 13 p *execProcess 14} 15 16func (s *execCreatedState) transition(name string) error { 17 switch name { 18 case "running": 19 s.p.State = &execRunningState{p: s.p} 20 case "stopped": 21 s.p.State = &execStoppedState{p: s.p} 22 case "deleted": 23 s.p.State = &deletedState{} 24 default: 25 return errors.Errorf("invalid state transition %q to %q", stateName(s), name) 26 } 27 return nil 28} 29 30func (s *execCreatedState) Resize(ws console.WinSize) error { 31 s.p.mu.Lock() 32 defer s.p.mu.Unlock() 33 34 return s.p.resize(ws) 35} 36 37func (s *execCreatedState) Start(ctx context.Context) error { 38 s.p.mu.Lock() 39 defer s.p.mu.Unlock() 40 if err := s.p.start(ctx); err != nil { 41 return err 42 } 43 return s.transition("running") 44} 45 46func (s *execCreatedState) Delete(ctx context.Context) error { 47 s.p.mu.Lock() 48 defer s.p.mu.Unlock() 49 if err := s.p.delete(ctx); err != nil { 50 return err 51 } 52 return s.transition("deleted") 53} 54 55func (s *execCreatedState) Kill(ctx context.Context, sig uint32, all bool) error { 56 s.p.mu.Lock() 57 defer s.p.mu.Unlock() 58 59 return s.p.kill(ctx, sig, all) 60} 61 62func (s *execCreatedState) SetExited(status int) { 63 s.p.mu.Lock() 64 defer s.p.mu.Unlock() 65 66 s.p.setExited(status) 67 68 if err := s.transition("stopped"); err != nil { 69 panic(err) 70 } 71} 72 73type execRunningState struct { 74 p *execProcess 75} 76 77func (s *execRunningState) transition(name string) error { 78 switch name { 79 case "stopped": 80 s.p.State = &execStoppedState{p: s.p} 81 default: 82 return errors.Errorf("invalid state transition %q to %q", stateName(s), name) 83 } 84 return nil 85} 86 87func (s *execRunningState) Resize(ws console.WinSize) error { 88 s.p.mu.Lock() 89 defer s.p.mu.Unlock() 90 91 return s.p.resize(ws) 92} 93 94func (s *execRunningState) Start(ctx context.Context) error { 95 s.p.mu.Lock() 96 defer s.p.mu.Unlock() 97 98 return errors.Errorf("cannot start a running process") 99} 100 101func (s *execRunningState) Delete(ctx context.Context) error { 102 s.p.mu.Lock() 103 defer s.p.mu.Unlock() 104 105 return errors.Errorf("cannot delete a running process") 106} 107 108func (s *execRunningState) Kill(ctx context.Context, sig uint32, all bool) error { 109 s.p.mu.Lock() 110 defer s.p.mu.Unlock() 111 112 return s.p.kill(ctx, sig, all) 113} 114 115func (s *execRunningState) SetExited(status int) { 116 s.p.mu.Lock() 117 defer s.p.mu.Unlock() 118 119 s.p.setExited(status) 120 121 if err := s.transition("stopped"); err != nil { 122 panic(err) 123 } 124} 125 126type execStoppedState struct { 127 p *execProcess 128} 129 130func (s *execStoppedState) transition(name string) error { 131 switch name { 132 case "deleted": 133 s.p.State = &deletedState{} 134 default: 135 return errors.Errorf("invalid state transition %q to %q", stateName(s), name) 136 } 137 return nil 138} 139 140func (s *execStoppedState) Resize(ws console.WinSize) error { 141 s.p.mu.Lock() 142 defer s.p.mu.Unlock() 143 144 return errors.Errorf("cannot resize a stopped container") 145} 146 147func (s *execStoppedState) Start(ctx context.Context) error { 148 s.p.mu.Lock() 149 defer s.p.mu.Unlock() 150 151 return errors.Errorf("cannot start a stopped process") 152} 153 154func (s *execStoppedState) Delete(ctx context.Context) error { 155 s.p.mu.Lock() 156 defer s.p.mu.Unlock() 157 if err := s.p.delete(ctx); err != nil { 158 return err 159 } 160 return s.transition("deleted") 161} 162 163func (s *execStoppedState) Kill(ctx context.Context, sig uint32, all bool) error { 164 s.p.mu.Lock() 165 defer s.p.mu.Unlock() 166 167 return s.p.kill(ctx, sig, all) 168} 169 170func (s *execStoppedState) SetExited(status int) { 171 // no op 172} 173