suggestion picker: a persistent layer to complement virtual keyboards like wvkbd
Diffstat (limited to 'shm_open.c')
| -rw-r--r-- | shm_open.c | 55 |
1 files changed, 55 insertions, 0 deletions
diff --git a/shm_open.c b/shm_open.c new file mode 100644 index 0000000..05cb571 --- /dev/null +++ b/shm_open.c @@ -0,0 +1,55 @@ +#define _POSIX_C_SOURCE 200112L +#include <errno.h> +#include <fcntl.h> +#include <sys/mman.h> +#include <time.h> +#include <unistd.h> + +static void +randname(char *buf) +{ + struct timespec ts; + long r; + clock_gettime(CLOCK_REALTIME, &ts); + r = ts.tv_nsec; + for (int i = 0; i < 6; ++i) { + buf[i] = 'A'+(r&15)+(r&16)*2; + r >>= 5; + } +} + +static int +create_shm_file(void) +{ + int retries = 100; + int fd; + do { + char name[] = "/wl_shm-XXXXXX"; + randname(name + sizeof(name) - 7); + --retries; + fd = shm_open(name, O_RDWR | O_CREAT | O_EXCL, 0600); + if (fd >= 0) { + shm_unlink(name); + return fd; + } + } while (retries > 0 && errno == EEXIST); + return -1; +} + +int +allocate_shm_file(size_t size) +{ + int fd = create_shm_file(); + int ret; + if (fd < 0) + return -1; + do { + ret = ftruncate(fd, size); + } while (ret < 0 && errno == EINTR); + if (ret < 0) { + close(fd); + return -1; + } + return fd; +} + |