17c59f3f6f3b6dbfcfb261b07062590d2dad2da62Elliott Hughes/*
27c59f3f6f3b6dbfcfb261b07062590d2dad2da62Elliott Hughes * Copyright (C) 2016 The Android Open Source Project
37c59f3f6f3b6dbfcfb261b07062590d2dad2da62Elliott Hughes * All rights reserved.
47c59f3f6f3b6dbfcfb261b07062590d2dad2da62Elliott Hughes *
57c59f3f6f3b6dbfcfb261b07062590d2dad2da62Elliott Hughes * Redistribution and use in source and binary forms, with or without
67c59f3f6f3b6dbfcfb261b07062590d2dad2da62Elliott Hughes * modification, are permitted provided that the following conditions
77c59f3f6f3b6dbfcfb261b07062590d2dad2da62Elliott Hughes * are met:
87c59f3f6f3b6dbfcfb261b07062590d2dad2da62Elliott Hughes *  * Redistributions of source code must retain the above copyright
97c59f3f6f3b6dbfcfb261b07062590d2dad2da62Elliott Hughes *    notice, this list of conditions and the following disclaimer.
107c59f3f6f3b6dbfcfb261b07062590d2dad2da62Elliott Hughes *  * Redistributions in binary form must reproduce the above copyright
117c59f3f6f3b6dbfcfb261b07062590d2dad2da62Elliott Hughes *    notice, this list of conditions and the following disclaimer in
127c59f3f6f3b6dbfcfb261b07062590d2dad2da62Elliott Hughes *    the documentation and/or other materials provided with the
137c59f3f6f3b6dbfcfb261b07062590d2dad2da62Elliott Hughes *    distribution.
147c59f3f6f3b6dbfcfb261b07062590d2dad2da62Elliott Hughes *
157c59f3f6f3b6dbfcfb261b07062590d2dad2da62Elliott Hughes * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
167c59f3f6f3b6dbfcfb261b07062590d2dad2da62Elliott Hughes * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
177c59f3f6f3b6dbfcfb261b07062590d2dad2da62Elliott Hughes * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
187c59f3f6f3b6dbfcfb261b07062590d2dad2da62Elliott Hughes * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
197c59f3f6f3b6dbfcfb261b07062590d2dad2da62Elliott Hughes * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
207c59f3f6f3b6dbfcfb261b07062590d2dad2da62Elliott Hughes * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
217c59f3f6f3b6dbfcfb261b07062590d2dad2da62Elliott Hughes * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
227c59f3f6f3b6dbfcfb261b07062590d2dad2da62Elliott Hughes * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
237c59f3f6f3b6dbfcfb261b07062590d2dad2da62Elliott Hughes * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
247c59f3f6f3b6dbfcfb261b07062590d2dad2da62Elliott Hughes * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
257c59f3f6f3b6dbfcfb261b07062590d2dad2da62Elliott Hughes * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
267c59f3f6f3b6dbfcfb261b07062590d2dad2da62Elliott Hughes * SUCH DAMAGE.
277c59f3f6f3b6dbfcfb261b07062590d2dad2da62Elliott Hughes */
287c59f3f6f3b6dbfcfb261b07062590d2dad2da62Elliott Hughes
297c59f3f6f3b6dbfcfb261b07062590d2dad2da62Elliott Hughes#include <sys/shm.h>
307c59f3f6f3b6dbfcfb261b07062590d2dad2da62Elliott Hughes
317c59f3f6f3b6dbfcfb261b07062590d2dad2da62Elliott Hughes#include <sys/syscall.h>
327c59f3f6f3b6dbfcfb261b07062590d2dad2da62Elliott Hughes#include <unistd.h>
337c59f3f6f3b6dbfcfb261b07062590d2dad2da62Elliott Hughes
347c59f3f6f3b6dbfcfb261b07062590d2dad2da62Elliott Hughesvoid* shmat(int id, const void* address, int flags) {
351878ea08de92f68cd89da76b5368fe81b535a029Elliott Hughes#if defined(SYS_shmat)
361878ea08de92f68cd89da76b5368fe81b535a029Elliott Hughes  return reinterpret_cast<void*>(syscall(SYS_shmat, id, address, flags));
371878ea08de92f68cd89da76b5368fe81b535a029Elliott Hughes#else
387c59f3f6f3b6dbfcfb261b07062590d2dad2da62Elliott Hughes  // See the kernel's ipc/syscall.c for the other side of this dance.
397c59f3f6f3b6dbfcfb261b07062590d2dad2da62Elliott Hughes  void* result = nullptr;
407c59f3f6f3b6dbfcfb261b07062590d2dad2da62Elliott Hughes  if (syscall(SYS_ipc, SHMAT, id, flags, &result, address, 0) == -1) {
417c59f3f6f3b6dbfcfb261b07062590d2dad2da62Elliott Hughes    return reinterpret_cast<void*>(-1);
427c59f3f6f3b6dbfcfb261b07062590d2dad2da62Elliott Hughes  }
437c59f3f6f3b6dbfcfb261b07062590d2dad2da62Elliott Hughes  return result;
447c59f3f6f3b6dbfcfb261b07062590d2dad2da62Elliott Hughes#endif
457c59f3f6f3b6dbfcfb261b07062590d2dad2da62Elliott Hughes}
467c59f3f6f3b6dbfcfb261b07062590d2dad2da62Elliott Hughes
477c59f3f6f3b6dbfcfb261b07062590d2dad2da62Elliott Hughesint shmctl(int id, int cmd, struct shmid_ds* buf) {
4823f088cd74b3c1da7aed07e5984970d38c85cd03Nikola Veljkovic#if !defined(__LP64__) || defined(__mips__)
497c59f3f6f3b6dbfcfb261b07062590d2dad2da62Elliott Hughes  // Annoyingly, the kernel requires this for 32-bit but rejects it for 64-bit.
5023f088cd74b3c1da7aed07e5984970d38c85cd03Nikola Veljkovic  // Mips64 is an exception to this, it requires the flag.
517c59f3f6f3b6dbfcfb261b07062590d2dad2da62Elliott Hughes  cmd |= IPC_64;
527c59f3f6f3b6dbfcfb261b07062590d2dad2da62Elliott Hughes#endif
531878ea08de92f68cd89da76b5368fe81b535a029Elliott Hughes#if defined(SYS_shmctl)
547c59f3f6f3b6dbfcfb261b07062590d2dad2da62Elliott Hughes  return syscall(SYS_shmctl, id, cmd, buf);
551878ea08de92f68cd89da76b5368fe81b535a029Elliott Hughes#else
561878ea08de92f68cd89da76b5368fe81b535a029Elliott Hughes  return syscall(SYS_ipc, SHMCTL, id, cmd, 0, buf, 0);
577c59f3f6f3b6dbfcfb261b07062590d2dad2da62Elliott Hughes#endif
587c59f3f6f3b6dbfcfb261b07062590d2dad2da62Elliott Hughes}
597c59f3f6f3b6dbfcfb261b07062590d2dad2da62Elliott Hughes
607c59f3f6f3b6dbfcfb261b07062590d2dad2da62Elliott Hughesint shmdt(const void* address) {
611878ea08de92f68cd89da76b5368fe81b535a029Elliott Hughes#if defined(SYS_shmdt)
627c59f3f6f3b6dbfcfb261b07062590d2dad2da62Elliott Hughes  return syscall(SYS_shmdt, address);
631878ea08de92f68cd89da76b5368fe81b535a029Elliott Hughes#else
641878ea08de92f68cd89da76b5368fe81b535a029Elliott Hughes  return syscall(SYS_ipc, SHMDT, 0, 0, 0, address, 0);
657c59f3f6f3b6dbfcfb261b07062590d2dad2da62Elliott Hughes#endif
667c59f3f6f3b6dbfcfb261b07062590d2dad2da62Elliott Hughes}
677c59f3f6f3b6dbfcfb261b07062590d2dad2da62Elliott Hughes
687c59f3f6f3b6dbfcfb261b07062590d2dad2da62Elliott Hughesint shmget(key_t key, size_t size, int flags) {
691878ea08de92f68cd89da76b5368fe81b535a029Elliott Hughes#if defined(SYS_shmget)
707c59f3f6f3b6dbfcfb261b07062590d2dad2da62Elliott Hughes  return syscall(SYS_shmget, key, size, flags);
711878ea08de92f68cd89da76b5368fe81b535a029Elliott Hughes#else
721878ea08de92f68cd89da76b5368fe81b535a029Elliott Hughes  return syscall(SYS_ipc, SHMGET, key, size, flags, 0, 0);
737c59f3f6f3b6dbfcfb261b07062590d2dad2da62Elliott Hughes#endif
747c59f3f6f3b6dbfcfb261b07062590d2dad2da62Elliott Hughes}
75