gopkg.in/ro-ag/posix.v1@v1.0.6/example/host.go (about) 1 package main 2 3 import ( 4 "gopkg.in/ro-ag/posix.v1" 5 "log" 6 "os" 7 "os/exec" 8 "strings" 9 "syscall" 10 "unsafe" 11 ) 12 13 const ApproximatedAddress uintptr = 0x20000000000 14 15 type Head struct { 16 Addr unsafe.Pointer 17 MemSize uintptr 18 TextSize uintptr 19 TextPtr unsafe.Pointer 20 } 21 22 type Holder struct { 23 *Head 24 Data []byte 25 } 26 27 const exeName = "./child_exe" 28 29 func main() { 30 31 fd, err := posix.MemfdCreate("test-mem", posix.MFD_ALLOW_SEALING) 32 CheckErr(err) 33 34 MemSize := posix.Getpagesize() * 4 35 err = posix.Ftruncate(fd, MemSize) 36 CheckErr(err) 37 38 buf, addr, err := posix.Mmap(unsafe.Pointer(ApproximatedAddress), MemSize, posix.PROT_WRITE, posix.MAP_SHARED, fd, 0) 39 CheckErr(err) 40 41 log.Printf("Got Address %p\n", unsafe.Pointer(addr)) 42 43 text := "This works as Mmap in C" 44 offset := unsafe.Sizeof(Head{}) 45 46 hdr := (*Head)(unsafe.Pointer(&buf[0])) 47 hdr.Addr = unsafe.Pointer(addr) 48 hdr.MemSize = uintptr(MemSize) 49 hdr.TextSize = uintptr(len(text)) 50 hdr.TextPtr = unsafe.Pointer(&buf[offset]) 51 52 holder := &Holder{ 53 Head: hdr, 54 Data: unsafe.Slice(&buf[offset], uintptr(len(text))), 55 } 56 57 log.Println("bytes written:", copy(holder.Data, text)) 58 log.Println("buf: ", buf[:offset+holder.TextSize]) 59 log.Printf("%T = %+v", holder.Head, holder.Head) 60 61 /* Execute External Program which needs a pointer */ 62 stdout, stderr := RunChild(exeName, uintptr(fd)) 63 log.Printf("stderr: %s", stderr) 64 log.Printf("stdout: \n%s", stdout) 65 66 CheckErr(posix.Munmap(buf)) // unmap memory 67 CheckErr(posix.Close(fd)) // close anonymous file 68 69 log.Println("- example done -") 70 } 71 72 func RunChild(name string, fd uintptr) (out, err string) { 73 file := os.NewFile(fd, "anonymous-fd") 74 cmd := exec.Command(name) 75 cmd.ExtraFiles = []*os.File{file} 76 var stderr, stdout strings.Builder 77 cmd.Stderr = &stderr 78 cmd.Stdout = &stdout 79 if err := cmd.Run(); err != nil { 80 log.Fatal(err) 81 } 82 return stdout.String(), stderr.String() 83 } 84 85 func init() { 86 log.Println("compile C program") 87 compile := exec.Command("gcc", "-o", exeName, "_child.c") 88 compile.Env = append(os.Environ()) 89 compile.Stderr = os.Stderr 90 compile.Stdout = os.Stdout 91 CheckErr(compile.Run()) 92 log.Println("compile success") 93 } 94 95 func CheckErr(err error) { 96 if err != nil { 97 no := err.(syscall.Errno) 98 log.Fatalf("%s(%d): %v, msg: %s\nhelp: %s", posix.ErrnoName(no), no, err, posix.ErrnoString(no), posix.ErrnoHelp(no)) 99 } 100 }