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 <string>
19 
20 #include <stout/nothing.hpp>
21 #include <stout/option.hpp>
22 #include <stout/try.hpp>
23 
29 {
30 public:
31  DynamicLibrary() : handle_(nullptr) { }
32 
33  // Since this class manages a naked handle it cannot be copy- or
34  // move-constructed.
35  // TODO(bbannier): Allow for move-construction.
36  DynamicLibrary(const DynamicLibrary&) = delete;
37  DynamicLibrary(DynamicLibrary&&) = delete;
38 
39  virtual ~DynamicLibrary()
40  {
41  if (handle_ != nullptr) {
42  close();
43  }
44  }
45 
46  Try<Nothing> open(const std::string& path)
47  {
48  // Check if we've already opened a library.
49  if (handle_ != nullptr) {
50  return Error("Library already opened");
51  }
52 
53  handle_ = dlopen(path.c_str(), RTLD_NOW);
54 
55  if (handle_ == nullptr) {
56  return Error("Could not load library '" + path + "': " + dlerror());
57  }
58 
59  path_ = path;
60 
61  return Nothing();
62  }
63 
65  {
66  if (handle_ == nullptr) {
67  return Error("Could not close library; handle was already `nullptr`");
68  }
69 
70  if (dlclose(handle_) != 0) {
71  return Error(
72  "Could not close library '" +
73  (path_.isSome() ? path_.get() : "") + "': " + dlerror());
74  }
75 
76  handle_ = nullptr;
77  path_ = None();
78 
79  return Nothing();
80  }
81 
82  Try<void*> loadSymbol(const std::string& name)
83  {
84  if (handle_ == nullptr) {
85  return Error(
86  "Could not get symbol '" + name + "'; library handle was `nullptr`");
87  }
88 
89  void* symbol = dlsym(handle_, name.c_str());
90 
91  if (symbol == nullptr) {
92  return Error(
93  "Error looking up symbol '" + name + "' in '" +
94  (path_.isSome() ? path_.get() : "") + "' : " + dlerror());
95  }
96 
97  return symbol;
98  }
99 
100 private:
101  void* handle_;
102  Option<std::string> path_;
103 };
104 
105 #endif // __STOUT_POSIX_DYNAMICLIBRARY_HPP__
Definition: path.hpp:26
Try< Nothing > open(const std::string &path)
Definition: dynamiclibrary.hpp:46
Definition: nothing.hpp:16
Definition: errorbase.hpp:36
Definition: check.hpp:33
Try< void * > loadSymbol(const std::string &name)
Definition: dynamiclibrary.hpp:82
bool isSome() const
Definition: option.hpp:115
const T & get() const &
Definition: option.hpp:118
DynamicLibrary is a very simple wrapper around the programming interface to the dynamic linking loade...
Definition: dynamiclibrary.hpp:28
Definition: none.hpp:27
DynamicLibrary()
Definition: dynamiclibrary.hpp:31
Try< Nothing > close()
Definition: dynamiclibrary.hpp:64
virtual ~DynamicLibrary()
Definition: dynamiclibrary.hpp:39
constexpr const char * name
Definition: shell.hpp:43