@@ -20,6 +20,7 @@ import (
2020	"golang.org/x/sys/unix" 
2121
2222	"github.com/opencontainers/cgroups" 
23+ 	"github.com/opencontainers/runc/internal/linux" 
2324	"github.com/opencontainers/runc/libcontainer/configs" 
2425	"github.com/opencontainers/runc/libcontainer/exeseal" 
2526	"github.com/opencontainers/runc/libcontainer/intelrdt" 
@@ -231,76 +232,17 @@ func (c *Container) Exec() error {
231232}
232233
233234func  (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 )
235+ 	fifoPath  :=  filepath .Join (c .stateDir , execFifoFilename )
236+ 	fd , err  :=  linux .Open (fifoPath , unix .O_WRONLY | unix .O_CLOEXEC , 0 )
258237	if  err  !=  nil  {
259238		return  err 
260239	}
261- 	if  len ( data )  <=   0  {
262- 		return  errors . New ( "cannot start an already running container" ) 
240+ 	if  _ ,  err   :=   unix . Write ( fd , [] byte ( "0" ));  err   !=   nil  {
241+ 		return  & os. PathError { Op :  "write exec fifo" ,  Path :  fifoPath ,  Err :  err } 
263242	}
264243	return  nil 
265244}
266245
267- func  awaitFifoOpen (path  string ) <- chan  openResult  {
268- 	fifoOpened  :=  make (chan  openResult )
269- 	go  func () {
270- 		result  :=  fifoOpen (path , true )
271- 		fifoOpened  <-  result 
272- 	}()
273- 	return  fifoOpened 
274- }
275- 
276- func  fifoOpen (path  string , block  bool ) openResult  {
277- 	flags  :=  os .O_RDONLY 
278- 	if  ! block  {
279- 		flags  |=  unix .O_NONBLOCK 
280- 	}
281- 	f , err  :=  os .OpenFile (path , flags , 0 )
282- 	if  err  !=  nil  {
283- 		return  openResult {err : fmt .Errorf ("exec fifo: %w" , err )}
284- 	}
285- 	return  openResult {file : f }
286- }
287- 
288- func  handleFifoResult (result  openResult ) error  {
289- 	if  result .err  !=  nil  {
290- 		return  result .err 
291- 	}
292- 	f  :=  result .file 
293- 	defer  f .Close ()
294- 	if  err  :=  readFromExecFifo (f ); err  !=  nil  {
295- 		return  err 
296- 	}
297- 	err  :=  os .Remove (f .Name ())
298- 	if  err  ==  nil  ||  os .IsNotExist (err ) {
299- 		return  nil 
300- 	}
301- 	return  err 
302- }
303- 
304246type  openResult  struct  {
305247	file  * os.File 
306248	err   error 
0 commit comments