func (m *mmapData) pushIntSlice(is []int) *C.int {
	ptr := unsafe.Pointer(&m.data[m.offset])
	nextptr := ptr
	for _, i := range is {
		*(*C.int)(nextptr) = C.int(i)
		m.offset += intSize
		nextptr = unsafe.Pointer(&m.data[m.offset])
	}
	m.panicIfOverAllocated()
	return (*C.int)(ptr)
}
Pushes an integer array into the mmapData buffer.
package goclone
import "C"
import (
	"syscall"
	"unsafe"
)
var (
	ptrSize = int(unsafe.Sizeof(unsafe.Pointer(nil)))
	intSize = int(unsafe.Sizeof(C.int(0)))
	gidSize = int(unsafe.Sizeof(C.gid_t(0)))
	pageSize = syscall.Getpagesize()
	stackSize = pageSize * 8
)
func rawDataSize(c *Cmd) int {
	dataSize := int(unsafe.Sizeof(C.goclone_cmd{}))
	dataSize += len(c.Path) + 1
	dataSize += (len(c.Args) + 1) * ptrSize
	for _, s := range c.Args {
		dataSize += len(s) + 1
	}
	dataSize += (len(c.Env) + 1) * ptrSize
	for _, s := range c.Env {
		dataSize += len(s) + 1
	}
	dataSize += len(c.Dir) + 1
	if c.SysProcAttr != nil {
		dataSize += len(c.SysProcAttr.Chroot) + 1
	} else {
		dataSize += 1
	}
	dataSize += (len(c.ExtraFiles) + 3) * intSize
	if c.SysProcAttr != nil && c.SysProcAttr.Credential != nil {
		dataSize += len(c.SysProcAttr.Credential.Groups) * gidSize
	}
	dataSize += (len(c.CgroupsTasksFiles) + 1) * ptrSize
	for _, s := range c.CgroupsTasksFiles {
		dataSize += len(s) + 1
	}
	dataSize += len(c.IPCNameSpace) + 1
	dataSize += len(c.MountNameSpace) + 1
	dataSize += len(c.NetworkNameSpace) + 1
	dataSize += len(c.PIDNameSpace) + 1
	dataSize += len(c.UserNameSpace) + 1
	dataSize += len(c.UTSNameSpace) + 1
	dataSize += len(c.Hostname) + 1
	return dataSize
}
type mmapData struct {
	data   []byte
	offset int
}
func mmapDataAlloc(size int) (*mmapData, error) {
	flags := syscall.MAP_SHARED | syscall.MAP_ANONYMOUS
	prot := syscall.PROT_WRITE | syscall.PROT_READ
	data, err := syscallMmap(-1, 0, size, prot, flags)
	if err != nil {
		return nil, err
	}
	return &mmapData{data: data}, nil
}
func (m *mmapData) panicIfOverAllocated() {
	if m.offset > len(m.data) {
		panic("data over allocation.")
	}
}
func (m *mmapData) free() error {
	return syscallMunmap(m.data)
}
func (m *mmapData) mprotect() error {
	m.offset = ((m.offset - 1) | (pageSize - 1)) + 1
	protected := m.data[m.offset : m.offset+pageSize]
	err := syscallMprotect(protected, syscall.PROT_NONE)
	m.offset += pageSize
	m.panicIfOverAllocated()
	return err
}
func (m *mmapData) stack() unsafe.Pointer {
	m.offset += stackSize
	return unsafe.Pointer(&m.data[m.offset-1])
}
func (m *mmapData) pushGocloneCmd() *C.goclone_cmd {
	ptr := (*C.goclone_cmd)(unsafe.Pointer(&m.data[m.offset]))
	m.offset += int(unsafe.Sizeof(C.goclone_cmd{}))
	m.panicIfOverAllocated()
	return ptr
}