github.com/SagerNet/gvisor@v0.0.0-20210707092255-7731c139d75c/pkg/shim/proc/exec_state.go (about) 1 // Copyright 2018 The containerd Authors. 2 // Copyright 2018 The gVisor Authors. 3 // 4 // Licensed under the Apache License, Version 2.0 (the "License"); 5 // you may not use this file except in compliance with the License. 6 // You may obtain a copy of the License at 7 // 8 // https://www.apache.org/licenses/LICENSE-2.0 9 // 10 // Unless required by applicable law or agreed to in writing, software 11 // distributed under the License is distributed on an "AS IS" BASIS, 12 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 // See the License for the specific language governing permissions and 14 // limitations under the License. 15 16 package proc 17 18 import ( 19 "context" 20 "fmt" 21 22 "github.com/containerd/console" 23 ) 24 25 type execState interface { 26 Resize(console.WinSize) error 27 Start(context.Context) error 28 Delete(context.Context) error 29 Kill(context.Context, uint32, bool) error 30 SetExited(int) 31 } 32 33 type execCreatedState struct { 34 p *execProcess 35 } 36 37 func (s *execCreatedState) name() string { 38 return "created" 39 } 40 41 func (s *execCreatedState) transition(transition stateTransition) { 42 switch transition { 43 case running: 44 s.p.execState = &execRunningState{p: s.p} 45 case stopped: 46 s.p.execState = &execStoppedState{p: s.p} 47 case deleted: 48 s.p.execState = &deletedState{} 49 default: 50 panic(fmt.Sprintf("invalid state transition %q to %q", s.name(), transition)) 51 } 52 } 53 54 func (s *execCreatedState) Resize(ws console.WinSize) error { 55 return s.p.resize(ws) 56 } 57 58 func (s *execCreatedState) Start(ctx context.Context) error { 59 if err := s.p.start(ctx); err != nil { 60 return err 61 } 62 s.transition(running) 63 return nil 64 } 65 66 func (s *execCreatedState) Delete(context.Context) error { 67 if err := s.p.delete(); err != nil { 68 return err 69 } 70 s.transition(deleted) 71 return nil 72 } 73 74 func (s *execCreatedState) Kill(ctx context.Context, sig uint32, all bool) error { 75 return s.p.kill(ctx, sig, all) 76 } 77 78 func (s *execCreatedState) SetExited(status int) { 79 s.p.setExited(status) 80 s.transition(stopped) 81 } 82 83 type execRunningState struct { 84 p *execProcess 85 } 86 87 func (s *execRunningState) name() string { 88 return "running" 89 } 90 91 func (s *execRunningState) transition(transition stateTransition) { 92 switch transition { 93 case stopped: 94 s.p.execState = &execStoppedState{p: s.p} 95 default: 96 panic(fmt.Sprintf("invalid state transition %q to %q", s.name(), transition)) 97 } 98 } 99 100 func (s *execRunningState) Resize(ws console.WinSize) error { 101 return s.p.resize(ws) 102 } 103 104 func (s *execRunningState) Start(context.Context) error { 105 return fmt.Errorf("cannot start a running process") 106 } 107 108 func (s *execRunningState) Delete(context.Context) error { 109 return fmt.Errorf("cannot delete a running process") 110 } 111 112 func (s *execRunningState) Kill(ctx context.Context, sig uint32, all bool) error { 113 return s.p.kill(ctx, sig, all) 114 } 115 116 func (s *execRunningState) SetExited(status int) { 117 s.p.setExited(status) 118 s.transition(stopped) 119 } 120 121 type execStoppedState struct { 122 p *execProcess 123 } 124 125 func (s *execStoppedState) name() string { 126 return "stopped" 127 } 128 129 func (s *execStoppedState) transition(transition stateTransition) { 130 switch transition { 131 case deleted: 132 s.p.execState = &deletedState{} 133 default: 134 panic(fmt.Sprintf("invalid state transition %q to %q", s.name(), transition)) 135 } 136 } 137 138 func (s *execStoppedState) Resize(console.WinSize) error { 139 return fmt.Errorf("cannot resize a stopped container") 140 } 141 142 func (s *execStoppedState) Start(context.Context) error { 143 return fmt.Errorf("cannot start a stopped process") 144 } 145 146 func (s *execStoppedState) Delete(context.Context) error { 147 if err := s.p.delete(); err != nil { 148 return err 149 } 150 s.transition(deleted) 151 return nil 152 } 153 154 func (s *execStoppedState) Kill(_ context.Context, sig uint32, _ bool) error { 155 return handleStoppedKill(sig) 156 } 157 158 func (s *execStoppedState) SetExited(int) { 159 // no op 160 }