reaper.go 935 B

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