()
| 231 | } |
| 232 | |
| 233 | func (c *Container) exec() error { |
| 234 | path := filepath.Join(c.stateDir, execFifoFilename) |
| 235 | pid := c.initProcess.pid() |
| 236 | blockingFifoOpenCh := awaitFifoOpen(path) |
| 237 | for { |
| 238 | select { |
| 239 | case result := <-blockingFifoOpenCh: |
| 240 | return handleFifoResult(result) |
| 241 | |
| 242 | case <-time.After(time.Millisecond * 100): |
| 243 | stat, err := system.Stat(pid) |
| 244 | if err != nil || stat.State == system.Zombie { |
| 245 | // could be because process started, ran, and completed between our 100ms timeout and our system.Stat() check. |
| 246 | // see if the fifo exists and has data (with a non-blocking open, which will succeed if the writing process is complete). |
| 247 | if err := handleFifoResult(fifoOpen(path, false)); err != nil { |
| 248 | return errors.New("container process is already dead") |
| 249 | } |
| 250 | return nil |
| 251 | } |
| 252 | } |
| 253 | } |
| 254 | } |
| 255 | |
| 256 | func readFromExecFifo(execFifo io.Reader) error { |
| 257 | data, err := io.ReadAll(execFifo) |
no test coverage detected