1 /* Copyright 2016 The Chromium OS Authors. All rights reserved. 2 * Use of this source code is governed by a BSD-style license that can be 3 * found in the LICENSE file. 4 */ 5 6 #include <sys/cdefs.h> 7 #include <sys/mman.h> 8 #ifdef __BIONIC__ 9 #include <cutils/ashmem.h> 10 #else 11 #include <sys/shm.h> 12 #endif 13 #include <errno.h> 14 #include <syslog.h> 15 #include <string.h> 16 17 #include "cras_shm.h" 18 19 #ifdef __BIONIC__ 20 21 int cras_shm_open_rw (const char *name, size_t size) 22 { 23 int fd; 24 25 /* Eliminate the / in the shm_name. */ 26 if (name[0] == '/') 27 name++; 28 fd = ashmem_create_region(name, size); 29 if (fd < 0) { 30 fd = -errno; 31 syslog(LOG_ERR, "failed to ashmem_create_region %s: %s\n", 32 name, strerror(-fd)); 33 } 34 return fd; 35 } 36 37 int cras_shm_reopen_ro (const char *name, int fd) 38 { 39 /* After mmaping the ashmem read/write, change it's protection 40 bits to disallow further write access. */ 41 if (ashmem_set_prot_region(fd, PROT_READ) != 0) { 42 fd = -errno; 43 syslog(LOG_ERR, 44 "failed to ashmem_set_prot_region %s: %s\n", 45 name, strerror(-fd)); 46 } 47 return fd; 48 } 49 50 void cras_shm_close_unlink (const char *name, int fd) 51 { 52 close(fd); 53 } 54 55 #else 56 57 int cras_shm_open_rw (const char *name, size_t size) 58 { 59 int fd; 60 int rc; 61 62 fd = shm_open(name, O_CREAT | O_EXCL | O_RDWR, 0600); 63 if (fd < 0) { 64 fd = -errno; 65 syslog(LOG_ERR, "failed to shm_open %s: %s\n", 66 name, strerror(-fd)); 67 return fd; 68 } 69 rc = ftruncate(fd, size); 70 if (rc) { 71 rc = -errno; 72 syslog(LOG_ERR, "failed to set size of shm %s: %s\n", 73 name, strerror(-rc)); 74 return rc; 75 } 76 return fd; 77 } 78 79 int cras_shm_reopen_ro (const char *name, int fd) 80 { 81 /* Open a read-only copy to dup and pass to clients. */ 82 fd = shm_open(name, O_RDONLY, 0); 83 if (fd < 0) { 84 fd = -errno; 85 syslog(LOG_ERR, 86 "Failed to re-open shared memory '%s' read-only: %s", 87 name, strerror(-fd)); 88 } 89 return fd; 90 } 91 92 void cras_shm_close_unlink (const char *name, int fd) 93 { 94 shm_unlink(name); 95 close(fd); 96 } 97 98 #endif 99