| git.druid.rocks | index | militantprogrammer | astral_canvas | src/ | platform/ | shm.c |
src/platform/shm.c
#include "platform/shm.h"
#include <errno.h>
#include <fcntl.h>
#include <stdio.h>
#include <string.h>
#include <sys/mman.h>
#include <unistd.h>
int shm_alloc(size_t size, void **outMapped)
{
if (size == 0 || !outMapped)
return -1;
int fileDescriptor = -1;
#ifdef __linux__
fileDescriptor = memfd_create("terminal-shm", MFD_CLOEXEC);
#endif
if (fileDescriptor < 0) {
char name[64];
snprintf(name, sizeof(name), "/terminal-shm-%d", (int)getpid());
fileDescriptor = shm_open(name, O_RDWR | O_CREAT | O_EXCL, 0600);
if (fileDescriptor >= 0)
shm_unlink(name);
}
if (fileDescriptor < 0)
return -1;
if (ftruncate(fileDescriptor, (off_t)size) < 0) {
close(fileDescriptor);
return -1;
}
void *mapped = mmap(NULL, size, PROT_READ | PROT_WRITE, MAP_SHARED, fileDescriptor, 0);
if (mapped == MAP_FAILED) {
close(fileDescriptor);
return -1;
}
memset(mapped, 0, size);
*outMapped = mapped;
return fileDescriptor;
}
void shm_free(int fileDescriptor, void *mapped, size_t size)
{
if (mapped && mapped != MAP_FAILED)
munmap(mapped, size);
if (fileDescriptor >= 0)
close(fileDescriptor);
}