func serialize(num int64) []byte {
	b := make([]byte, 8)
	base := uintptr(unsafe.Pointer(&num))
	for i := 0; i < 8; i++ {
		b[i] = *(*byte)(unsafe.Pointer(base + uintptr(i)))
	}
	return b
}
/*
real c-style pointer casting
package sysvipc
import "C"
import (
	"time"
	"unsafe"
)
type MessageQueue int64
func GetMsgQueue(key int64, flags *MQFlags) (MessageQueue, error) {
	rc, err := C.msgget(C.key_t(key), C.int(flags.flags()))
	if rc == -1 {
		return -1, err
	}
	return MessageQueue(rc), nil
}
func (mq MessageQueue) Send(mtyp int64, body []byte, flags *MQSendFlags) error {
	b := make([]byte, len(body)+8)
	copy(b[:8], serialize(mtyp))
	copy(b[8:], body)
	rc, err := C.msgsnd(
		C.int(mq),
		unsafe.Pointer(&b[0]),
		C.size_t(len(body)),
		C.int(flags.flags()),
	)
	if rc == -1 {
		return err
	}
	return nil
}
func (mq MessageQueue) Receive(maxlen uint, msgtyp int64, flags *MQRecvFlags) ([]byte, int64, error) {
	b := make([]byte, maxlen+8)
	rc, err := C.msgrcv(
		C.int(mq),
		unsafe.Pointer(&b[0]),
		C.size_t(maxlen),
		C.long(msgtyp),
		C.int(flags.flags()),
	)
	if rc == -1 {
		return nil, 0, err
	}
	mtyp := deserialize(b[:8])
	return b[8 : rc+8], mtyp, nil
}
func (mq MessageQueue) Stat() (*MQInfo, error) {
	mqds := C.struct_msqid_ds{}
	rc, err := C.msgctl(C.int(mq), C.IPC_STAT, &mqds)
	if rc == -1 {
		return nil, err
	}
	mqinf := MQInfo{
		Perms: IpcPerms{
			OwnerUID:   int(mqds.msg_perm.uid),
			OwnerGID:   int(mqds.msg_perm.gid),
			CreatorUID: int(mqds.msg_perm.cuid),
			CreatorGID: int(mqds.msg_perm.cgid),
			Mode:       uint16(mqds.msg_perm.mode),
		},
		LastSend:   time.Unix(int64(mqds.msg_stime), 0),
		LastRcv:    time.Unix(int64(mqds.msg_rtime), 0),
		LastChange: time.Unix(int64(mqds.msg_ctime), 0),
		MsgCount:   uint(mqds.msg_qnum),
		MaxBytes:   uint(mqds.msg_qbytes),
		LastSender: int(mqds.msg_lspid),
		LastRcver:  int(mqds.msg_lrpid),
	}
	return &mqinf, nil
}
func (mq MessageQueue) Set(mqi *MQInfo) error {
	mqds := &C.struct_msqid_ds{
		msg_perm: C.struct_ipc_perm{
			uid:  C.__uid_t(mqi.Perms.OwnerUID),
			gid:  C.__gid_t(mqi.Perms.OwnerGID),
			mode: C.ushort(mqi.Perms.Mode & 0x1FF),
		},
		msg_qbytes: C.msglen_t(mqi.MaxBytes),
	}
	rc, err := C.msgctl(C.int(mq), C.IPC_SET, mqds)
	if rc == -1 {
		return err
	}
	return nil
}
func (mq MessageQueue) Remove() error {
	rc, err := C.msgctl(C.int(mq), C.IPC_RMID, nil)
	if rc == -1 {
		return err
	}
	return nil
}
type MQInfo struct {
	Perms      IpcPerms
	LastSend   time.Time
	LastRcv    time.Time
	LastChange time.Time
	MsgCount uint
	MaxBytes uint
	LastSender int
	LastRcver  int
}
type MQFlags struct {
	Create bool
	Exclusive bool
	Perms int
}
func (mf *MQFlags) flags() int64 {
	if mf == nil {
		return 0
	}
	var f int64 = int64(mf.Perms) & 0777
	if mf.Create {
		f |= int64(C.IPC_CREAT)
	}
	if mf.Exclusive {
		f |= int64(C.IPC_EXCL)
	}
	return f
}
type MQSendFlags struct {
	DontWait bool
}
func (mf *MQSendFlags) flags() int64 {
	if mf == nil {
		return 0
	}
	var f int64
	if mf.DontWait {
		f |= int64(C.IPC_NOWAIT)
	}
	return f
}
type MQRecvFlags struct {
	DontWait bool
	Truncate bool
}
func (mf *MQRecvFlags) flags() int64 {
	if mf == nil {
		return 0
	}
	var f int64
	if mf.DontWait {
		f |= int64(C.IPC_NOWAIT)
	}
	if mf.Truncate {
		f |= int64(C.MSG_NOERROR)
	}
	return f
}