1// +build !windows
2
3/*
4   Copyright The containerd Authors.
5
6   Licensed under the Apache License, Version 2.0 (the "License");
7   you may not use this file except in compliance with the License.
8   You may obtain a copy of the License at
9
10       http://www.apache.org/licenses/LICENSE-2.0
11
12   Unless required by applicable law or agreed to in writing, software
13   distributed under the License is distributed on an "AS IS" BASIS,
14   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15   See the License for the specific language governing permissions and
16   limitations under the License.
17*/
18
19package sys
20
21import (
22	"golang.org/x/sys/unix"
23)
24
25// Exit is the wait4 information from an exited process
26type Exit struct {
27	Pid    int
28	Status int
29}
30
31// Reap reaps all child processes for the calling process and returns their
32// exit information
33func Reap(wait bool) (exits []Exit, err error) {
34	var (
35		ws  unix.WaitStatus
36		rus unix.Rusage
37	)
38	flag := unix.WNOHANG
39	if wait {
40		flag = 0
41	}
42	for {
43		pid, err := unix.Wait4(-1, &ws, flag, &rus)
44		if err != nil {
45			if err == unix.ECHILD {
46				return exits, nil
47			}
48			return exits, err
49		}
50		if pid <= 0 {
51			return exits, nil
52		}
53		exits = append(exits, Exit{
54			Pid:    pid,
55			Status: exitStatus(ws),
56		})
57	}
58}
59
60const exitSignalOffset = 128
61
62// exitStatus returns the correct exit status for a process based on if it
63// was signaled or exited cleanly
64func exitStatus(status unix.WaitStatus) int {
65	if status.Signaled() {
66		return exitSignalOffset + int(status.Signal())
67	}
68	return status.ExitStatus()
69}
70