Vcsn  2.8
Be Rational
xltdl.cc
Go to the documentation of this file.
1 #include <cstdio>
2 #include <iostream>
3 
4 #include <boost/filesystem.hpp>
5 
6 #include <lib/vcsn/misc/xltdl.hh>
7 
8 namespace vcsn
9 {
10  namespace detail
11  {
12  namespace
13  {
14  void init()
15  {
16  static bool first = true;
17  if (first)
18  {
19  lt_dlinit();
20  first = false;
21  }
22  }
23  }
24 
25  /*-------------.
26  | xlt_advise. |
27  `-------------*/
28 
30  : path_()
31  {
32  init();
33  if (lt_dladvise_init(&advise_))
34  raise("failed to initialize dladvise: ", lt_dlerror());
35  }
36 
37  // FIXME: Bad: dtors must not throw.
39  {
40  // FIXME: lt_dlexit when we refcount.
41  if (lt_dladvise_destroy(&advise_))
42  raise("failed to destroy dladvise: ", lt_dlerror());
43  }
44 
45  xlt_advise&
47  {
48  if (global ? lt_dladvise_global(&advise_) : lt_dladvise_local(&advise_))
49  raise("failed to set dladvise to ", global ? "global" : "local",
50  ": ", lt_dlerror());
51  return *this;
52  }
53 
54  xlt_advise&
56  {
57  if (lt_dladvise_ext(&advise_))
58  raise("failed to set dladvise to ext: ", lt_dlerror());
59  return *this;
60  }
61 
62  xlt_advise&
64  {
65  verbose_ = v;
66  return *this;
67  }
68 
69  const file_library&
70  xlt_advise::path() const noexcept
71  {
72  return path_;
73  }
74 
76  xlt_advise::path() noexcept
77  {
78  return path_;
79  }
80 
81  xlt_advise&
82  xlt_advise::path(const file_library& p) noexcept
83  {
84  path_ = p;
85  return *this;
86  }
87 
88  lt_dlhandle
90  {
91  if (verbose_)
92  std::cerr << "xltdl: dlopen(" << s << ")... ";
93  auto res = lt_dlopenadvise(s.c_str(), advise_);
94  if (verbose_)
95  {
96  if (res)
97  std::cerr << "success\n";
98  else
99  std::cerr << "fail: " << lt_dlerror() << '\n';
100  }
101  return res;
102  }
103 
104  xlt_handle
105  xlt_advise::open(const std::string& s)
106  {
107  auto res = lt_dlhandle{nullptr};
108  // We cannot simply use search_file in file_library, because we
109  // don't know the extension of the file we are looking for (*.la,
110  // *.so, *.dyld etc.). That's an implementation detail that ltdl
111  // saves us from.
112  using path = file_library::path;
113  if (path_.search_path_get().empty() || path(s).is_absolute())
114  res = dlopen_(s);
115  else
116  for (const auto& p: path_.search_path_get())
117  if ((res = dlopen_(p / s)))
118  break;
119 
120  if (!res)
121  raise("failed to dlopen module ", s, ": ", lt_dlerror());
122 
123  return res;
124  }
125 
126 
127  /*-------------.
128  | xlt_handle. |
129  `-------------*/
130 
131  xlt_handle::xlt_handle(lt_dlhandle h)
132  : handle(h)
133  {}
134 
136  {
137  // FIXME: We can't close -- yet. We need to keep track of the
138  // number of trackers. Otherwise a simple "handle h =
139  // advise.open" will close the handle when cleaning the temporary
140  // made by "advise.open".
141 
142  // close();
143  }
144 
145  void
147  {
148  if (handle)
149  {
150  int errors = lt_dlclose(handle);
151  handle = nullptr;
152  if (errors)
153  raise("failed to dlclose module: ", lt_dlerror());
154  }
155  }
156 
157  void
159  {
160  assert(handle);
161  handle = nullptr;
162  }
163 
164  void
165  xlt_handle::attach(lt_dlhandle h)
166  {
167  assert(!handle);
168  handle = h;
169  }
170 
171 
172  /*-------------.
173  | Standalone. |
174  `-------------*/
175 
176  xlt_handle
177  xlt_openext(const std::string& s, bool global)
178  {
179  return xlt_advise().global(global).ext().open(s);
180  }
181  }
182 }
xlt_advise & global(bool global)
Definition: xltdl.cc:46
lt_dlhandle handle
The handle.
Definition: xltdl.hh:80
void attach(lt_dlhandle h)
Detach so that destruction does not close.
Definition: xltdl.cc:165
xlt_advise & ext()
Definition: xltdl.cc:55
lt_dladvise advise_
Definition: xltdl.hh:46
void detach()
Detach so that destruction does not close.
Definition: xltdl.cc:158
Explicit path representation.
Definition: path.hh:16
lt_dlhandle dlopen_(const file_library::path &s) const
Does not use the search path. Can return 0.
Definition: xltdl.cc:89
Definition: a-star.hh:8
void close()
Close the handle.
Definition: xltdl.cc:146
const file_library & path() const noexcept
Definition: xltdl.cc:70
xlt_handle(lt_dlhandle h=nullptr)
Definition: xltdl.cc:131
Manage search paths.
Definition: file-library.hh:22
file_library path_
Definition: xltdl.hh:47
boost::filesystem::path path
Definition: file-library.hh:27
xlt_handle xlt_openext(const std::string &s, bool global)
Wrapper around lt_dlopenext.
Definition: xltdl.cc:177
const path_list_type & search_path_get() const
xlt_handle open(const std::string &s)
Definition: xltdl.cc:105
return res
Definition: multiply.hh:399
xlt_advise & verbose(int v)
Whether to report dlopen attempts.
Definition: xltdl.cc:63