1 /* This Source Code Form is subject to the terms of the Mozilla Public
2  * License, v. 2.0. If a copy of the MPL was not distributed with this
3  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
4 
5 #include <cstring>
6 #include <dlfcn.h>
7 #include <fcntl.h>
8 #include <linux/ashmem.h>
9 #include <stdio.h>
10 #include <sys/stat.h>
11 #include <sys/types.h>
12 #include <sys/ioctl.h>
13 #include <unistd.h>
14 
15 #include "Ashmem.h"
16 
17 namespace mozilla {
18 namespace android {
19 
libhandle()20 static void* libhandle() {
21   static void* handle = dlopen("libandroid.so", RTLD_LAZY | RTLD_LOCAL);
22   return handle;
23 }
24 
ashmem_create(const char * name,size_t size)25 int ashmem_create(const char* name, size_t size) {
26   static auto fCreate =
27       (int (*)(const char*, size_t))dlsym(libhandle(), "ASharedMemory_create");
28 
29   if (fCreate) {
30     return fCreate(name, size);
31   }
32 
33   int fd = open("/" ASHMEM_NAME_DEF, O_RDWR, 0600);
34   if (fd < 0) {
35     return fd;
36   }
37 
38   if (name) {
39     char str[ASHMEM_NAME_LEN];
40     strlcpy(str, name, sizeof(str));
41     ioctl(fd, ASHMEM_SET_NAME, str);
42   }
43 
44   if (ioctl(fd, ASHMEM_SET_SIZE, size) != 0) {
45     close(fd);
46     return -1;
47   }
48 
49   return fd;
50 }
51 
ashmem_getSize(int fd)52 size_t ashmem_getSize(int fd) {
53   static auto fGetSize =
54       (size_t(*)(int))dlsym(libhandle(), "ASharedMemory_getSize");
55   if (fGetSize) {
56     return fGetSize(fd);
57   }
58 
59   return (size_t)ioctl(fd, ASHMEM_GET_SIZE, nullptr);
60 }
61 
ashmem_setProt(int fd,int prot)62 int ashmem_setProt(int fd, int prot) {
63   static auto fSetProt =
64       (int (*)(int, int))dlsym(libhandle(), "ASharedMemory_setProt");
65   if (fSetProt) {
66     return fSetProt(fd, prot);
67   }
68 
69   return ioctl(fd, ASHMEM_SET_PROT_MASK, prot);
70 }
71 
72 }  // namespace android
73 }  // namespace mozilla
74