1// Copyright 2023 The Go Authors. All rights reserved.
2// Use of this source code is governed by a BSD-style
3// license that can be found in the LICENSE file.
4
5package unix
6
7import (
8	"syscall"
9)
10
11const is64bit = ^uint(0) >> 63 // 0 for 32-bit hosts, 1 for 64-bit ones.
12
13// SiginfoChild is a struct filled in by Linux waitid syscall.
14// In C, siginfo_t contains a union with multiple members;
15// this struct corresponds to one used when Signo is SIGCHLD.
16//
17// NOTE fields are exported to be used by TestSiginfoChildLayout.
18type SiginfoChild struct {
19	Signo       int32
20	siErrnoCode                // Two int32 fields, swapped on MIPS.
21	_           [is64bit]int32 // Extra padding for 64-bit hosts only.
22
23	// End of common part. Beginning of signal-specific part.
24
25	Pid    int32
26	Uid    uint32
27	Status int32
28
29	// Pad to 128 bytes.
30	_ [128 - (6+is64bit)*4]byte
31}
32
33const (
34	// Possible values for SiginfoChild.Code field.
35	_CLD_EXITED    int32 = 1
36	_CLD_KILLED          = 2
37	_CLD_DUMPED          = 3
38	_CLD_TRAPPED         = 4
39	_CLD_STOPPED         = 5
40	_CLD_CONTINUED       = 6
41
42	// These are the same as in syscall/syscall_linux.go.
43	core      = 0x80
44	stopped   = 0x7f
45	continued = 0xffff
46)
47
48// WaitStatus converts SiginfoChild, as filled in by the waitid syscall,
49// to syscall.WaitStatus.
50func (s *SiginfoChild) WaitStatus() (ws syscall.WaitStatus) {
51	switch s.Code {
52	case _CLD_EXITED:
53		ws = syscall.WaitStatus(s.Status << 8)
54	case _CLD_DUMPED:
55		ws = syscall.WaitStatus(s.Status) | core
56	case _CLD_KILLED:
57		ws = syscall.WaitStatus(s.Status)
58	case _CLD_TRAPPED, _CLD_STOPPED:
59		ws = syscall.WaitStatus(s.Status<<8) | stopped
60	case _CLD_CONTINUED:
61		ws = continued
62	}
63	return
64}
65