Skip to content

Instantly share code, notes, and snippets.

@smira
Created September 2, 2019 20:22
Show Gist options
  • Save smira/9dbb8e1f7877510014bcc6217af9e68a to your computer and use it in GitHub Desktop.
Save smira/9dbb8e1f7877510014bcc6217af9e68a to your computer and use it in GitHub Desktop.
waitid implementation for Go linux/amd64
package linux
import (
"fmt"
"syscall"
"unsafe"
)
// Values for waitid() idtype parameter
//
//nolint: golint
const (
P_ALL = 0
P_PID = 1
P_PGID = 2
)
// SiginfoWaitid provides version of siginfo_t struct for waitid() syscall
type SiginfoWaitid struct {
Signo int32
Errno int32
Code int32
_ int32 // padding
Pid uint32
UID uint32
Status int32
_ [100]byte // struct should be 128 bytes
}
// Waitid implements Linux-specific syscall waitid()
func Waitid(idtype int, id int, infop *SiginfoWaitid, options int) error {
_, _, e := syscall.Syscall6(syscall.SYS_WAITID, uintptr(idtype), uintptr(id), uintptr(unsafe.Pointer(infop)), uintptr(options), 0, 0)
if e == 0 {
return nil
}
return e
}
func init() {
if unsafe.Sizeof(SiginfoWaitid{}) != 128 {
panic(fmt.Sprintf("SiginfoWaitid structure should be 128 bytes, but it is %d bytes", unsafe.Sizeof(SiginfoWaitid{})))
}
}
package linux_test
import (
"os/exec"
"syscall"
"testing"
"github.com/stretchr/testify/suite"
"./linux"
)
type WaitidSuite struct {
suite.Suite
}
func (suite *WaitidSuite) TestWaitidNoProcesses() {
var info linux.SiginfoWaitid
err := linux.Waitid(linux.P_ALL, 0, &info, syscall.WEXITED|syscall.WNOHANG)
suite.Assert().Equal(err, syscall.ECHILD)
}
func (suite *WaitidSuite) TestWaitidSingleProcess() {
var info linux.SiginfoWaitid
cmd := exec.Command("/bin/sh", "-c", ":")
suite.Assert().NoError(cmd.Start())
err := linux.Waitid(linux.P_ALL, 0, &info, syscall.WEXITED|syscall.WNOWAIT)
suite.Assert().Nil(err)
// zombie status retrieved, but zombie is not reaped
suite.Assert().EqualValues(info.Pid, cmd.Process.Pid)
// cmd.Wait should still get zombie status
suite.Assert().Nil(cmd.Wait())
}
func TestWaitidSuite(t *testing.T) {
suite.Run(t, new(WaitidSuite))
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment