Skip to content

Instantly share code, notes, and snippets.

@purpleidea
Forked from paulzhol/main.go
Created February 27, 2021 20:49
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save purpleidea/8494e37fd4a0d80a1ae7f01f5a00a3da to your computer and use it in GitHub Desktop.
Save purpleidea/8494e37fd4a0d80a1ae7f01f5a00a3da to your computer and use it in GitHub Desktop.
golang.org/x/sys/unix.Signalfd usage example (Linux)
// +build linux
package main
import (
"flag"
"log"
"os"
"runtime"
"time"
"unsafe"
"golang.org/x/sys/unix"
)
func testSignalFd() {
var sigmask unix.Sigset_t
fd, err := unix.Signalfd(-1, &sigmask, unix.SFD_CLOEXEC|unix.SFD_NONBLOCK)
if err != nil {
log.Fatalf("failed to create a signalfd: %v", err)
}
signalfd := os.NewFile(uintptr(fd), "signalfd")
defer signalfd.Close()
sigmask.Val[0] |= 1 << uint(unix.SIGUSR1-1)
_, err = unix.Signalfd(fd, &sigmask, 0)
if err != nil {
log.Fatalf("failed to update sigmask on signalfd: %v", err)
}
log.Printf("Sending SIGUSR1 in 2 sec")
t := time.AfterFunc(2 * time.Second, func() {
unix.Kill(unix.Getpid(), unix.SIGUSR1)
})
defer t.Stop()
log.Printf("Waiting for SIGUSR1 from signalfd")
buf := make([]byte, unsafe.Sizeof(unix.SignalfdSiginfo{}))
n, err := signalfd.Read(buf)
if err != nil {
log.Fatalf("failed reading siginfo from signalfd: %v", err)
}
info := *(*unix.SignalfdSiginfo)(unsafe.Pointer(&buf[0]))
log.Printf("n: %d, %+v", n, info)
}
func main() {
log.SetFlags(0)
maskExec := flag.Bool("mask_exec", false, "mask SIGUSR1 and exec self")
flag.Parse()
if *maskExec {
runtime.LockOSThread()
const SIG_SETMASK = 2
var sigmask unix.Sigset_t
sigmask.Val[0] |= 1 << (uint(unix.SIGUSR1) - 1)
unix.Syscall6(unix.SYS_RT_SIGPROCMASK, SIG_SETMASK, uintptr(unsafe.Pointer(&sigmask)), 0 /*_NSIG/8 */, 8, 0, 0)
var execPath [256]byte
n, err := unix.Readlink("/proc/self/exe", execPath[:])
if err != nil {
log.Fatalf("failed to read /proc/self/exe symlink: %v", err)
}
err = unix.Exec(string(execPath[:n]), []string{string(execPath[:n])}, os.Environ())
log.Fatal(err)
}
testSignalFd()
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment