Use memfd on FreeBSD 13, shm_open(SHM_ANON) on older versions

/dev/shm usually does not exist on FreeBSD, so the mkostemp call was failing.
FreeBSD 13 offers memfd support complete with seals, use it.
This commit is contained in:
Greg V 2020-11-09 00:51:44 +03:00 committed by Wim Taymans
parent 90ade199e6
commit 6ffb997c5a

View file

@ -43,11 +43,7 @@
#define NAME "mempool" #define NAME "mempool"
#ifndef __FreeBSD__ #if !defined(__FreeBSD__) && !defined(HAVE_MEMFD_CREATE)
#define USE_MEMFD
#endif
#if defined(USE_MEMFD) && !defined(HAVE_MEMFD_CREATE)
/* /*
* No glibc wrappers exist for memfd_create(2), so provide our own. * No glibc wrappers exist for memfd_create(2), so provide our own.
* *
@ -60,6 +56,8 @@ static inline int memfd_create(const char *name, unsigned int flags)
{ {
return syscall(SYS_memfd_create, name, flags); return syscall(SYS_memfd_create, name, flags);
} }
#define HAVE_MEMFD_CREATE 1
#endif #endif
/* memfd_create(2) flags */ /* memfd_create(2) flags */
@ -478,13 +476,20 @@ struct pw_memblock * pw_mempool_alloc(struct pw_mempool *pool, enum pw_memblock_
spa_list_init(&b->mappings); spa_list_init(&b->mappings);
spa_list_init(&b->memmaps); spa_list_init(&b->memmaps);
#ifdef USE_MEMFD #ifdef HAVE_MEMFD_CREATE
b->this.fd = memfd_create("pipewire-memfd", MFD_CLOEXEC | MFD_ALLOW_SEALING); b->this.fd = memfd_create("pipewire-memfd", MFD_CLOEXEC | MFD_ALLOW_SEALING);
if (b->this.fd == -1) { if (b->this.fd == -1) {
res = -errno; res = -errno;
pw_log_error(NAME" %p: Failed to create memfd: %m", pool); pw_log_error(NAME" %p: Failed to create memfd: %m", pool);
goto error_free; goto error_free;
} }
#elif defined(__FreeBSD__)
b->this.fd = shm_open(SHM_ANON, O_CREAT | O_RDWR | O_CLOEXEC, 0);
if (b->this.fd == -1) {
res = -errno;
pw_log_error(NAME" %p: Failed to create SHM_ANON fd: %m", pool);
goto error_free;
}
#else #else
char filename[] = "/dev/shm/pipewire-tmpfile.XXXXXX"; char filename[] = "/dev/shm/pipewire-tmpfile.XXXXXX";
b->this.fd = mkostemp(filename, O_CLOEXEC); b->this.fd = mkostemp(filename, O_CLOEXEC);
@ -501,7 +506,7 @@ struct pw_memblock * pw_mempool_alloc(struct pw_mempool *pool, enum pw_memblock_
pw_log_warn(NAME" %p: Failed to truncate temporary file: %m", pool); pw_log_warn(NAME" %p: Failed to truncate temporary file: %m", pool);
goto error_close; goto error_close;
} }
#ifdef USE_MEMFD #ifdef HAVE_MEMFD_CREATE
if (flags & PW_MEMBLOCK_FLAG_SEAL) { if (flags & PW_MEMBLOCK_FLAG_SEAL) {
unsigned int seals = F_SEAL_GROW | F_SEAL_SHRINK | F_SEAL_SEAL; unsigned int seals = F_SEAL_GROW | F_SEAL_SHRINK | F_SEAL_SEAL;
if (fcntl(b->this.fd, F_ADD_SEALS, seals) == -1) { if (fcntl(b->this.fd, F_ADD_SEALS, seals) == -1) {