From 3464655e84c73d8aedbaf805fef29072c6f75665 Mon Sep 17 00:00:00 2001 From: Chia-I Wu Date: Tue, 9 Nov 2021 09:44:13 -0800 Subject: [PATCH] mesa: copy anon_file from Mesa Signed-off-by: Chia-I Wu Reviewed-by: Yiwei Zhang Reviewed-by: Ryan Neph --- config.h.meson | 1 + meson.build | 2 +- src/mesa/meson.build | 1 + src/mesa/util/anon_file.c | 166 ++++++++++++++++++++++++++++++++++++++ src/mesa/util/anon_file.h | 33 ++++++++ 5 files changed, 202 insertions(+), 1 deletion(-) create mode 100644 src/mesa/util/anon_file.c create mode 100644 src/mesa/util/anon_file.h diff --git a/config.h.meson b/config.h.meson index 599dc8d..dffa8d7 100644 --- a/config.h.meson +++ b/config.h.meson @@ -23,6 +23,7 @@ #mesondefine HAVE_FUNC_ATTRIBUTE_UNUSED #mesondefine HAVE_FUNC_ATTRIBUTE_WARN_UNUSED_RESULT #mesondefine HAVE_FUNC_ATTRIBUTE_WEAK +#mesondefine HAVE_MEMFD_CREATE #mesondefine HAVE_STRTOK_R #mesondefine HAVE_TIMESPEC_GET #mesondefine HAVE_SYS_UIO_H diff --git a/meson.build b/meson.build index f6ed468..e452517 100644 --- a/meson.build +++ b/meson.build @@ -148,7 +148,7 @@ foreach a : supported_function_attributes conf_data.set('HAVE_FUNC_ATTRIBUTE_@0@'.format(a.to_upper()), 1) endforeach -foreach f : ['strtok_r', 'timespec_get'] +foreach f : ['memfd_create', 'strtok_r', 'timespec_get'] if cc.has_function(f) conf_data.set('HAVE_@0@'.format(f.to_upper()), 1) endif diff --git a/src/mesa/meson.build b/src/mesa/meson.build index fd767a7..20501cc 100644 --- a/src/mesa/meson.build +++ b/src/mesa/meson.build @@ -4,6 +4,7 @@ inc_mesa = include_directories('.', 'compat', 'pipe', 'util') files_mesa = files( + 'util/anon_file.c', 'util/bitscan.c', 'util/hash_table.c', 'util/os_file.c', diff --git a/src/mesa/util/anon_file.c b/src/mesa/util/anon_file.c new file mode 100644 index 0000000..e2d9265 --- /dev/null +++ b/src/mesa/util/anon_file.c @@ -0,0 +1,166 @@ +/* + * Copyright © 2012 Collabora, Ltd. + * + * Permission is hereby granted, free of charge, to any person obtaining + * a copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sublicense, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice (including the + * next paragraph) shall be included in all copies or substantial + * portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS + * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN + * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +/* + * Based on weston shared/os-compatibility.c + */ + +#ifndef _WIN32 +#include "anon_file.h" + +#include +#include +#include +#include + +#if defined(HAVE_MEMFD_CREATE) || defined(__FreeBSD__) || defined(__OpenBSD__) +#include +#elif defined(ANDROID) +#include +#include +#else +#include +#endif + +#if !(defined(__FreeBSD__) || defined(HAVE_MEMFD_CREATE) || defined(HAVE_MKOSTEMP) || defined(ANDROID)) +static int +set_cloexec_or_close(int fd) +{ + long flags; + + if (fd == -1) + return -1; + + flags = fcntl(fd, F_GETFD); + if (flags == -1) + goto err; + + if (fcntl(fd, F_SETFD, flags | FD_CLOEXEC) == -1) + goto err; + + return fd; + +err: + close(fd); + return -1; +} +#endif + +#if !(defined(__FreeBSD__) || defined(HAVE_MEMFD_CREATE) || defined(ANDROID)) +static int +create_tmpfile_cloexec(char *tmpname) +{ + int fd; + +#ifdef HAVE_MKOSTEMP + fd = mkostemp(tmpname, O_CLOEXEC); +#else + fd = mkstemp(tmpname); +#endif + + if (fd < 0) { + return fd; + } + +#ifndef HAVE_MKOSTEMP + fd = set_cloexec_or_close(fd); +#endif + + unlink(tmpname); + return fd; +} +#endif + +/* + * Create a new, unique, anonymous file of the given size, and + * return the file descriptor for it. The file descriptor is set + * CLOEXEC. The file is immediately suitable for mmap()'ing + * the given size at offset zero. + * + * An optional name for debugging can be provided as the second argument. + * + * The file should not have a permanent backing store like a disk, + * but may have if XDG_RUNTIME_DIR is not properly implemented in OS. + * + * If memfd or SHM_ANON is supported, the filesystem is not touched at all. + * Otherwise, the file name is deleted from the file system. + * + * The file is suitable for buffer sharing between processes by + * transmitting the file descriptor over Unix sockets using the + * SCM_RIGHTS methods. + */ +int +os_create_anonymous_file(off_t size, const char *debug_name) +{ + int fd, ret; +#if defined(HAVE_MEMFD_CREATE) + if (!debug_name) + debug_name = "mesa-shared"; + fd = memfd_create(debug_name, MFD_CLOEXEC | MFD_ALLOW_SEALING); +#elif defined(ANDROID) + if (!debug_name) + debug_name = "mesa-shared"; + fd = syscall(SYS_memfd_create, debug_name, MFD_CLOEXEC | MFD_ALLOW_SEALING); +#elif defined(__FreeBSD__) + fd = shm_open(SHM_ANON, O_CREAT | O_RDWR | O_CLOEXEC, 0600); +#elif defined(__OpenBSD__) + char template[] = "/tmp/mesa-XXXXXXXXXX"; + fd = shm_mkstemp(template); + if (fd != -1) + shm_unlink(template); +#else + const char *path; + char *name; + + path = getenv("XDG_RUNTIME_DIR"); + if (!path) { + errno = ENOENT; + return -1; + } + + if (debug_name) + asprintf(&name, "%s/mesa-shared-%s-XXXXXX", path, debug_name); + else + asprintf(&name, "%s/mesa-shared-XXXXXX", path); + if (!name) + return -1; + + fd = create_tmpfile_cloexec(name); + + free(name); +#endif + + if (fd < 0) + return -1; + + ret = ftruncate(fd, size); + if (ret < 0) { + close(fd); + return -1; + } + + return fd; +} +#endif diff --git a/src/mesa/util/anon_file.h b/src/mesa/util/anon_file.h new file mode 100644 index 0000000..790537b --- /dev/null +++ b/src/mesa/util/anon_file.h @@ -0,0 +1,33 @@ +/* + * Copyright © 2012 Collabora, Ltd. + * + * Permission is hereby granted, free of charge, to any person obtaining + * a copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sublicense, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice (including the + * next paragraph) shall be included in all copies or substantial + * portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS + * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN + * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +#ifndef _ANON_FILE_H_ +#define _ANON_FILE_H_ + +#include + +int os_create_anonymous_file(off_t size, const char *debug_name); + +#endif