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}