blob: 6b4085a9e1f32b5bcd0148fe9d2d8b5fff9e49f0 [file] [log] [blame]
/* Copyright 2016 The Chromium OS Authors. All rights reserved.
* Use of this source code is governed by a BSD-style license that can be
* found in the LICENSE file.
*/
#include <sys/cdefs.h>
#include <sys/mman.h>
#ifdef __BIONIC__
#include <cutils/ashmem.h>
#else
#include <sys/shm.h>
#endif
#include <errno.h>
#include <syslog.h>
#include <string.h>
#include "cras_shm.h"
#ifdef __BIONIC__
int cras_shm_open_rw (const char *name, size_t size)
{
int fd;
/* Eliminate the / in the shm_name. */
if (name[0] == '/')
name++;
fd = ashmem_create_region(name, size);
if (fd < 0) {
fd = -errno;
syslog(LOG_ERR, "failed to ashmem_create_region %s: %s\n",
name, strerror(-fd));
}
return fd;
}
int cras_shm_reopen_ro (const char *name, int fd)
{
/* After mmaping the ashmem read/write, change it's protection
bits to disallow further write access. */
if (ashmem_set_prot_region(fd, PROT_READ) != 0) {
fd = -errno;
syslog(LOG_ERR,
"failed to ashmem_set_prot_region %s: %s\n",
name, strerror(-fd));
}
return fd;
}
void cras_shm_close_unlink (const char *name, int fd)
{
close(fd);
}
#else
int cras_shm_open_rw (const char *name, size_t size)
{
int fd;
int rc;
fd = shm_open(name, O_CREAT | O_EXCL | O_RDWR, 0600);
if (fd < 0) {
fd = -errno;
syslog(LOG_ERR, "failed to shm_open %s: %s\n",
name, strerror(-fd));
return fd;
}
rc = ftruncate(fd, size);
if (rc) {
rc = -errno;
syslog(LOG_ERR, "failed to set size of shm %s: %s\n",
name, strerror(-rc));
return rc;
}
return fd;
}
int cras_shm_reopen_ro (const char *name, int fd)
{
/* Open a read-only copy to dup and pass to clients. */
fd = shm_open(name, O_RDONLY, 0);
if (fd < 0) {
fd = -errno;
syslog(LOG_ERR,
"Failed to re-open shared memory '%s' read-only: %s",
name, strerror(-fd));
}
return fd;
}
void cras_shm_close_unlink (const char *name, int fd)
{
shm_unlink(name);
close(fd);
}
#endif