dlfcn/rtld.rs
1/// A safe Rust wrapper around the RTLD values defined in <dlfcn.h> in the C stdlib.
2/// Create a new instance through [`RtldValue::new`].
3pub struct RtldValue {
4 pub(crate) main: RtldMain,
5 pub(crate) ors: Vec<RtldOr>,
6}
7
8impl RtldValue {
9 /// Makes a new value with the main value as `main`, of type [`RtldMain`].
10 pub fn new(main: RtldMain) -> Self {
11 Self {
12 main,
13 ors: Vec::new(),
14 }
15 }
16
17 /// Adds a [`RtldOr`] value to the list. It will be ORed on top of [`RtldMain`] upon calling
18 /// [`RtldValue::to_libc`].
19 pub fn with(mut self, or: RtldOr) -> Self {
20 self.ors.push(or);
21 self
22 }
23
24 /// Converts the RTLD value to a [`libc::c_int`] for use in libc related areas.
25 pub fn to_libc(&self) -> ::libc::c_int {
26 let mut ret = self.main.to_libc();
27 for or in &self.ors {
28 ret |= or.to_libc();
29 }
30 ret
31 }
32}
33
34/// The RTLD main value to be used.
35pub enum RtldMain {
36 /// Resolve only binds which are needed upon request. If a symbol isn't ever requested, it
37 /// won't be resolved.
38 Lazy,
39
40 /// If this is set or the environment variable LD_BIND_NOW is set to a non-empty string, all
41 /// unresolved symbols will be resolved before the load returns.
42 Now,
43}
44
45impl RtldMain {
46 /// Maps the [`RtldMain`] value to a [`libc::c_int`].
47 pub fn to_libc(&self) -> ::libc::c_int {
48 match *self {
49 RtldMain::Lazy => ::libc::RTLD_LAZY,
50 RtldMain::Now => ::libc::RTLD_NOW,
51 }
52 }
53}
54
55/// The RTLD OR values to be used with the OR operator (|).
56pub enum RtldOr {
57 /// The symbols defined in the library will be made available to all other subsequently loaded
58 /// libraries. Be careful as this does not make them available to previously loaded ones.
59 Global,
60
61 /// This is the exact opposite of [`RtldOr::Global`], as it doesn't make any symbol available
62 /// to other loaded libraries. This is the default value of these two.
63 Local,
64
65 /// (Requires glibc 2.2 or higher for C libraries to take it into use)
66 ///
67 /// Do not unload the library during close. This also means subsequent loads of this library
68 /// will be ignored.
69 NoDelete,
70
71 /// (Requires glibc 2.2 or higher for C libraries to take it into use)
72 ///
73 /// Do not load the library during opening. This can be used to regain a handle together with
74 /// [`RtldOr::Global`], though will in this crate not reopen the table, but rather populate another one.
75 NoLoad,
76
77 /// (Requires glibc 2.3.4 or higher for C libraries to take it into use)
78 ///
79 /// Put this libary's symbols ahead in the preference chain against that of the global scope.
80 /// This means it will disregard any global symbol if there is one specifically defined in the
81 /// library.
82 DeepBind,
83}
84
85impl RtldOr {
86 /// Maps the [`RtldOr`] value to a [`libc::c_int`].
87 pub fn to_libc(&self) -> ::libc::c_int {
88 match *self {
89 RtldOr::Global => ::libc::RTLD_GLOBAL,
90 RtldOr::Local => ::libc::RTLD_LOCAL,
91 RtldOr::NoDelete => ::libc::RTLD_NODELETE,
92 RtldOr::NoLoad => ::libc::RTLD_NOLOAD,
93 RtldOr::DeepBind => ::libc::RTLD_DEEPBIND,
94 }
95 }
96}