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