libkvikio  23.12.00
shim/utils.hpp
1 /*
2  * Copyright (c) 2021-2023, NVIDIA CORPORATION.
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  * http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 #pragma once
17 
18 #include <dlfcn.h>
19 #include <sys/utsname.h>
20 #include <filesystem>
21 #include <sstream>
22 #include <vector>
23 
24 namespace kvikio {
25 
26 #define KVIKIO_STRINGIFY_DETAIL(x) #x
27 #define KVIKIO_STRINGIFY(x) KVIKIO_STRINGIFY_DETAIL(x)
28 
35 inline void* load_library(const char* name, int mode = RTLD_LAZY | RTLD_LOCAL | RTLD_NODELETE)
36 {
37  ::dlerror(); // Clear old errors
38  void* ret = ::dlopen(name, mode);
39  if (ret == nullptr) { throw std::runtime_error(::dlerror()); }
40  return ret;
41 }
42 
49 inline void* load_library(const std::vector<const char*>& names,
50  int mode = RTLD_LAZY | RTLD_LOCAL | RTLD_NODELETE)
51 {
52  std::stringstream ss;
53  for (const char* name : names) {
54  ss << name << " ";
55  try {
56  return load_library(name, mode);
57  } catch (const std::runtime_error&) {
58  }
59  }
60  throw std::runtime_error("cannot open shared object file, tried: " + ss.str());
61 }
62 
71 template <typename T>
72 void get_symbol(T& handle, void* lib, const char* name)
73 {
74  ::dlerror(); // Clear old errors
75  // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
76  handle = reinterpret_cast<T>(::dlsym(lib, name));
77  const char* err = ::dlerror();
78  if (err != nullptr) { throw std::runtime_error(err); }
79 }
80 
88 [[nodiscard]] inline bool is_running_in_wsl()
89 {
90  struct utsname buf {};
91  int err = ::uname(&buf);
92  if (err == 0) {
93  const std::string name(static_cast<char*>(buf.release));
94  // 'Microsoft' for WSL1 and 'microsoft' for WSL2
95  return name.find("icrosoft") != std::string::npos;
96  }
97  return false;
98 }
99 
109 [[nodiscard]] inline bool run_udev_readable()
110 {
111  try {
112  return std::filesystem::is_directory("/run/udev");
113  } catch (const std::filesystem::filesystem_error&) {
114  return false;
115  }
116 }
117 
118 } // namespace kvikio