unix: add PidfdSendSignal on Linux

This completes the pidfd_* family of syscalls and adds a test to verify that a
child process can be terminated using the new PidfdSendSignal function.

Change-Id: I71f6a1e26518f513731e20afef02030462e9a2c0
Reviewed-on: https://go-review.googlesource.com/c/sys/+/393794
Trust: Matt Layher <mdlayher@gmail.com>
Run-TryBot: Matt Layher <mdlayher@gmail.com>
TryBot-Result: Gopher Robot <gobot@golang.org>
Reviewed-by: Ian Lance Taylor <iant@golang.org>
This commit is contained in:
Matt Layher 2022-03-18 09:50:32 -04:00
Родитель 2edf467146
Коммит a9b59b0215
18 изменённых файлов: 162 добавлений и 0 удалений

Просмотреть файл

@ -934,6 +934,8 @@ const _C__NSIG = C._NSIG
type SignalfdSiginfo C.struct_signalfd_siginfo
type Siginfo C.siginfo_t
// Terminal handling
type Termios C.termios_t

Просмотреть файл

@ -2297,6 +2297,7 @@ type RemoteIovec struct {
//sys PidfdOpen(pid int, flags int) (fd int, err error) = SYS_PIDFD_OPEN
//sys PidfdGetfd(pidfd int, targetfd int, flags int) (fd int, err error) = SYS_PIDFD_GETFD
//sys PidfdSendSignal(pidfd int, sig Signal, info *Siginfo, flags int) (err error) = SYS_PIDFD_SEND_SIGNAL
//sys shmat(id int, addr uintptr, flag int) (ret uintptr, err error)
//sys shmctl(id int, cmd int, buf *SysvShmDesc) (result int, err error)

Просмотреть файл

@ -15,11 +15,13 @@ import (
"io/ioutil"
"net"
"os"
"os/exec"
"path/filepath"
"runtime"
"runtime/debug"
"strconv"
"strings"
"syscall"
"testing"
"time"
"unsafe"
@ -217,6 +219,46 @@ func firstIPv4(t *testing.T, ifi *net.Interface) (net.IP, bool) {
return nil, false
}
func TestPidfd(t *testing.T) {
// Start a child process which will sleep for 1 hour; longer than the 10
// minute default Go test timeout.
cmd := exec.Command("sleep", "1h")
if err := cmd.Start(); err != nil {
t.Fatalf("failed to exec sleep: %v", err)
}
fd, err := unix.PidfdOpen(cmd.Process.Pid, 0)
if err != nil {
// GOARCH arm/arm64 and GOOS android builders do not support pidfds.
if errors.Is(err, unix.ENOSYS) {
t.Skipf("skipping, pidfd_open is not implemented: %v", err)
}
t.Fatalf("failed to open child pidfd: %v", err)
}
defer unix.Close(fd)
const want = unix.SIGHUP
if err := unix.PidfdSendSignal(fd, want, nil, 0); err != nil {
t.Fatalf("failed to signal child process: %v", err)
}
// Now verify that the child process received the expected signal.
var eerr *exec.ExitError
if err := cmd.Wait(); !errors.As(err, &eerr) {
t.Fatalf("child process terminated but did not return an exit error: %v", err)
}
ws, ok := eerr.Sys().(syscall.WaitStatus)
if !ok {
t.Fatalf("expected syscall.WaitStatus value, but got: %#T", eerr.Sys())
}
if got := ws.Signal(); got != want {
t.Fatalf("unexpected child exit signal, got: %s, want: %s", got, want)
}
}
func TestPpoll(t *testing.T) {
if runtime.GOOS == "android" {
t.Skip("mkfifo syscall is not available on android, skipping test")

Просмотреть файл

@ -1992,6 +1992,16 @@ func PidfdGetfd(pidfd int, targetfd int, flags int) (fd int, err error) {
// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
func PidfdSendSignal(pidfd int, sig Signal, info *Siginfo, flags int) (err error) {
_, _, e1 := Syscall6(SYS_PIDFD_SEND_SIGNAL, uintptr(pidfd), uintptr(sig), uintptr(unsafe.Pointer(info)), uintptr(flags), 0, 0)
if e1 != 0 {
err = errnoErr(e1)
}
return
}
// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
func shmat(id int, addr uintptr, flag int) (ret uintptr, err error) {
r0, _, e1 := Syscall(SYS_SHMAT, uintptr(id), uintptr(addr), uintptr(flag))
ret = uintptr(r0)

Просмотреть файл

@ -250,6 +250,13 @@ type Sigset_t struct {
const _C__NSIG = 0x41
type Siginfo struct {
Signo int32
Errno int32
Code int32
_ [116]byte
}
type Termios struct {
Iflag uint32
Oflag uint32

Просмотреть файл

@ -265,6 +265,14 @@ type Sigset_t struct {
const _C__NSIG = 0x41
type Siginfo struct {
Signo int32
Errno int32
Code int32
_ int32
_ [112]byte
}
type Termios struct {
Iflag uint32
Oflag uint32

Просмотреть файл

@ -241,6 +241,13 @@ type Sigset_t struct {
const _C__NSIG = 0x41
type Siginfo struct {
Signo int32
Errno int32
Code int32
_ [116]byte
}
type Termios struct {
Iflag uint32
Oflag uint32

Просмотреть файл

@ -244,6 +244,14 @@ type Sigset_t struct {
const _C__NSIG = 0x41
type Siginfo struct {
Signo int32
Errno int32
Code int32
_ int32
_ [112]byte
}
type Termios struct {
Iflag uint32
Oflag uint32

Просмотреть файл

@ -246,6 +246,13 @@ type Sigset_t struct {
const _C__NSIG = 0x80
type Siginfo struct {
Signo int32
Code int32
Errno int32
_ [116]byte
}
type Termios struct {
Iflag uint32
Oflag uint32

Просмотреть файл

@ -247,6 +247,14 @@ type Sigset_t struct {
const _C__NSIG = 0x80
type Siginfo struct {
Signo int32
Code int32
Errno int32
_ int32
_ [112]byte
}
type Termios struct {
Iflag uint32
Oflag uint32

Просмотреть файл

@ -247,6 +247,14 @@ type Sigset_t struct {
const _C__NSIG = 0x80
type Siginfo struct {
Signo int32
Code int32
Errno int32
_ int32
_ [112]byte
}
type Termios struct {
Iflag uint32
Oflag uint32

Просмотреть файл

@ -246,6 +246,13 @@ type Sigset_t struct {
const _C__NSIG = 0x80
type Siginfo struct {
Signo int32
Code int32
Errno int32
_ [116]byte
}
type Termios struct {
Iflag uint32
Oflag uint32

Просмотреть файл

@ -253,6 +253,13 @@ type Sigset_t struct {
const _C__NSIG = 0x41
type Siginfo struct {
Signo int32
Errno int32
Code int32
_ [116]byte
}
type Termios struct {
Iflag uint32
Oflag uint32

Просмотреть файл

@ -254,6 +254,14 @@ type Sigset_t struct {
const _C__NSIG = 0x41
type Siginfo struct {
Signo int32
Errno int32
Code int32
_ int32
_ [112]byte
}
type Termios struct {
Iflag uint32
Oflag uint32

Просмотреть файл

@ -254,6 +254,14 @@ type Sigset_t struct {
const _C__NSIG = 0x41
type Siginfo struct {
Signo int32
Errno int32
Code int32
_ int32
_ [112]byte
}
type Termios struct {
Iflag uint32
Oflag uint32

Просмотреть файл

@ -272,6 +272,14 @@ type Sigset_t struct {
const _C__NSIG = 0x41
type Siginfo struct {
Signo int32
Errno int32
Code int32
_ int32
_ [112]byte
}
type Termios struct {
Iflag uint32
Oflag uint32

Просмотреть файл

@ -267,6 +267,14 @@ type Sigset_t struct {
const _C__NSIG = 0x41
type Siginfo struct {
Signo int32
Errno int32
Code int32
_ int32
_ [112]byte
}
type Termios struct {
Iflag uint32
Oflag uint32

Просмотреть файл

@ -249,6 +249,14 @@ type Sigset_t struct {
const _C__NSIG = 0x41
type Siginfo struct {
Signo int32
Errno int32
Code int32
_ int32
_ [112]byte
}
type Termios struct {
Iflag uint32
Oflag uint32