0
0
mirror of https://github.com/termux/termux-packages.git synced 2024-11-23 14:56:16 +00:00
termux-packages/x11-packages/xorg-server-xvfb/use_ashmem.patch
2023-02-21 21:23:15 +09:00

85 lines
2.0 KiB
Diff

--- ./Xext/shm_old.c 2023-02-07 03:16:51.000000000 +0200
+++ ./Xext/shm.c 2023-02-21 10:35:54.199460924 +0200
@@ -60,6 +60,7 @@
#include <sys/mman.h>
#include "protocol-versions.h"
#include "busfault.h"
+#include <linux/ioctl.h>
/* Needed for Solaris cross-zone shared memory extension */
#ifdef HAVE_SHMCTL64
@@ -1142,6 +1143,20 @@
FreeResource (shmdesc->resource, RT_NONE);
}
+static int
+shm_tmpfile_size(int fd)
+{
+ char path[PATH_MAX] = {0};
+ char realpath[256] = {0};
+ sprintf(path, "/proc/self/fd/%d", fd);
+
+ int size;
+ if (readlink(path, realpath, sizeof(realpath)) != -1 && !strcmp("/dev/ashmem", realpath))
+ return ioctl(fd, /* ASHMEM_GET_SIZE */ _IO(0x77, 4), NULL);
+ else
+ return 0;
+}
+
static int
ProcShmAttachFd(ClientPtr client)
{
@@ -1161,7 +1176,7 @@
if (fd < 0)
return BadMatch;
- if (fstat(fd, &statb) < 0 || statb.st_size == 0) {
+ if (fstat(fd, &statb) < 0 || (statb.st_size == 0 && (statb.st_size = shm_tmpfile_size(fd)) == 0)) {
close(fd);
return BadMatch;
}
@@ -1257,6 +1272,28 @@
return -1;
}
+static inline int
+shm_tmpfile_sized(size_t size)
+{
+ int fd, ret;
+ long flags;
+ fd = open("/dev/ashmem", O_RDWR | O_CLOEXEC);
+ if (fd < 0)
+ return fd;
+ ret = ioctl(fd, /* ASHMEM_SET_SIZE */ _IOW(0x77, 3, size_t), size);
+ if (ret < 0)
+ goto err;
+ flags = fcntl(fd, F_GETFD);
+ if (flags == -1)
+ goto err;
+ if (fcntl(fd, F_SETFD, flags | FD_CLOEXEC) == -1)
+ goto err;
+ return fd;
+ err:
+ close(fd);
+ return ret;
+}
+
static int
ProcShmCreateSegment(ClientPtr client)
{
@@ -1276,13 +1313,9 @@
client->errorValue = stuff->readOnly;
return BadValue;
}
- fd = shm_tmpfile();
+ fd = shm_tmpfile_sized(stuff->size);
if (fd < 0)
return BadAlloc;
- if (ftruncate(fd, stuff->size) < 0) {
- close(fd);
- return BadAlloc;
- }
shmdesc = malloc(sizeof(ShmDescRec));
if (!shmdesc) {
close(fd);