Skip to content

Instantly share code, notes, and snippets.

@LeonB
Created April 29, 2015 21:06
Show Gist options
  • Save LeonB/f224c005f4b524ebb9cc to your computer and use it in GitHub Desktop.
Save LeonB/f224c005f4b524ebb9cc to your computer and use it in GitHub Desktop.
package main
import (
"bytes"
"fmt"
"log"
"net"
"os"
"os/exec"
"unsafe"
mmap "github.com/edsrzf/mmap-go"
utils "github.com/leonb/irsdk-go/utils"
"golang.org/x/sys/unix"
)
const (
MEMMAPFILENAME = "Local\\IRSDKMemMapFileName"
)
func get_wine_shm(shmname string) (uintptr, error) {
domain := unix.AF_UNIX
sotype := unix.SOCK_DGRAM
proto := 0
fds, err := unix.Socketpair(domain, sotype, proto)
if err != nil {
return 0, err
}
defer unix.Close(fds[0])
defer unix.Close(fds[1])
mode := "r"
cmd := exec.Command("/opt/iracing/bin/wine", "--bottle", "default", "shmwrapper1.exe", shmname, mode, "shmwrapper2.bin")
writeFile := os.NewFile(uintptr(fds[0]), "child-writes")
readFile := os.NewFile(uintptr(fds[1]), "parent-reads")
stderr := &bytes.Buffer{}
defer writeFile.Close()
defer readFile.Close()
// Attach buffer to command
cmd.Stdout = writeFile
cmd.Stderr = stderr
err = cmd.Run()
if err != nil {
return 0, fmt.Errorf("cmd.Run(): %v", err)
}
c, err := net.FileConn(readFile)
if err != nil {
fmt.Errorf("FileConn: %v", err)
}
defer c.Close()
uc, ok := c.(*net.UnixConn)
if !ok {
fmt.Errorf("unexpected FileConn type; expected UnixConn, got %T", c)
}
buf := make([]byte, 32) // expect 1 byte
oob := make([]byte, 32) // expect 24 bytes
// closeUnix := time.AfterFunc(5*time.Second, func() {
// return 0, fmt.Errorf("timeout reading from unix socket")
// uc.Close()
// })
_, oobn, _, _, err := uc.ReadMsgUnix(buf, oob)
// closeUnix.Stop()
scms, err := unix.ParseSocketControlMessage(oob[:oobn])
if err != nil {
return 0, fmt.Errorf("ParseSocketControlMessage: %v", err)
}
if len(scms) != 1 {
return 0, fmt.Errorf("expected 1 SocketControlMessage; got scms = %#v", scms)
}
scm := scms[0]
gotFds, err := unix.ParseUnixRights(&scm)
if err != nil {
return 0, fmt.Errorf("unix.ParseUnixRights: %v", err)
}
if len(gotFds) != 1 {
return 0, fmt.Errorf("wanted 1 fd; got %#v", gotFds)
}
// Block until cmd is finished
cmd.Wait()
return uintptr(gotFds[0]), nil
}
func main() {
// Get wine file descriptor
shmfd, err := get_wine_shm(MEMMAPFILENAME)
if err != nil {
log.Fatal(err)
}
fmt.Printf("shmfd: %+v\n", shmfd)
// Turn file descriptor into os.File
file := os.NewFile(shmfd, MEMMAPFILENAME)
fmt.Printf("file: %+v\n", file)
// Mmap file
mmap, err := mmap.Map(file, mmap.RDONLY, 0)
if err != nil {
log.Fatal(err)
}
sharedMemPtr := unsafe.Pointer(&mmap)
header := (*utils.Header)(sharedMemPtr)
fmt.Printf("%+v", header)
fmt.Printf(string(mmap[:]))
// fmt.Printf("%+v\n", mmap)
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment