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