aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorLibravatar Manuel Stoeckl <code@mstoeckl.com>2022-11-24 17:56:01 -0500
committerLibravatar Simon Ser <contact@emersion.fr>2022-11-26 10:29:58 +0100
commit9f4229827f43cc26cf699a92e847834fed61e950 (patch)
treedc86a9b7e8cf3c0b2dd352124ffb5ec08b6e7f16
parentoutput: set damage ring bounds to pixel values (diff)
downloadsway-9f4229827f43cc26cf699a92e847834fed61e950.tar.gz
sway-9f4229827f43cc26cf699a92e847834fed61e950.tar.zst
sway-9f4229827f43cc26cf699a92e847834fed61e950.zip
Use shm_open instead of mkstemp
shm_open is more reliable because it does not require a writeable filesystem folder, unlike mkstemp. (cherry picked from commit e2bc8866f46701e9c825ad7fa5baac02b2e4898f)
-rw-r--r--client/pool-buffer.c66
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
16static int create_pool_file(size_t size, char **name) { 18static 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
50static void buffer_release(void *data, struct wl_buffer *wl_buffer) { 43static 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;