summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorKeith Packard <keithp@keithp.com>2014-01-30 12:11:34 -0800
committerKeith Packard <keithp@keithp.com>2014-01-30 12:11:34 -0800
commit8ec3e0a5b1cf9d94c5e1b3d66b979ef9e9019aa8 (patch)
tree392c8c606a066497cc255fb407e324d171abd4ce
parent739c624630154b422d7f5e4ae92f93df42fa35b9 (diff)
shmfd example: use O_TMPFILE. Create multiple segments
Signed-off-by: Keith Packard <keithp@keithp.com>
-rw-r--r--shmfd.c60
1 files changed, 55 insertions, 5 deletions
diff --git a/shmfd.c b/shmfd.c
index 45b9067..2094efa 100644
--- a/shmfd.c
+++ b/shmfd.c
@@ -27,17 +27,43 @@
#include <xcb/shm.h>
#include <xcb/xcb_aux.h>
#include <unistd.h>
+#include <fcntl.h>
+
+#define __O_TMPFILE 020000000
+#define O_TMPFILE (__O_TMPFILE | O_DIRECTORY)
int
-make_shm(int size, void **addrp)
+shm_tmpfile(void)
{
- void *addr;
+ int fd;
+ int flags;
char template[] = "/run/shm/shmfd-XXXXXX";
- int fd = mkstemp(template);
-
- if (fd < 0)
+#ifdef O_TMPFILE
+ fd = open("/run/shm", O_TMPFILE|O_RDWR|O_CLOEXEC|O_EXCL, 0666);
+ if (fd >= 0) {
+ printf ("Using O_TMPFILE\n");
return fd;
+ }
+ printf ("Not using O_TMPFILE\n");
+ perror("O_TMPFILE");
+#endif
+ fd = mkstemp(template);
+ if (fd < 0)
+ return -1;
unlink(template);
+ if (fcntl(fd, F_GETFD, &flags) >= 0) {
+ flags |= FD_CLOEXEC;
+ (void) fcntl(fd, F_SETFD, &flags);
+ }
+ return fd;
+}
+
+int
+make_shm(int size, void **addrp)
+{
+ void *addr;
+ int fd = shm_tmpfile();
+
ftruncate(fd, size);
addr = mmap (NULL, size, PROT_READ|PROT_WRITE, MAP_SHARED, fd, 0);
if (addr == MAP_FAILED) {
@@ -78,16 +104,21 @@ main (int argc, char **argv)
xcb_screen_t *screen;
int fd;
int segment_fd;
+ int segment_fd_2;
void *addr;
void *server_addr;
+ void *server_addr_2;
xcb_shm_seg_t shm_seg;
xcb_shm_seg_t shm_server_seg;
+ xcb_shm_seg_t shm_server_seg_2;
xcb_gc_t gc;
xcb_window_t window;
xcb_generic_event_t *event;
xcb_generic_error_t *error;
xcb_shm_create_segment_cookie_t shm_create_segment_cookie;
+ xcb_shm_create_segment_cookie_t shm_create_segment_cookie_2;
xcb_shm_create_segment_reply_t *shm_create_segment_reply;
+ xcb_shm_create_segment_reply_t *shm_create_segment_reply_2;
xcb_generic_error_t *shm_create_segment_error;
int *shm_create_segment_fds;
uint32_t window_mask;
@@ -113,6 +144,13 @@ main (int argc, char **argv)
(shm_server_seg = xcb_generate_id(c)),
size,
1);
+ shm_create_segment_cookie_2 = xcb_shm_create_segment(c,
+ (shm_server_seg_2 = xcb_generate_id(c)),
+ size,
+ 1);
+ shm_create_segment_reply_2 = xcb_shm_create_segment_reply (c,
+ shm_create_segment_cookie_2,
+ &shm_create_segment_error);
shm_create_segment_reply = xcb_shm_create_segment_reply (c,
shm_create_segment_cookie,
&shm_create_segment_error);
@@ -128,6 +166,18 @@ main (int argc, char **argv)
else
server_addr = NULL;
+ if (shm_create_segment_reply_2) {
+ shm_create_segment_fds = xcb_shm_create_segment_reply_fds(c,
+ shm_create_segment_reply_2);
+ segment_fd_2 = shm_create_segment_fds[0];
+
+ server_addr_2 = mmap(NULL, size, PROT_READ|PROT_WRITE, MAP_SHARED, segment_fd_2, 0);
+ free(shm_create_segment_reply_2);
+// paint(server_addr_2, WIDTH, HEIGHT, 1);
+ }
+ else
+ server_addr_2 = NULL;
+
window_mask = XCB_CW_BACK_PIXEL|XCB_CW_EVENT_MASK;
window_values[0] = 0xffffff;
window_values[1] = XCB_EVENT_MASK_EXPOSURE|XCB_EVENT_MASK_KEY_PRESS;