110 lines
2.3 KiB
C
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;
|
||
|
|
}
|