diff options
Diffstat (limited to 'source/kit/shared_memory.posix.c')
-rw-r--r-- | source/kit/shared_memory.posix.c | 105 |
1 files changed, 30 insertions, 75 deletions
diff --git a/source/kit/shared_memory.posix.c b/source/kit/shared_memory.posix.c index d2c4973..1695f14 100644 --- a/source/kit/shared_memory.posix.c +++ b/source/kit/shared_memory.posix.c @@ -7,119 +7,77 @@ # include <sys/stat.h> # include <fcntl.h> # include <unistd.h> -# include <limits.h> # include <assert.h> -typedef struct { - i8 owned; - i32 fd; - char name[NAME_MAX + 1]; -} kit_shared_memory_internal_t; - -kit_shared_memory_t kit_shared_memory_create(kit_str_t name, - i64 size) { - kit_shared_memory_t mem; - kit_shared_memory_internal_t *internal = - (kit_shared_memory_internal_t *) &mem._state; +kit_shared_memory_t kit_shared_memory_open(kit_str_t name, i64 size, + i32 mode) { + kit_shared_memory_t mem; memset(&mem, 0, sizeof mem); + assert(size > 0); + assert(name.size > 0); assert(name.size + 1 <= NAME_MAX); - if (name.size + 1 > NAME_MAX) { - mem.status = KIT_ERROR_NAME_TOO_LONG; - return mem; - } - - for (i64 i = 0; i < name.size; i++) - if (name.values[i] == '/') { - mem.status = KIT_ERROR_INVALID_NAME; - return mem; - } - - internal->name[0] = '/'; - memcpy(internal->name + 1, name.values, name.size); - internal->name[1 + name.size] = '\0'; + assert(name.values != NULL); - i32 fd = shm_open(internal->name, O_RDWR | O_CREAT | O_EXCL, 0660); - - assert(fd != -1); - if (fd == -1) { - mem.status = KIT_ERROR_SHM_OPEN_FAILED; + if (size <= 0) { + mem.status = KIT_ERROR_INVALID_SIZE; return mem; } - if (ftruncate(fd, size) == -1) { - shm_unlink(internal->name); - assert(0); - mem.status = KIT_ERROR_FTRUNCATE_FAILED; + if (name.size <= 0) { + mem.status = KIT_ERROR_INVALID_NAME; return mem; } - void *p = mmap(NULL, size, PROT_READ | PROT_WRITE, MAP_SHARED, fd, - 0); - - if (p == MAP_FAILED) { - shm_unlink(internal->name); - assert(0); - mem.status = KIT_ERROR_MMAP_FAILED; - return mem; - } - - internal->owned = 1; - internal->fd = fd; - - mem.status = KIT_OK; - mem.size = size; - mem.bytes = (u8 *) p; - return mem; -} - -kit_shared_memory_t kit_shared_memory_open(kit_str_t name, i64 size) { - kit_shared_memory_t mem; - kit_shared_memory_internal_t *internal = - (kit_shared_memory_internal_t *) &mem._state; - - memset(&mem, 0, sizeof mem); - - assert(name.size + 1 <= NAME_MAX); if (name.size + 1 > NAME_MAX) { mem.status = KIT_ERROR_NAME_TOO_LONG; return mem; } for (i64 i = 0; i < name.size; i++) - if (name.values[i] == '/') { + if (name.values[i] == '/' || name.values[i] == '\\') { mem.status = KIT_ERROR_INVALID_NAME; return mem; } - internal->name[0] = '/'; - memcpy(internal->name + 1, name.values, name.size); - internal->name[1 + name.size] = '\0'; + mem._name[0] = '/'; + memcpy(mem._name + 1, name.values, name.size); + mem._name[1 + name.size] = '\0'; - i32 fd = shm_open(internal->name, O_RDWR, 0660); + i32 fd = shm_open(mem._name, + mode == KIT_SHARED_MEMORY_CREATE + ? O_RDWR | O_CREAT | O_EXCL + : O_RDWR, + mode == KIT_SHARED_MEMORY_CREATE ? 0660 : 0); - assert(fd != -1); if (fd == -1) { mem.status = KIT_ERROR_SHM_OPEN_FAILED; return mem; } + if (mode == KIT_SHARED_MEMORY_CREATE && ftruncate(fd, size) == -1) { + shm_unlink(mem._name); + assert(0); + mem.status = KIT_ERROR_FTRUNCATE_FAILED; + return mem; + } + void *p = mmap(NULL, size, PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0); if (p == MAP_FAILED) { + shm_unlink(mem._name); assert(0); mem.status = KIT_ERROR_MMAP_FAILED; return mem; } - internal->owned = 0; - internal->fd = fd; - mem.status = KIT_OK; mem.size = size; mem.bytes = (u8 *) p; + mem._owned = (mode == KIT_SHARED_MEMORY_CREATE); + mem._fd = fd; return mem; } @@ -129,14 +87,11 @@ kit_status_t kit_shared_memory_close(kit_shared_memory_t *mem) { if (mem == NULL) return KIT_ERROR_INVALID_ARGUMENT; - kit_shared_memory_internal_t *internal = - (kit_shared_memory_internal_t *) &mem->_state; - kit_status_t status = KIT_OK; if (munmap(mem->bytes, mem->size) != 0) status |= KIT_ERROR_MUNMAP_FAILED; - if (internal->owned && shm_unlink(internal->name) != 0) + if (mem->_owned && shm_unlink(mem->_name) != 0) status |= KIT_ERROR_UNLINK_FAILED; return status; |