summaryrefslogtreecommitdiffstats
path: root/openat/src/name.rs
diff options
context:
space:
mode:
authorTomasz Kramkowski <tomasz@kramkow.ski>2023-01-27 13:58:10 +0000
committerTomasz Kramkowski <tomasz@kramkow.ski>2023-01-27 13:58:10 +0000
commit6cef9f0fc159de4c9fd708050ec76adb4e74d390 (patch)
tree81856b3b4da6d18e10516b0be737a157e13f129b /openat/src/name.rs
parent9e8dd00da25273fba9f0cafccbde2236e04fb24e (diff)
downloadpam_usercg_rust-6cef9f0fc159de4c9fd708050ec76adb4e74d390.tar.gz
pam_usercg_rust-6cef9f0fc159de4c9fd708050ec76adb4e74d390.tar.xz
pam_usercg_rust-6cef9f0fc159de4c9fd708050ec76adb4e74d390.zip
openat variant
Diffstat (limited to 'openat/src/name.rs')
-rw-r--r--openat/src/name.rs76
1 files changed, 76 insertions, 0 deletions
diff --git a/openat/src/name.rs b/openat/src/name.rs
new file mode 100644
index 0000000..c181db1
--- /dev/null
+++ b/openat/src/name.rs
@@ -0,0 +1,76 @@
+use std::ffi::{OsStr, CStr, CString};
+use std::path::{Path, PathBuf};
+use std::os::unix::ffi::OsStrExt;
+
+use crate::{Entry};
+
+
+/// The purpose of this is similar to `AsRef<Path>` but it's optimized for
+/// things that can be directly used as `CStr` (which is type passed to
+/// the underlying system call).
+///
+/// This trait should be implemented for everything for which `AsRef<Path>`
+/// is implemented
+pub trait AsPath {
+ /// The return value of the `to_path` that holds data copied from the
+ /// original path (if copy is needed, otherwise it's just a reference)
+ type Buffer: AsRef<CStr>;
+ /// Returns `None` when path contains a zero byte
+ fn to_path(self) -> Option<Self::Buffer>;
+}
+
+impl<'a> AsPath for &'a Path {
+ type Buffer = CString;
+ fn to_path(self) -> Option<CString> {
+ CString::new(self.as_os_str().as_bytes()).ok()
+ }
+}
+
+impl<'a> AsPath for &'a PathBuf {
+ type Buffer = CString;
+ fn to_path(self) -> Option<CString> {
+ CString::new(self.as_os_str().as_bytes()).ok()
+ }
+}
+
+impl<'a> AsPath for &'a OsStr {
+ type Buffer = CString;
+ fn to_path(self) -> Option<CString> {
+ CString::new(self.as_bytes()).ok()
+ }
+}
+
+impl<'a> AsPath for &'a str {
+ type Buffer = CString;
+ fn to_path(self) -> Option<CString> {
+ CString::new(self.as_bytes()).ok()
+ }
+}
+
+impl<'a> AsPath for &'a String {
+ type Buffer = CString;
+ fn to_path(self) -> Option<CString> {
+ CString::new(self.as_bytes()).ok()
+ }
+}
+
+impl<'a> AsPath for String {
+ type Buffer = CString;
+ fn to_path(self) -> Option<CString> {
+ CString::new(self).ok()
+ }
+}
+
+impl<'a> AsPath for &'a CStr {
+ type Buffer = &'a CStr;
+ fn to_path(self) -> Option<&'a CStr> {
+ Some(self)
+ }
+}
+
+impl<'a> AsPath for &'a Entry {
+ type Buffer = &'a CStr;
+ fn to_path(self) -> Option<&'a CStr> {
+ Some(&self.name)
+ }
+}