[compat] fix solaris shm_open syscall causing crashes with SHM_ANON, implement portable posix shm_open_anon
Some checks failed
eden-license / license-header (pull_request) Failing after 16s
Some checks failed
eden-license / license-header (pull_request) Failing after 16s
This commit is contained in:
parent
1f34d836b4
commit
4e91958ba1
1 changed files with 63 additions and 11 deletions
|
@ -9,7 +9,7 @@
|
|||
#include <windows.h>
|
||||
#include "common/dynamic_library.h"
|
||||
|
||||
#elif defined(__linux__) || defined(__FreeBSD__) // ^^^ Windows ^^^ vvv Linux vvv
|
||||
#elif defined(__linux__) || defined(__FreeBSD__) || defined(__sun__) // ^^^ Windows ^^^ vvv Linux vvv
|
||||
|
||||
#ifndef _GNU_SOURCE
|
||||
#define _GNU_SOURCE
|
||||
|
@ -21,9 +21,14 @@
|
|||
#include <unistd.h>
|
||||
#include "common/scope_exit.h"
|
||||
|
||||
// FreeBSD
|
||||
#ifndef MAP_NORESERVE
|
||||
#define MAP_NORESERVE 0
|
||||
#endif
|
||||
// Solaris 11 and illumos
|
||||
#ifndef MAP_ALIGNED_SUPER
|
||||
#define MAP_ALIGNED_SUPER 0
|
||||
#endif
|
||||
|
||||
#endif // ^^^ Linux ^^^
|
||||
|
||||
|
@ -364,7 +369,7 @@ private:
|
|||
std::unordered_map<size_t, size_t> placeholder_host_pointers; ///< Placeholder backing offset
|
||||
};
|
||||
|
||||
#elif defined(__linux__) || defined(__FreeBSD__) // ^^^ Windows ^^^ vvv Linux vvv
|
||||
#elif defined(__linux__) || defined(__FreeBSD__) || defined(__sun__) // ^^^ Windows ^^^ vvv Linux vvv
|
||||
|
||||
#ifdef ARCHITECTURE_arm64
|
||||
|
||||
|
@ -409,22 +414,65 @@ static void* ChooseVirtualBase(size_t virtual_size) {
|
|||
#else
|
||||
|
||||
static void* ChooseVirtualBase(size_t virtual_size) {
|
||||
#if defined(__FreeBSD__)
|
||||
void* virtual_base =
|
||||
mmap(nullptr, virtual_size, PROT_READ | PROT_WRITE,
|
||||
MAP_PRIVATE | MAP_ANONYMOUS | MAP_NORESERVE | MAP_ALIGNED_SUPER, -1, 0);
|
||||
|
||||
void* virtual_base = mmap(nullptr, virtual_size, PROT_READ | PROT_WRITE, MAP_PRIVATE | MAP_ANONYMOUS | MAP_NORESERVE | MAP_ALIGNED_SUPER, -1, 0);
|
||||
if (virtual_base != MAP_FAILED) {
|
||||
return virtual_base;
|
||||
}
|
||||
#endif
|
||||
|
||||
return mmap(nullptr, virtual_size, PROT_READ | PROT_WRITE,
|
||||
MAP_PRIVATE | MAP_ANONYMOUS | MAP_NORESERVE, -1, 0);
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
#if defined(__sun__) || defined(__HAIKU__) || defined(__NetBSD__) || defined(__DragonFly__)
|
||||
/// Most Unices don't have a portable shm_open (AIX, OpenBSD, NetBSD, Solaris 11, OpenIndiana)
|
||||
/// Portable implementation of shm_open(SHM_ANON, ...) - roughly equivalent but without
|
||||
/// OS support - may fail sporadically, beware!
|
||||
static int shm_open_anon(int flags, mode_t mode) {
|
||||
char name[16] = "/shm-";
|
||||
char *const limit = name + sizeof(name) - 1;
|
||||
*limit = '\0';
|
||||
char *start = name + strlen(name);
|
||||
for (int tries = 0; tries < 4; tries++) {
|
||||
struct timespec tv;
|
||||
clock_gettime(CLOCK_REALTIME, &tv);
|
||||
unsigned long r = (unsigned long)tv.tv_sec + (unsigned long)tv.tv_nsec;
|
||||
for (char *fill = start; fill < limit; r /= 8)
|
||||
*fill++ = '0' + (r % 8);
|
||||
int fd = shm_open(name, flags, mode);
|
||||
if (fd != -1)
|
||||
return ([](const char *name, int fd) {
|
||||
if (shm_unlink(name) == -1) {
|
||||
int tmp = errno;
|
||||
close(fd);
|
||||
errno = tmp;
|
||||
return -1;
|
||||
}
|
||||
return fd;
|
||||
})(name, fd);
|
||||
if (errno != EEXIST)
|
||||
break;
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
#elif defined(__OpenBSD__)
|
||||
/// Except OpenBSD which explicitly uses shm_mkstemp instead (as a more secure alternative)
|
||||
static int shm_open_anon(int flags, mode_t mode) {
|
||||
char name[16] = "/shm-XXXXXXXXXX";
|
||||
int fd;
|
||||
if ((fd = shm_mkstemp(name)) == -1)
|
||||
return -1;
|
||||
return ([](const char *name, int fd) {
|
||||
if (shm_unlink(name) == -1) {
|
||||
int tmp = errno;
|
||||
close(fd);
|
||||
errno = tmp;
|
||||
return -1;
|
||||
}
|
||||
return fd;
|
||||
})(name, fd);
|
||||
}
|
||||
#endif
|
||||
|
||||
class HostMemory::Impl {
|
||||
public:
|
||||
explicit Impl(size_t backing_size_, size_t virtual_size_)
|
||||
|
@ -443,7 +491,11 @@ public:
|
|||
}
|
||||
|
||||
// Backing memory initialization
|
||||
#if defined(__FreeBSD__) && __FreeBSD__ < 13
|
||||
#if defined(__sun__) || defined(__HAIKU__) || defined(__NetBSD__) || defined(__DragonFly__)
|
||||
fd = shm_open_anon(O_RDWR | O_CREAT | O_EXCL | O_NOFOLLOW, 0600);
|
||||
#elif defined(__OpenBSD__)
|
||||
fd = shm_open_anon(O_RDWR | O_CREAT | O_EXCL | O_NOFOLLOW, 0600);
|
||||
#elif defined(__FreeBSD__) && __FreeBSD__ < 13
|
||||
// XXX Drop after FreeBSD 12.* reaches EOL on 2024-06-30
|
||||
fd = shm_open(SHM_ANON, O_RDWR, 0600);
|
||||
#else
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue