github.com/hinshun/containerd@v0.2.7/osutils/reaper.go (about)

     1  // +build !windows
     2  
     3  package osutils
     4  
     5  import "syscall"
     6  
     7  // Exit is the wait4 information from an exited process
     8  type Exit struct {
     9  	Pid    int
    10  	Status int
    11  }
    12  
    13  // Reap reaps all child processes for the calling process and returns their
    14  // exit information
    15  func Reap(wait bool) (exits []Exit, err error) {
    16  	var (
    17  		ws  syscall.WaitStatus
    18  		rus syscall.Rusage
    19  	)
    20  	flag := syscall.WNOHANG
    21  	if wait {
    22  		flag = 0
    23  	}
    24  	for {
    25  		pid, err := syscall.Wait4(-1, &ws, flag, &rus)
    26  		if err != nil {
    27  			if err == syscall.ECHILD {
    28  				return exits, nil
    29  			}
    30  			return exits, err
    31  		}
    32  		if pid <= 0 {
    33  			return exits, nil
    34  		}
    35  		exits = append(exits, Exit{
    36  			Pid:    pid,
    37  			Status: exitStatus(ws),
    38  		})
    39  	}
    40  }
    41  
    42  const exitSignalOffset = 128
    43  
    44  // exitStatus returns the correct exit status for a process based on if it
    45  // was signaled or exited cleanly
    46  func exitStatus(status syscall.WaitStatus) int {
    47  	if status.Signaled() {
    48  		return exitSignalOffset + int(status.Signal())
    49  	}
    50  	return status.ExitStatus()
    51  }