github.com/angenalZZZ/gofunc@v0.0.0-20210507121333-48ff1be3917b/data/shm/shmi_linux.go (about) 1 // +build linux,cgo 2 3 package shm 4 5 /* 6 #cgo LDFLAGS: -lrt 7 8 #include <sys/mman.h> 9 #include <sys/types.h> 10 #include <sys/stat.h> 11 #include <fcntl.h> 12 #include <stdio.h> 13 #include <unistd.h> 14 15 int _create(const char* name, int size, int flag) { 16 mode_t mode = S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP; 17 18 int fd = shm_open(name, flag, mode); 19 if (fd < 0) { 20 return -1; 21 } 22 23 if (ftruncate(fd, size) != 0) { 24 close(fd); 25 return -2; 26 } 27 return fd; 28 } 29 30 int Create(const char* name, int size) { 31 int flag = O_RDWR | O_CREAT; 32 return _create(name, size, flag); 33 } 34 35 int Open(const char* name, int size) { 36 int flag = O_RDWR; 37 return _create(name, size, flag); 38 } 39 40 void* Map(int fd, int size) { 41 void* p = mmap( 42 NULL, size, 43 PROT_READ | PROT_WRITE, 44 MAP_SHARED, fd, 0); 45 if (p == MAP_FAILED) { 46 return NULL; 47 } 48 return p; 49 } 50 51 void Close(int fd, void* p, int size) { 52 if (p != NULL) { 53 munmap(p, size); 54 } 55 if (fd != 0) { 56 close(fd); 57 } 58 } 59 60 void Delete(const char* name) { 61 shm_unlink(name); 62 } 63 */ 64 import "C" 65 66 import ( 67 "fmt" 68 "io" 69 "unsafe" 70 ) 71 72 type sharedMemory struct { 73 name string 74 fd C.int 75 v unsafe.Pointer 76 size int32 77 parent bool 78 } 79 80 // create shared memory. return sharedMemory object. 81 func create(name string, size int32) (*sharedMemory, error) { 82 name = "/" + name 83 84 fd := C.Create(C.CString(name), C.int(size)) 85 if fd < 0 { 86 return nil, fmt.Errorf("create") 87 } 88 89 v := C.Map(fd, C.int(size)) 90 if v == nil { 91 C.Close(fd, nil, C.int(size)) 92 C.Delete(C.CString(name)) 93 } 94 95 return &sharedMemory{name, fd, v, size, true}, nil 96 } 97 98 // open shared memory. return sharedMemory object. 99 func open(name string, size int32) (*sharedMemory, error) { 100 name = "/" + name 101 102 fd := C.Open(C.CString(name), C.int(size)) 103 if fd < 0 { 104 return nil, fmt.Errorf("open") 105 } 106 107 v := C.Map(fd, C.int(size)) 108 if v == nil { 109 C.Close(fd, nil, C.int(size)) 110 C.Delete(C.CString(name)) 111 } 112 113 return &sharedMemory{name, fd, v, size, false}, nil 114 } 115 116 func (o *sharedMemory) close() error { 117 if o.v != nil { 118 C.Close(o.fd, o.v, C.int(o.size)) 119 o.v = nil 120 } 121 if o.parent { 122 C.Delete(C.CString(o.name)) 123 } 124 return nil 125 } 126 127 // read shared memory. return read size. 128 func (o *sharedMemory) readAt(p []byte, off int64) (n int, err error) { 129 if off >= int64(o.size) { 130 return 0, io.EOF 131 } 132 if max := int64(o.size) - off; int64(len(p)) > max { 133 p = p[:max] 134 } 135 return f.BytesFromPtr(uintptr(o.v), p, off, o.size), nil 136 } 137 138 // write shared memory. return write size. 139 func (o *sharedMemory) writeAt(p []byte, off int64) (n int, err error) { 140 if off >= int64(o.size) { 141 return 0, io.EOF 142 } 143 if max := int64(o.size) - off; int64(len(p)) > max { 144 p = p[:max] 145 } 146 return f.BytesToPtr(p, uintptr(o.v), off, o.size), nil 147 }