Files

110 lines
2.3 KiB
C

#include "shm.h"
#include <sys/mman.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <unistd.h>
#include <stdlib.h>
#include <string.h>
#include <errno.h>
struct crt_shm {
int fd;
void* ptr;
size_t size;
char name[256];
};
crt_shm_t* crt_shm_create(const char* name, size_t size) {
crt_shm_t* shm = calloc(1, sizeof(crt_shm_t));
if (!shm) return NULL;
strncpy(shm->name, name, sizeof(shm->name) - 1);
shm->size = size;
shm->fd = shm_open(name, O_CREAT | O_RDWR, 0666);
if (shm->fd < 0) {
free(shm);
return NULL;
}
if (ftruncate(shm->fd, size) < 0) {
close(shm->fd);
shm_unlink(name);
free(shm);
return NULL;
}
shm->ptr = mmap(NULL, size, PROT_READ | PROT_WRITE, MAP_SHARED, shm->fd, 0);
if (shm->ptr == MAP_FAILED) {
close(shm->fd);
shm_unlink(name);
free(shm);
return NULL;
}
memset(shm->ptr, 0, size);
return shm;
}
crt_shm_t* crt_shm_open(const char* name) {
crt_shm_t* shm = calloc(1, sizeof(crt_shm_t));
if (!shm) return NULL;
strncpy(shm->name, name, sizeof(shm->name) - 1);
shm->fd = shm_open(name, O_RDWR, 0666);
if (shm->fd < 0) {
free(shm);
return NULL;
}
struct stat st;
if (fstat(shm->fd, &st) < 0) {
close(shm->fd);
free(shm);
return NULL;
}
shm->size = st.st_size;
shm->ptr = mmap(NULL, shm->size, PROT_READ | PROT_WRITE, MAP_SHARED, shm->fd, 0);
if (shm->ptr == MAP_FAILED) {
close(shm->fd);
free(shm);
return NULL;
}
return shm;
}
void crt_shm_close(crt_shm_t* shm) {
if (!shm) return;
if (shm->ptr && shm->ptr != MAP_FAILED) {
munmap(shm->ptr, shm->size);
}
if (shm->fd >= 0) {
close(shm->fd);
}
free(shm);
}
void* crt_shm_ptr(crt_shm_t* shm) {
return shm ? shm->ptr : NULL;
}
size_t crt_shm_size(crt_shm_t* shm) {
return shm ? shm->size : 0;
}
int crt_shm_resize(crt_shm_t* shm, size_t new_size) {
if (!shm || !shm->ptr) return -1;
if (munmap(shm->ptr, shm->size) < 0) return -1;
if (ftruncate(shm->fd, new_size) < 0) return -1;
shm->ptr = mmap(NULL, new_size, PROT_READ | PROT_WRITE, MAP_SHARED, shm->fd, 0);
if (shm->ptr == MAP_FAILED) return -1;
shm->size = new_size;
return 0;
}