aboutsummaryrefslogtreecommitdiffstats
path: root/client/pool-buffer.c
diff options
context:
space:
mode:
Diffstat (limited to 'client/pool-buffer.c')
-rw-r--r--client/pool-buffer.c67
1 files changed, 31 insertions, 36 deletions
diff --git a/client/pool-buffer.c b/client/pool-buffer.c
index ea31edd3..c47c40eb 100644
--- a/client/pool-buffer.c
+++ b/client/pool-buffer.c
@@ -1,50 +1,42 @@
1#define _POSIX_C_SOURCE 200809
2#include <assert.h> 1#include <assert.h>
3#include <cairo.h> 2#include <cairo.h>
3#include <errno.h>
4#include <fcntl.h> 4#include <fcntl.h>
5#include <pango/pangocairo.h> 5#include <pango/pangocairo.h>
6#include <stdio.h> 6#include <stdio.h>
7#include <stdlib.h> 7#include <stdlib.h>
8#include <string.h> 8#include <string.h>
9#include <sys/mman.h> 9#include <sys/mman.h>
10#include <time.h>
10#include <unistd.h> 11#include <unistd.h>
11#include <wayland-client.h> 12#include <wayland-client.h>
12#include "config.h" 13#include "config.h"
13#include "pool-buffer.h" 14#include "pool-buffer.h"
14#include "util.h" 15#include "util.h"
15 16
16static int create_pool_file(size_t size, char **name) { 17static int anonymous_shm_open(void) {
17 static const char template[] = "sway-client-XXXXXX"; 18 int retries = 100;
18 const char *path = getenv("XDG_RUNTIME_DIR"); 19
19 if (path == NULL) { 20 do {
20 fprintf(stderr, "XDG_RUNTIME_DIR is not set\n"); 21 // try a probably-unique name
21 return -1; 22 struct timespec ts;
22 } 23 clock_gettime(CLOCK_MONOTONIC, &ts);
23 24 pid_t pid = getpid();
24 size_t name_size = strlen(template) + 1 + strlen(path) + 1; 25 char name[50];
25 *name = malloc(name_size); 26 snprintf(name, sizeof(name), "/sway-%x-%x",
26 if (*name == NULL) { 27 (unsigned int)pid, (unsigned int)ts.tv_nsec);
27 fprintf(stderr, "allocation failed\n"); 28
28 return -1; 29 // shm_open guarantees that O_CLOEXEC is set
29 } 30 int fd = shm_open(name, O_RDWR | O_CREAT | O_EXCL, 0600);
30 snprintf(*name, name_size, "%s/%s", path, template); 31 if (fd >= 0) {
31 32 shm_unlink(name);
32 int fd = mkstemp(*name); 33 return fd;
33 if (fd < 0) { 34 }
34 return -1;
35 }
36
37 if (!sway_set_cloexec(fd, true)) {
38 close(fd);
39 return -1;
40 }
41 35
42 if (ftruncate(fd, size) < 0) { 36 --retries;
43 close(fd); 37 } while (retries > 0 && errno == EEXIST);
44 return -1;
45 }
46 38
47 return fd; 39 return -1;
48} 40}
49 41
50static void buffer_release(void *data, struct wl_buffer *wl_buffer) { 42static void buffer_release(void *data, struct wl_buffer *wl_buffer) {
@@ -62,17 +54,20 @@ static struct pool_buffer *create_buffer(struct wl_shm *shm,
62 uint32_t stride = width * 4; 54 uint32_t stride = width * 4;
63 size_t size = stride * height; 55 size_t size = stride * height;
64 56
65 char *name; 57 int fd = anonymous_shm_open();
66 int fd = create_pool_file(size, &name); 58 if (fd == -1) {
67 assert(fd != -1); 59 return NULL;
60 }
61 if (ftruncate(fd, size) < 0) {
62 close(fd);
63 return NULL;
64 }
68 void *data = mmap(NULL, size, PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0); 65 void *data = mmap(NULL, size, PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0);
69 struct wl_shm_pool *pool = wl_shm_create_pool(shm, fd, size); 66 struct wl_shm_pool *pool = wl_shm_create_pool(shm, fd, size);
70 buf->buffer = wl_shm_pool_create_buffer(pool, 0, 67 buf->buffer = wl_shm_pool_create_buffer(pool, 0,
71 width, height, stride, format); 68 width, height, stride, format);
72 wl_shm_pool_destroy(pool); 69 wl_shm_pool_destroy(pool);
73 close(fd); 70 close(fd);
74 unlink(name);
75 free(name);
76 71
77 buf->size = size; 72 buf->size = size;
78 buf->width = width; 73 buf->width = width;