1//===---------- Shared implementations for shm_open/shm_unlink ------------===//
2//
3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4// See https://llvm.org/LICENSE.txt for license information.
5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6//
7//===----------------------------------------------------------------------===//
8
9#include "src/__support/CPP/array.h"
10#include "src/__support/CPP/optional.h"
11#include "src/__support/CPP/string_view.h"
12#include "src/errno/libc_errno.h"
13#include "src/string/memory_utils/inline_memcpy.h"
14
15// TODO: Get PATH_MAX via https://github.com/llvm/llvm-project/issues/85121
16#include <linux/limits.h>
17
18namespace LIBC_NAMESPACE {
19
20namespace shm_common {
21
22LIBC_INLINE_VAR constexpr cpp::string_view SHM_PREFIX = "/dev/shm/";
23using SHMPath = cpp::array<char, NAME_MAX + SHM_PREFIX.size() + 1>;
24
25LIBC_INLINE cpp::optional<SHMPath> translate_name(cpp::string_view name) {
26 // trim leading slashes
27 size_t offset = name.find_first_not_of(c: '/');
28 if (offset == cpp::string_view::npos) {
29 libc_errno = EINVAL;
30 return cpp::nullopt;
31 }
32 name = name.substr(Start: offset);
33
34 // check the name
35 if (name.size() > NAME_MAX) {
36 libc_errno = ENAMETOOLONG;
37 return cpp::nullopt;
38 }
39 if (name == "." || name == ".." || name.contains(c: '/')) {
40 libc_errno = EINVAL;
41 return cpp::nullopt;
42 }
43
44 // prepend the prefix
45 SHMPath buffer;
46 inline_memcpy(dst: buffer.data(), src: SHM_PREFIX.data(), count: SHM_PREFIX.size());
47 inline_memcpy(dst: buffer.data() + SHM_PREFIX.size(), src: name.data(), count: name.size());
48 buffer[SHM_PREFIX.size() + name.size()] = '\0';
49 return buffer;
50}
51} // namespace shm_common
52
53} // namespace LIBC_NAMESPACE
54

source code of libc/src/sys/mman/linux/shm_common.h