pstore2
process_file_name.hpp
Go to the documentation of this file.
1 //===- include/pstore/os/process_file_name.hpp ------------*- mode: C++ -*-===//
2 //* __ _ _ *
3 //* _ __ _ __ ___ ___ ___ ___ ___ / _(_) | ___ _ __ __ _ _ __ ___ ___ *
4 //* | '_ \| '__/ _ \ / __/ _ \/ __/ __| | |_| | |/ _ \ | '_ \ / _` | '_ ` _ \ / _ \ *
5 //* | |_) | | | (_) | (_| __/\__ \__ \ | _| | | __/ | | | | (_| | | | | | | __/ *
6 //* | .__/|_| \___/ \___\___||___/___/ |_| |_|_|\___| |_| |_|\__,_|_| |_| |_|\___| *
7 //* |_| *
8 //===----------------------------------------------------------------------===//
9 //
10 // Part of the pstore project, under the Apache License v2.0 with LLVM Exceptions.
11 // See https://github.com/SNSystems/pstore/blob/master/LICENSE.txt for license
12 // information.
13 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
14 //
15 //===----------------------------------------------------------------------===//
18 
19 #ifndef PSTORE_OS_PROCESS_FILE_NAME_HPP
20 #define PSTORE_OS_PROCESS_FILE_NAME_HPP
21 
22 #include <cerrno>
23 
24 #include "pstore/support/error.hpp"
25 
26 namespace pstore {
27 
29  std::string process_file_name ();
30 
31 } // end namespace pstore
32 
33 
34 namespace pstore {
35 
46  template <typename ProcessPathFunction, typename BufferType>
47  std::size_t process_file_name (ProcessPathFunction get_process_path, BufferType & buffer) {
48  static_assert (std::is_same<typename BufferType::value_type, char>::value,
49  "BufferType::value_type must be char");
50  constexpr auto const max_reasonable_size = std::size_t{16 * 1024 * 1024};
51  auto size = std::size_t{0};
52  auto next_size = std::max (buffer.capacity (), std::size_t{2});
53  do {
54  buffer.resize (next_size);
55  size = get_process_path (::pstore::gsl::make_span (buffer));
56  next_size = std::max (size, next_size + next_size / 2U);
57  } while ((size == 0 || size >= buffer.size ()) && next_size < max_reasonable_size);
58  if (next_size >= max_reasonable_size) {
59  raise (error_code::unknown_process_path);
60  }
61  return size;
62  }
63 
64  namespace freebsd {
83  template <typename SpanType, typename SysCtlFunction, typename BufferType>
84  std::size_t process_file_name (SpanType mib, SysCtlFunction ctl, BufferType & buffer) {
85  static_assert (std::is_same<typename SpanType::element_type, int>::value,
86  "mib must be a span of integers");
87 
88  auto read_link = [&mib, &ctl] (gsl::span<char> const b) {
89  PSTORE_ASSERT (b.size () >= 0);
90  auto const buffer_size = static_cast<std::size_t> (b.size ());
91  auto length = buffer_size;
92  errno = 0;
93  if (ctl (mib.data (), static_cast<unsigned int> (mib.size ()), b.data (), &length,
94  nullptr, 0) == -1) {
95  if (errno == ENOMEM) {
96  return buffer_size;
97  }
98  raise (errno_erc{errno}, "sysctl(CTL_KERN/KERN_PROC/KERN_PROC_PATHNAME)");
99  }
100  // Subtract 1 to ignore the terminating null character.
101  return std::max (std::size_t{1}, length) - std::size_t{1};
102  };
103  return pstore::process_file_name (read_link, buffer);
104  }
105  } // end namespace freebsd
106 } // end namespace pstore
107 #endif // PSTORE_OS_PROCESS_FILE_NAME_HPP
Definition: gsl.hpp:58
This class is a tiny wrapper that allows an errno value to be passed to std::make_error_code().
Definition: error.hpp:99
Definition: nonpod2.cpp:40
Provides an pstore-specific error codes and a suitable error category for them.
std::string process_file_name()
Returns the path of the current process image.
std::size_t process_file_name(ProcessPathFunction get_process_path, BufferType &buffer)
Definition: process_file_name.hpp:47