diff options
author | Manuel Stoeckl <code@mstoeckl.com> | 2022-11-24 17:56:01 -0500 |
---|---|---|
committer | Simon Ser <contact@emersion.fr> | 2022-11-25 00:05:12 +0100 |
commit | e2bc8866f46701e9c825ad7fa5baac02b2e4898f (patch) | |
tree | 584932a9c3665b72f66d5fe62d1b9af3c698363a | |
parent | Update for wlroots!3814 (diff) | |
download | sway-e2bc8866f46701e9c825ad7fa5baac02b2e4898f.tar.gz sway-e2bc8866f46701e9c825ad7fa5baac02b2e4898f.tar.zst sway-e2bc8866f46701e9c825ad7fa5baac02b2e4898f.zip |
Use shm_open instead of mkstemp
shm_open is more reliable because it does not require
a writeable filesystem folder, unlike mkstemp.
-rw-r--r-- | client/pool-buffer.c | 66 |
1 files changed, 31 insertions, 35 deletions
diff --git a/client/pool-buffer.c b/client/pool-buffer.c index ea31edd3..3546b897 100644 --- a/client/pool-buffer.c +++ b/client/pool-buffer.c | |||
@@ -1,50 +1,43 @@ | |||
1 | #define _POSIX_C_SOURCE 200809 | 1 | #define _POSIX_C_SOURCE 200809 |
2 | #include <assert.h> | 2 | #include <assert.h> |
3 | #include <cairo.h> | 3 | #include <cairo.h> |
4 | #include <errno.h> | ||
4 | #include <fcntl.h> | 5 | #include <fcntl.h> |
5 | #include <pango/pangocairo.h> | 6 | #include <pango/pangocairo.h> |
6 | #include <stdio.h> | 7 | #include <stdio.h> |
7 | #include <stdlib.h> | 8 | #include <stdlib.h> |
8 | #include <string.h> | 9 | #include <string.h> |
9 | #include <sys/mman.h> | 10 | #include <sys/mman.h> |
11 | #include <time.h> | ||
10 | #include <unistd.h> | 12 | #include <unistd.h> |
11 | #include <wayland-client.h> | 13 | #include <wayland-client.h> |
12 | #include "config.h" | 14 | #include "config.h" |
13 | #include "pool-buffer.h" | 15 | #include "pool-buffer.h" |
14 | #include "util.h" | 16 | #include "util.h" |
15 | 17 | ||
16 | static int create_pool_file(size_t size, char **name) { | 18 | static int anonymous_shm_open(void) { |
17 | static const char template[] = "sway-client-XXXXXX"; | 19 | int retries = 100; |
18 | const char *path = getenv("XDG_RUNTIME_DIR"); | 20 | |
19 | if (path == NULL) { | 21 | do { |
20 | fprintf(stderr, "XDG_RUNTIME_DIR is not set\n"); | 22 | // try a probably-unique name |
21 | return -1; | 23 | struct timespec ts; |
22 | } | 24 | clock_gettime(CLOCK_MONOTONIC, &ts); |
23 | 25 | pid_t pid = getpid(); | |
24 | size_t name_size = strlen(template) + 1 + strlen(path) + 1; | 26 | char name[50]; |
25 | *name = malloc(name_size); | 27 | snprintf(name, sizeof(name), "/sway-%x-%x", |
26 | if (*name == NULL) { | 28 | (unsigned int)pid, (unsigned int)ts.tv_nsec); |
27 | fprintf(stderr, "allocation failed\n"); | 29 | |
28 | return -1; | 30 | // shm_open guarantees that O_CLOEXEC is set |
29 | } | 31 | int fd = shm_open(name, O_RDWR | O_CREAT | O_EXCL, 0600); |
30 | snprintf(*name, name_size, "%s/%s", path, template); | 32 | if (fd >= 0) { |
31 | 33 | shm_unlink(name); | |
32 | int fd = mkstemp(*name); | 34 | return fd; |
33 | if (fd < 0) { | 35 | } |
34 | return -1; | ||
35 | } | ||
36 | |||
37 | if (!sway_set_cloexec(fd, true)) { | ||
38 | close(fd); | ||
39 | return -1; | ||
40 | } | ||
41 | 36 | ||
42 | if (ftruncate(fd, size) < 0) { | 37 | --retries; |
43 | close(fd); | 38 | } while (retries > 0 && errno == EEXIST); |
44 | return -1; | ||
45 | } | ||
46 | 39 | ||
47 | return fd; | 40 | return -1; |
48 | } | 41 | } |
49 | 42 | ||
50 | static void buffer_release(void *data, struct wl_buffer *wl_buffer) { | 43 | static void buffer_release(void *data, struct wl_buffer *wl_buffer) { |
@@ -62,17 +55,20 @@ static struct pool_buffer *create_buffer(struct wl_shm *shm, | |||
62 | uint32_t stride = width * 4; | 55 | uint32_t stride = width * 4; |
63 | size_t size = stride * height; | 56 | size_t size = stride * height; |
64 | 57 | ||
65 | char *name; | 58 | int fd = anonymous_shm_open(); |
66 | int fd = create_pool_file(size, &name); | 59 | if (fd == -1) { |
67 | assert(fd != -1); | 60 | return NULL; |
61 | } | ||
62 | if (ftruncate(fd, size) < 0) { | ||
63 | close(fd); | ||
64 | return NULL; | ||
65 | } | ||
68 | void *data = mmap(NULL, size, PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0); | 66 | 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); | 67 | struct wl_shm_pool *pool = wl_shm_create_pool(shm, fd, size); |
70 | buf->buffer = wl_shm_pool_create_buffer(pool, 0, | 68 | buf->buffer = wl_shm_pool_create_buffer(pool, 0, |
71 | width, height, stride, format); | 69 | width, height, stride, format); |
72 | wl_shm_pool_destroy(pool); | 70 | wl_shm_pool_destroy(pool); |
73 | close(fd); | 71 | close(fd); |
74 | unlink(name); | ||
75 | free(name); | ||
76 | 72 | ||
77 | buf->size = size; | 73 | buf->size = size; |
78 | buf->width = width; | 74 | buf->width = width; |