mirror of
https://github.com/rwinkhart/sys.git
synced 2026-08-28 04:46:44 -04:00
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:
@@ -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")
|
||||
|
||||
Reference in New Issue
Block a user