Apache Mesos
dynamiclibrary.hpp
Go to the documentation of this file.
1 // Licensed under the Apache License, Version 2.0 (the "License");
2 // you may not use this file except in compliance with the License.
3 // You may obtain a copy of the License at
4 //
5 // http://www.apache.org/licenses/LICENSE-2.0
6 //
7 // Unless required by applicable law or agreed to in writing, software
8 // distributed under the License is distributed on an "AS IS" BASIS,
9 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
10 // See the License for the specific language governing permissions and
11 // limitations under the License.
12 
13 #ifndef __STOUT_POSIX_DYNAMICLIBRARY_HPP__
14 #define __STOUT_POSIX_DYNAMICLIBRARY_HPP__
15 
16 #include <dlfcn.h>
17 
18 #include <memory>
19 #include <string>
20 
21 #include <stout/nothing.hpp>
22 #include <stout/option.hpp>
23 #include <stout/try.hpp>
24 
30 {
31 public:
33  : handle_(nullptr, [](void* handle) {
34  if (handle == nullptr) {
35  return 0;
36  }
37 
38  return dlclose(handle);
39  })
40  {}
41 
42  virtual ~DynamicLibrary() = default;
43 
44  Try<Nothing> open(const std::string& path)
45  {
46  // Check if we've already opened a library.
47  if (handle_ != nullptr) {
48  return Error("Library already opened");
49  }
50 
51  handle_.reset(dlopen(path.c_str(), RTLD_NOW));
52 
53  if (handle_ == nullptr) {
54  return Error("Could not load library '" + path + "': " + dlerror());
55  }
56 
57  path_ = path;
58 
59  return Nothing();
60  }
61 
63  {
64  if (handle_ == nullptr) {
65  return Error("Could not close library; handle was already `nullptr`");
66  }
67 
68  if (dlclose(handle_.get()) != 0) {
69  return Error(
70  "Could not close library '" +
71  (path_.isSome() ? path_.get() : "") + "': " + dlerror());
72  }
73 
74  // Release the handle so the default `dlclose` operation is not
75  // invoked anymore as after successful explicit `dlclose` it does
76  // not point to an open shared object anymore.
77  handle_.release();
78 
79  handle_ = nullptr;
80  path_ = None();
81 
82  return Nothing();
83  }
84 
85  Try<void*> loadSymbol(const std::string& name)
86  {
87  if (handle_ == nullptr) {
88  return Error(
89  "Could not get symbol '" + name + "'; library handle was `nullptr`");
90  }
91 
92  void* symbol = dlsym(handle_.get(), name.c_str());
93 
94  if (symbol == nullptr) {
95  return Error(
96  "Error looking up symbol '" + name + "' in '" +
97  (path_.isSome() ? path_.get() : "") + "' : " + dlerror());
98  }
99 
100  return symbol;
101  }
102 
103 private:
104  std::unique_ptr<void, int (*)(void*)> handle_;
105  Option<std::string> path_;
106 };
107 
108 #endif // __STOUT_POSIX_DYNAMICLIBRARY_HPP__
Definition: path.hpp:29
Try< Nothing > open(const std::string &path)
Definition: dynamiclibrary.hpp:44
Definition: nothing.hpp:16
Definition: errorbase.hpp:36
Definition: check.hpp:33
virtual ~DynamicLibrary()=default
Try< void * > loadSymbol(const std::string &name)
Definition: dynamiclibrary.hpp:85
bool isSome() const
Definition: option.hpp:116
const T & get() const &
Definition: option.hpp:119
DynamicLibrary is a very simple wrapper around the programming interface to the dynamic linking loade...
Definition: dynamiclibrary.hpp:29
Definition: none.hpp:27
DynamicLibrary()
Definition: dynamiclibrary.hpp:32
Try< Nothing > close()
Definition: dynamiclibrary.hpp:62
constexpr const char * name
Definition: shell.hpp:41