1 //===- FuzzerShmemPosix.cpp - Posix shared memory ---------------*- C++ -* ===//
3 // The LLVM Compiler Infrastructure
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
8 //===----------------------------------------------------------------------===//
10 //===----------------------------------------------------------------------===//
11 #include "FuzzerDefs.h"
15 #include "FuzzerShmem.h"
19 #include <semaphore.h>
24 #include <sys/types.h>
29 std::string SharedMemoryRegion::Path(const char *Name) {
30 return DirPlusFile(TmpDir(), Name);
33 std::string SharedMemoryRegion::SemName(const char *Name, int Idx) {
34 std::string Res(Name);
35 // When passing a name without a leading <slash> character to
36 // sem_open, the behaviour is unspecified in POSIX. Add a leading
37 // <slash> character for the name if there is no such one.
38 if (!Res.empty() && Res[0] != '/')
39 Res.insert(Res.begin(), '/');
40 return Res + (char)('0' + Idx);
43 bool SharedMemoryRegion::Map(int fd) {
45 (uint8_t *)mmap(0, kShmemSize, PROT_WRITE | PROT_READ, MAP_SHARED, fd, 0);
46 if (Data == (uint8_t*)-1)
51 bool SharedMemoryRegion::Create(const char *Name) {
52 int fd = open(Path(Name).c_str(), O_CREAT | O_RDWR, 0777);
53 if (fd < 0) return false;
54 if (ftruncate(fd, kShmemSize) < 0) return false;
57 for (int i = 0; i < 2; i++) {
58 sem_unlink(SemName(Name, i).c_str());
59 Semaphore[i] = sem_open(SemName(Name, i).c_str(), O_CREAT, 0644, 0);
60 if (Semaphore[i] == SEM_FAILED)
67 bool SharedMemoryRegion::Open(const char *Name) {
68 int fd = open(Path(Name).c_str(), O_RDWR);
69 if (fd < 0) return false;
71 if (0 != fstat(fd, &stat_res))
73 assert(stat_res.st_size == kShmemSize);
76 for (int i = 0; i < 2; i++) {
77 Semaphore[i] = sem_open(SemName(Name, i).c_str(), 0);
78 if (Semaphore[i] == SEM_FAILED)
85 bool SharedMemoryRegion::Destroy(const char *Name) {
86 return 0 == unlink(Path(Name).c_str());
89 void SharedMemoryRegion::Post(int Idx) {
90 assert(Idx == 0 || Idx == 1);
91 sem_post((sem_t*)Semaphore[Idx]);
94 void SharedMemoryRegion::Wait(int Idx) {
95 assert(Idx == 0 || Idx == 1);
96 for (int i = 0; i < 10 && sem_wait((sem_t*)Semaphore[Idx]); i++) {
97 // sem_wait may fail if interrupted by a signal.
100 Printf("%s: sem_wait[%d] failed %s\n", i < 9 ? "WARNING" : "ERROR", i,
106 } // namespace fuzzer
108 #endif // LIBFUZZER_POSIX